Skip to content

Commit 9209c19

Browse files
committed
fix bug #65808 the socket_connect() won't work with IPv6 address
1 parent b2f8f35 commit 9209c19

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2013, PHP 5.4.22
44

5+
- Sockets:
6+
. Fixed bug #65808 (the socket_connect() won't work with IPv6 address).
7+
(Mike)
8+
59
?? ??? 2013, PHP 5.4.21
610

711
- Core:

ext/sockets/sockets.c

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,8 @@ static char *php_strerror(int error TSRMLS_DC) /* {{{ */
607607
/* }}} */
608608

609609
#if HAVE_IPV6
610+
static int php_get_if_index_from_string(const char *val, unsigned *out TSRMLS_DC);
611+
610612
/* Sets addr by hostname, or by ip in string form (AF_INET6) */
611613
static int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
612614
{
@@ -615,6 +617,7 @@ static int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socke
615617
struct addrinfo hints;
616618
struct addrinfo *addrinfo = NULL;
617619
#endif
620+
char *scope = strchr(string, '%');
618621

619622
if (inet_pton(AF_INET6, string, &tmp)) {
620623
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
649652

650653
}
651654

655+
if (scope++) {
656+
long lval = 0;
657+
double dval = 0;
658+
unsigned scope_id = 0;
659+
660+
if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, &dval, 0)) {
661+
if (lval > 0 && lval <= UINT_MAX) {
662+
scope_id = lval;
663+
}
664+
} else {
665+
php_get_if_index_from_string(scope, &scope_id TSRMLS_CC);
666+
}
667+
668+
sin6->sin6_scope_id = scope_id;
669+
}
670+
652671
return 1;
653672
}
654673
/* }}} */
@@ -714,6 +733,28 @@ static int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char
714733
return 0;
715734
}
716735

736+
static int php_get_if_index_from_string(const char *val, unsigned *out TSRMLS_DC)
737+
{
738+
#if HAVE_IF_NAMETOINDEX
739+
unsigned int ind;
740+
741+
ind = if_nametoindex(val);
742+
if (ind == 0) {
743+
php_error_docref(NULL TSRMLS_CC, E_WARNING,
744+
"no interface with name \"%s\" could be found", val);
745+
return FAILURE;
746+
} else {
747+
*out = ind;
748+
return SUCCESS;
749+
}
750+
#else
751+
php_error_docref(NULL TSRMLS_CC, E_WARNING,
752+
"this platform does not support looking up an interface by "
753+
"name, an integer interface index must be supplied instead");
754+
return FAILURE;
755+
#endif
756+
}
757+
717758
static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
718759
{
719760
int ret;
@@ -729,26 +770,10 @@ static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
729770
ret = SUCCESS;
730771
}
731772
} else {
732-
#if HAVE_IF_NAMETOINDEX
733-
unsigned int ind;
734773
zval_add_ref(&val);
735774
convert_to_string_ex(&val);
736-
ind = if_nametoindex(Z_STRVAL_P(val));
737-
if (ind == 0) {
738-
php_error_docref(NULL TSRMLS_CC, E_WARNING,
739-
"no interface with name \"%s\" could be found", Z_STRVAL_P(val));
740-
ret = FAILURE;
741-
} else {
742-
*out = ind;
743-
ret = SUCCESS;
744-
}
775+
ret = php_get_if_index_from_string(Z_STRVAL_P(val), out TSRMLS_CC);
745776
zval_ptr_dtor(&val);
746-
#else
747-
php_error_docref(NULL TSRMLS_CC, E_WARNING,
748-
"this platform does not support looking up an interface by "
749-
"name, an integer interface index must be supplied instead");
750-
ret = FAILURE;
751-
#endif
752777
}
753778

754779
return ret;

0 commit comments

Comments
 (0)