From 1bf96620f312f69463ff6c048f17e9c0c6e42355 Mon Sep 17 00:00:00 2001 From: Paul J R Date: Thu, 18 Oct 2012 06:16:28 +1100 Subject: [PATCH 1/2] Added (optional) ifindex parameter to socket_sendto and socket_recvfrom for ipv6 link-local udp communications --- ext/sockets/sockets.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 0d1714257dbc7..a3c56cc81f606 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -226,6 +226,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_recvfrom, 0, 0, 5) ZEND_ARG_INFO(0, flags) ZEND_ARG_INFO(1, name) ZEND_ARG_INFO(1, port) + ZEND_ARG_INFO(1, ifindex) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_sendto, 0, 0, 5) @@ -235,6 +236,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_sendto, 0, 0, 5) ZEND_ARG_INFO(0, flags) ZEND_ARG_INFO(0, addr) ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, ifindex) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_get_option, 0, 0, 3) @@ -1742,11 +1744,11 @@ PHP_FUNCTION(socket_send) } /* }}} */ -/* {{{ proto int socket_recvfrom(resource socket, string &buf, int len, int flags, string &name [, int &port]) +/* {{{ proto int socket_recvfrom(resource socket, string &buf, int len, int flags, string &name [, int &port [, int &ifindex]]) Receives data from a socket, connected or not */ PHP_FUNCTION(socket_recvfrom) { - zval *arg1, *arg2, *arg5, *arg6 = NULL; + zval *arg1, *arg2, *arg5, *arg6 = NULL, *arg7 = NULL; php_socket *php_sock; struct sockaddr_un s_un; struct sockaddr_in sin; @@ -1759,7 +1761,7 @@ PHP_FUNCTION(socket_recvfrom) long arg3, arg4; char *recv_buf, *address; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzllz|z", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzllz|zz", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7) == FAILURE) { return; } @@ -1819,6 +1821,11 @@ PHP_FUNCTION(socket_recvfrom) ZVAL_STRINGL(arg2, recv_buf, retval, 0); ZVAL_STRING(arg5, address ? address : "0.0.0.0", 1); ZVAL_LONG(arg6, ntohs(sin.sin_port)); + + if(arg7 != NULL) { + zval_dtor(arg7); + ZVAL_LONG(arg7, -1); + } break; #if HAVE_IPV6 case AF_INET6: @@ -1849,6 +1856,10 @@ PHP_FUNCTION(socket_recvfrom) ZVAL_STRINGL(arg2, recv_buf, retval, 0); ZVAL_STRING(arg5, addr6[0] ? addr6 : "::", 1); ZVAL_LONG(arg6, ntohs(sin6.sin6_port)); + if(arg7 != NULL) { + zval_dtor(arg7); + ZVAL_LONG(arg7, sin6.sin6_scope_id); + } break; #endif default: @@ -1860,7 +1871,7 @@ PHP_FUNCTION(socket_recvfrom) } /* }}} */ -/* {{{ proto int socket_sendto(resource socket, string buf, int len, int flags, string addr [, int port]) +/* {{{ proto int socket_sendto(resource socket, string buf, int len, int flags, string addr [, int port [, int ifindex]]) Sends a message to a socket, whether it is connected or not */ PHP_FUNCTION(socket_sendto) { @@ -1872,11 +1883,11 @@ PHP_FUNCTION(socket_sendto) struct sockaddr_in6 sin6; #endif int retval, buf_len, addr_len; - long len, flags, port = 0; + long len, flags, port = 0, ifindex=-1; char *buf, *addr; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rslls|l", &arg1, &buf, &buf_len, &len, &flags, &addr, &addr_len, &port) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "rslls|ll", &arg1, &buf, &buf_len, &len, &flags, &addr, &addr_len, &port, &ifindex) == FAILURE) { return; } @@ -1908,7 +1919,7 @@ PHP_FUNCTION(socket_sendto) break; #if HAVE_IPV6 case AF_INET6: - if (argc != 6) { + if (argc != 6 && argc != 7) { WRONG_PARAM_COUNT; } @@ -1916,6 +1927,10 @@ PHP_FUNCTION(socket_sendto) sin6.sin6_family = AF_INET6; sin6.sin6_port = htons((unsigned short) port); + if(ifindex>-1) { + sin6.sin6_scope_id = ifindex; + } + if (! php_set_inet6_addr(&sin6, addr, php_sock TSRMLS_CC)) { RETURN_FALSE; } From 049a5aa14eb895cac0d450f811a8b2cd680762a4 Mon Sep 17 00:00:00 2001 From: Paul J R Date: Thu, 18 Oct 2012 18:01:05 +1100 Subject: [PATCH 2/2] Added (optional) ifindex parameter to socket_connect() --- ext/sockets/sockets.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index a3c56cc81f606..49bd95b0bbd32 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -193,6 +193,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_connect, 0, 0, 2) ZEND_ARG_INFO(0, socket) ZEND_ARG_INFO(0, addr) ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, ifindex) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_strerror, 0, 0, 1) @@ -1488,7 +1489,7 @@ PHP_FUNCTION(socket_create) } /* }}} */ -/* {{{ proto bool socket_connect(resource socket, string addr [, int port]) +/* {{{ proto bool socket_connect(resource socket, string addr [, int port [, int ifindex]]) Opens a connection to addr:port on the socket specified by socket */ PHP_FUNCTION(socket_connect) { @@ -1496,10 +1497,10 @@ PHP_FUNCTION(socket_connect) php_socket *php_sock; char *addr; int retval, addr_len; - long port = 0; + long port = 0, ifindex = -1; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc TSRMLS_CC, "rs|l", &arg1, &addr, &addr_len, &port) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "rs|ll", &arg1, &addr, &addr_len, &port, &ifindex) == FAILURE) { return; } @@ -1510,7 +1511,7 @@ PHP_FUNCTION(socket_connect) case AF_INET6: { struct sockaddr_in6 sin6 = {0}; - if (argc != 3) { + if (argc != 3 && argc != 4) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Socket of type AF_INET6 requires 3 arguments"); RETURN_FALSE; } @@ -1520,6 +1521,8 @@ PHP_FUNCTION(socket_connect) sin6.sin6_family = AF_INET6; sin6.sin6_port = htons((unsigned short int)port); + if(ifindex != -1) sin6.sin6_scope_id = ifindex; + if (! php_set_inet6_addr(&sin6, addr, php_sock TSRMLS_CC)) { RETURN_FALSE; }