Commit:    9209c19f8f7eef807cb457b32d3ab517ff8dc178
Author:    Michael Wallner <m...@php.net>         Wed, 2 Oct 2013 15:19:25 +0200
Parents:   b2f8f35a889e77c3123ade348907e73bf6d6689e
Branches:  PHP-5.4 PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=9209c19f8f7eef807cb457b32d3ab517ff8dc178

Log:
fix bug #65808  the socket_connect() won't work with IPv6 address

Bugs:
https://bugs.php.net/65808

Changed paths:
  M  NEWS
  M  ext/sockets/sockets.c


Diff:
diff --git a/NEWS b/NEWS
index 9bef174..c2086c07 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                            
            NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2013, PHP 5.4.22
 
+- Sockets:
+  . Fixed bug #65808 (the socket_connect() won't work with IPv6 address).
+    (Mike)
+
 ?? ??? 2013, PHP 5.4.21
 
 - Core:
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index d0d0294..d094b3c 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -607,6 +607,8 @@ static char *php_strerror(int error TSRMLS_DC) /* {{{ */
 /* }}} */
 
 #if HAVE_IPV6
+static int php_get_if_index_from_string(const char *val, unsigned *out 
TSRMLS_DC);
+
 /* Sets addr by hostname, or by ip in string form (AF_INET6) */
 static int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, 
php_socket *php_sock TSRMLS_DC) /* {{{ */
 {
@@ -615,6 +617,7 @@ static int php_set_inet6_addr(struct sockaddr_in6 *sin6, 
char *string, php_socke
        struct addrinfo hints;
        struct addrinfo *addrinfo = NULL;
 #endif
+       char *scope = strchr(string, '%');
 
        if (inet_pton(AF_INET6, string, &tmp)) {
                memcpy(&(sin6->sin6_addr.s6_addr), &(tmp.s6_addr), 
sizeof(struct in6_addr));
@@ -649,6 +652,22 @@ static int php_set_inet6_addr(struct sockaddr_in6 *sin6, 
char *string, php_socke
 
        }
 
+       if (scope++) {
+               long lval = 0;
+               double dval = 0;
+               unsigned scope_id = 0;
+
+               if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, 
&dval, 0)) {
+                       if (lval > 0 && lval <= UINT_MAX) {
+                               scope_id = lval;
+                       }
+               } else {
+                       php_get_if_index_from_string(scope, &scope_id 
TSRMLS_CC);
+               }
+
+               sin6->sin6_scope_id = scope_id;
+       }
+
        return 1;
 }
 /* }}} */
@@ -714,6 +733,28 @@ static int php_set_inet46_addr(php_sockaddr_storage *ss, 
socklen_t *ss_len, char
        return 0;
 }
 
+static int php_get_if_index_from_string(const char *val, unsigned *out 
TSRMLS_DC)
+{
+#if HAVE_IF_NAMETOINDEX
+       unsigned int ind;
+
+       ind = if_nametoindex(val);
+       if (ind == 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                       "no interface with name \"%s\" could be found", val);
+               return FAILURE;
+       } else {
+               *out = ind;
+               return SUCCESS;
+       }
+#else
+       php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                       "this platform does not support looking up an interface 
by "
+                       "name, an integer interface index must be supplied 
instead");
+       return FAILURE;
+#endif
+}
+
 static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
 {
        int ret;
@@ -729,26 +770,10 @@ static int php_get_if_index_from_zval(zval *val, unsigned 
*out TSRMLS_DC)
                        ret = SUCCESS;
                }
        } else {
-#if HAVE_IF_NAMETOINDEX
-               unsigned int ind;
                zval_add_ref(&val);
                convert_to_string_ex(&val);
-               ind = if_nametoindex(Z_STRVAL_P(val));
-               if (ind == 0) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING,
-                               "no interface with name \"%s\" could be found", 
Z_STRVAL_P(val));
-                       ret = FAILURE;
-               } else {
-                       *out = ind;
-                       ret = SUCCESS;
-               }
+               ret = php_get_if_index_from_string(Z_STRVAL_P(val), out 
TSRMLS_CC);
                zval_ptr_dtor(&val);
-#else
-               php_error_docref(NULL TSRMLS_CC, E_WARNING,
-                               "this platform does not support looking up an 
interface by "
-                               "name, an integer interface index must be 
supplied instead");
-               ret = FAILURE;
-#endif
        }
 
        return ret;


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to