summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Wallner <mike@php.net>2013-10-02 15:19:25 +0200
committerMichael Wallner <mike@php.net>2013-10-02 15:19:25 +0200
commit9209c19f8f7eef807cb457b32d3ab517ff8dc178 (patch)
tree0857d78e4622272fd66711bbf0b3d532d4da1b49
parentb2f8f35a889e77c3123ade348907e73bf6d6689e (diff)
downloadphp-git-9209c19f8f7eef807cb457b32d3ab517ff8dc178.tar.gz
fix bug #65808 the socket_connect() won't work with IPv6 address
-rw-r--r--NEWS4
-rw-r--r--ext/sockets/sockets.c59
2 files changed, 46 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index 9bef174d37..c2086c0791 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 d0d0294647..d094b3cc1d 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;