Skip to content

Exposing the sin6_scope_id parameter in socket_recvfrom, socket_sendto and socket_connect for IPv6 link-local unicast/multicast communications. #220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions ext/sockets/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -226,6 +227,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)
Expand All @@ -235,6 +237,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)
Expand Down Expand Up @@ -1486,18 +1489,18 @@ 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)
{
zval *arg1;
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;
}

Expand All @@ -1508,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;
}
Expand All @@ -1518,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;
}
Expand Down Expand Up @@ -1742,11 +1747,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;
Expand All @@ -1759,7 +1764,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;
}

Expand Down Expand Up @@ -1819,6 +1824,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:
Expand Down Expand Up @@ -1849,6 +1859,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:
Expand All @@ -1860,7 +1874,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)
{
Expand All @@ -1872,11 +1886,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;
}

Expand Down Expand Up @@ -1908,14 +1922,18 @@ PHP_FUNCTION(socket_sendto)
break;
#if HAVE_IPV6
case AF_INET6:
if (argc != 6) {
if (argc != 6 && argc != 7) {
WRONG_PARAM_COUNT;
}

memset(&sin6, 0, sizeof(sin6));
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;
}
Expand Down