in src/tcp/connect.php [21:94]
async function connect_async(
string $host,
int $port,
ConnectOptions $opts = shape(),
): Awaitable<CloseableSocket> {
$ipver = $opts['ip_version'] ?? Network\IPProtocolBehavior::PREFER_IPV6;
$timeout_ns = $opts['timeout_ns'] ?? 0;
switch ($ipver) {
case Network\IPProtocolBehavior::PREFER_IPV6:
$sds = vec[OS\SocketDomain::PF_INET6, OS\SocketDomain::PF_INET];
break;
case Network\IPProtocolBehavior::FORCE_IPV6:
$sds = vec[OS\SocketDomain::PF_INET6];
break;
case Network\IPProtocolBehavior::FORCE_IPV4:
$sds = vec[OS\SocketDomain::PF_INET];
break;
}
$ex = null;
foreach ($sds as $sd) {
$sock = OS\socket($sd, OS\SocketType::SOCK_STREAM, 0);
$sa = null;
switch ($sd) {
case OS\SocketDomain::PF_INET:
$ipv4_host = _Network\resolve_hostname(
OS\AddressFamily::AF_INET,
$host,
);
if ($ipv4_host is nonnull) {
$sa = new OS\sockaddr_in(
$port,
OS\inet_pton_inet($ipv4_host),
);
}
break;
case OS\SocketDomain::PF_INET6:
$ipv6_host = _Network\resolve_hostname(
OS\AddressFamily::AF_INET6,
$host,
);
if ($ipv6_host !== null) {
$sa = new OS\sockaddr_in6(
$port,
/* flowinfo = */ 0,
OS\inet_pton_inet6($ipv6_host),
/* scope id = */ 0,
);
}
break;
case OS\SocketDomain::PF_UNIX:
invariant_violation('unreachable');
}
if ($sa === null) {
continue;
}
try {
await _Network\socket_connect_async($sock, $sa, $timeout_ns);
return new _TCP\CloseableTCPSocket($sock);
} catch (OS\ErrnoException $this_sd_ex) {
$ex = $this_sd_ex;
}
}
if ($ex === null) {
_OS\throw_errno(
OS\Errno::EINVAL,
"Failed to create a sockaddr for any domain",
);
}
throw $ex;
}