php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73307 Stream Socket Server unable to create IPv4/IPv6 Sockets
Submitted: 2016-10-12 16:45 UTC Modified: 2016-10-19 10:43 UTC
From: lucius at luciusgaitan dot com Assigned:
Status: Not a bug Package: Unknown/Other Function
PHP Version: 7.0.11 OS: CentOS 7.2.1511 x64
Private report: No CVE-ID: None
 [2016-10-12 16:45 UTC] lucius at luciusgaitan dot com
Description:
------------
Having a dual stack server, php is unable to create two sockets in the same port for different addresses ipv4 and ipv6.
Only the first attempt to create the socket succeeds, the second returns "PHP Warning:  stream_socket_server(): unable to connect to ... (Address already in use)".

Using the defaults 0.0.0.0 and [::]. If the real ip addresses are defined everything works well.

Also, $errno equals to 0 and returned value is FALSE as described in /manual/en/function.stream-socket-server.php.


./configure --with-config-file-path=/etc --disable-short-tags --enable-bcmath --enable-calendar --enable-gd-native-ttf --enable-mbstring --enable-pdo=shared --enable-sockets --enable-zip --with-curl=/opt/curlssl/ --with-freetype-dir=/usr --with-gd --with-jpeg-dir=/usr --with-mysqli --with-openssl --with-pcre-regex --with-pdo-mysql=shared --with-pdo-sqlite=shared --with-pic --with-png-dir=/usr --with-zlib --with-zlib-dir=/usr --enable-pcntl --with-bz2 -enable-opcache --enable-fpm --with-fpm-systemd



Thank you.



Test script:
---------------
$errno = null; $error = null;
$bindto = ['0.0.0.0', '[::]'];
$socket = [];

for ($x = 0; $x < 2; ++$x) {
    $ctx = stream_context_create(['socket' => ['bindto' => $bindto[$x] . ':3672']]);
    $socket[] = stream_socket_server('tls://' . $bindto[$x] . ':3672', $errno, $error, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctx);
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-19 10:43 UTC] bwoebi@php.net
-Status: Open +Status: Not a bug
 [2016-10-19 10:43 UTC] bwoebi@php.net
This is behavior of the underlying syscalls; some OS choose to map IPv4 into the IPv6 space in general. (And thus [::] is a superset of 0.0.0.0 there, leading to address already in use.)

Under Linux you may find your default behavior under /proc/sys/net/ipv6/bindv6only (1 if separated, 0 if overlapping).

Additionally, to explicitly control it from the script, PHP 7.0.1+ expose a "ipv6_v6only" socket stream context option.

Try: $ctx = stream_context_create(['socket' => ['ipv6_v6only' => true]]);
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Apr 24 05:01:30 2024 UTC