]> granicus.if.org Git - php/commitdiff
- Fixed bug #51958: socket_accept() fails on IPv6 sockets.
authorGustavo André dos Santos Lopes <cataphract@php.net>
Mon, 14 Mar 2011 22:59:05 +0000 (22:59 +0000)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Mon, 14 Mar 2011 22:59:05 +0000 (22:59 +0000)
#On hold for 5.3

ext/sockets/sockets.c
ext/sockets/tests/bug51958.phpt [new file with mode: 0644]

index 3203543997e2e9c052517531b7b6a2413ca105ab..a180c86c6e83f90d4893b0e7c5425c2dcbd43c13 100644 (file)
@@ -402,16 +402,13 @@ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog TSR
 }
 /* }}} */
 
-static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct sockaddr *la TSRMLS_DC) /* {{{ */
+static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct sockaddr *la, socklen_t *la_len TSRMLS_DC) /* {{{ */
 {
-       socklen_t       salen;
        php_socket      *out_sock = (php_socket*)emalloc(sizeof(php_socket));
 
        *new_sock = out_sock;
-       salen = sizeof(*la);
-       out_sock->blocking = 1;
 
-       out_sock->bsd_socket = accept(in_sock->bsd_socket, la, &salen);
+       out_sock->bsd_socket = accept(in_sock->bsd_socket, la, la_len);
 
        if (IS_INVALID_SOCKET(out_sock)) {
                PHP_SOCKET_ERROR(out_sock, "unable to accept incoming connection", errno);
@@ -419,6 +416,10 @@ static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct
                return 0;
        }
 
+       out_sock->error = 0;
+       out_sock->blocking = 1;
+       out_sock->type = la->sa_family;
+
        return 1;
 }
 /* }}} */
@@ -1023,9 +1024,10 @@ PHP_FUNCTION(socket_create_listen)
    Accepts a connection on the listening socket fd */
 PHP_FUNCTION(socket_accept)
 {
-       zval                            *arg1;
-       php_socket                      *php_sock, *new_sock;
-       struct sockaddr_in      sa;
+       zval                             *arg1;
+       php_socket                       *php_sock, *new_sock;
+       php_sockaddr_storage sa;
+       socklen_t                        sa_len = sizeof(sa);
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
                return;
@@ -1033,13 +1035,10 @@ PHP_FUNCTION(socket_accept)
 
        ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
 
-       if (!php_accept_connect(php_sock, &new_sock, (struct sockaddr *) &sa TSRMLS_CC)) {
+       if (!php_accept_connect(php_sock, &new_sock, (struct sockaddr*)&sa, &sa_len TSRMLS_CC)) {
                RETURN_FALSE;
        }
 
-       new_sock->error = 0;
-       new_sock->blocking = 1;
-
        ZEND_REGISTER_RESOURCE(return_value, new_sock, le_socket);
 }
 /* }}} */
diff --git a/ext/sockets/tests/bug51958.phpt b/ext/sockets/tests/bug51958.phpt
new file mode 100644 (file)
index 0000000..e5db683
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--\r
+Bug #51958: socket_accept() fails on IPv6 server sockets\r
+--SKIPIF--\r
+<?php\r
+if (!extension_loaded('sockets')) {\r
+    die('skip sockets extension not available.');\r
+}\r
+if (!defined('IPPROTO_IPV6')) {\r
+       die('skip IPv6 not available.');\r
+}\r
+if (PHP_OS != "WINNT")\r
+       die('skip test relies Winsock's error code for WSAEWOULDBLOCK/EAGAIN');\r
+--FILE--\r
+<?php\r
+$listenfd = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP);\r
+socket_bind($listenfd, "::1", 13579);\r
+socket_listen($listenfd);\r
+socket_set_nonblock($listenfd);\r
+$connfd = @socket_accept($listenfd);\r
+echo socket_last_error();\r
+--EXPECT--\r
+10035\r