rfc:socket_getaddrinfo

This is an old revision of the document!


PHP RFC: Implement socket_getaddrinfo()

Introduction

This RFC targets a reported feature request in #72733. The request is that PHP expose the C level function getaddrinfo(). This is a missing nice piece to the current socket library. When dealing with IP variable networks it would be beneficial to allow libc to tell us what methods of connecting/listening would be most appropriate given a set of hints.

Proposals

I'm starting this RFC with 3 proposed solutions, which are very similar, but I'm not sure which is preferable for implementation.

Proposal 1

The implementation[1] I'm proposing implements 5 new socket_* functions. socket_getaddrinfo() will return an array of resources, with each resource corresponding to each returned addrinfo. The next two implemented methods socket_addrinfo_bind(), and socket_addrinfo_connect(), would be used to bind, or connect, to a given resource rather than make the user go through the process of creating the socket and connect/binding themselves. The fourth function is a free'r if you'd want to free the resources before end of script. And the last to pull info from the addrinfo resource.

socket_getaddrinfo(string node[, mixed service, array hints]) : array
socket_addrinfo_connect(resource $addrinfo) : resource
socket_addrinfo_bind(resource $addrinfo) : resource
socket_addrinfo(resource $addrinfo) : array
socket_addrinfo_close(sockaddrresource sockaddr) : null
<?php
$addrinfo = socket_getaddrinfo('127.0.0.1', 2000, array('ai_family' => AI_INET, 'ai_socktype' => SOCK_STREAM));
$sockaddr = reset($addrinfo);
if (!$sockaddr) die ("No Valid Socket Types");
$sock = socket_addrinfo_bind($sockaddr);
// ^^ $sock is a socket resource that is bound to 127.0.0.1:2000 using TCP/IP ready for reading
foreach ($addrinfo as $sockaddr) {
    socket_addrinfo_close($sockaddr);
}

Proposal 2

This attempt [2] is very similar to the first, except, I change socket_create() and socket_bind() to accept one argument from two, IF, that argument is our addrinfo resource. If it is our addrinfo resource the functions, rather than a boolean return will return the resource to the bound/connected socket resource.

socket_getaddrinfo(string $node[, mixed $service, array $hints]) : array
socket_connect(resource $sock_or_addr[, string $address, int $port = 0]) : mixed
socket_bind(resource $sock_or_addr[, string address, int port = 0]) : mixed
socket_addrinfo(resource $addrinfo) : array
socket_addrinfo_close(resourece $addrinfo) : null
<?php
$addrinfo = socket_getaddrinfo('127.0.0.1', 2000, array('ai_family' => AI_INET, 'ai_socktype' => SOCK_STREAM));
$sockaddr = reset($addrinfo);
if (!$sockaddr) die ("No Valid Socket Types");
$sock = socket_bind($sockaddr);
// ^^ $sock is a socket resource that is bound to 127.0.0.1:2000 using TCP/IP ready for reading
foreach ($addrinfo as $sockaddr) {
    socket_addrinfo_close($sockaddr);
}

Proposal 3

This attempt [3] is very similar to the others, and tries to be a hybrid approach. It still alters the default signature of socket_(connect|bind) to change the second argument to mixed. This method is the most C-like of the 3. After playing with all three, this is my preferred, but changing default signatures is not always the best idea.

socket_getaddrinfo(string $node[, mixed $service, array $hints]) : array
socket_connect(resource $sock, mixed $address_or_addrinfo[, int $port = 0]) : bool
socket_bind(resource $sock, string $address_or_addrinfo[, int port = 0]) : bool
socket_addrinfo_close(resourece $addrinfo) : null
<?php
$addrinfo = socket_getaddrinfo('127.0.0.1', 2000, array('ai_family' => AI_INET, 'ai_socktype' => SOCK_STREAM));
$sockaddr = reset($addrinfo);
if (!$sockaddr) die ("No Valid Socket Types");
$sock = socket_create($sockaddr['ai_family'], $sockaddr['ai_socktype'], $sockaddr['ai_protocol']);
$sock = socket_bind($sock, $sockaddr);
// ^^ $sock is a socket resource that is bound to 127.0.0.1:2000 using TCP/IP ready for reading
foreach ($addrinfo as $sockaddr) {
    socket_addrinfo_close($sockaddr);
}

Backward Incompatible Changes

New functionality; BC problems in changing default socket function signatures for Proposal 2&3.

Proposed PHP Version(s)

Next PHP 7.x (currently 7.2)

RFC Impact

To SAPIs

None

To Existing Extensions

Socket acquired new functionality

To Opcache

None

New Constants

Exposing the AI_* family of constants.

Open Issues

Proposed Voting Choices

Vote to implement the new functions, would require a 2/3 majority.

Implementation

References

rfc/socket_getaddrinfo.1470925654.txt.gz · Last modified: 2017/09/22 13:28 (external edit)