--- embedaddon/php/ext/sockets/sockets.c 2013/07/22 01:32:01 1.1.1.3 +++ embedaddon/php/ext/sockets/sockets.c 2014/06/15 20:03:55 1.1.1.5 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sockets.c,v 1.1.1.3 2013/07/22 01:32:01 misho Exp $ */ +/* $Id: sockets.c,v 1.1.1.5 2014/06/15 20:03:55 misho Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -352,7 +352,7 @@ const zend_function_entry sockets_functions[] = { PHP_FE(socket_clear_error, arginfo_socket_clear_error) PHP_FE(socket_import_stream, arginfo_socket_import_stream) - /* for downwards compatability */ + /* for downwards compatibility */ PHP_FALIAS(socket_getopt, socket_get_option, arginfo_socket_get_option) PHP_FALIAS(socket_setopt, socket_set_option, arginfo_socket_set_option) @@ -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 *sin 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 *sin } + 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 *s 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, unsig 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; @@ -843,6 +868,9 @@ PHP_MINIT_FUNCTION(sockets) REGISTER_LONG_CONSTANT("SO_RCVTIMEO", SO_RCVTIMEO, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SO_TYPE", SO_TYPE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SO_ERROR", SO_ERROR, CONST_CS | CONST_PERSISTENT); +#ifdef SO_BINDTODEVICE + REGISTER_LONG_CONSTANT("SO_BINDTODEVICE", SO_BINDTODEVICE, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("SOL_SOCKET", SOL_SOCKET, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOMAXCONN", SOMAXCONN, CONST_CS | CONST_PERSISTENT); #ifdef TCP_NODELAY @@ -2355,7 +2383,19 @@ ipv6_loop_hops: #endif break; } - +#ifdef SO_BINDTODEVICE + case SO_BINDTODEVICE: { + if (Z_TYPE_PP(arg4) == IS_STRING) { + opt_ptr = Z_STRVAL_PP(arg4); + optlen = Z_STRLEN_PP(arg4); + } else { + opt_ptr = ""; + optlen = 0; + } + break; + } +#endif + default: convert_to_long_ex(arg4); ov = Z_LVAL_PP(arg4);