diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2015-11-06 21:41:51 +0100 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2015-11-06 21:45:31 +0100 |
commit | 855bb36fd0bad9ac99a176d75a2792e9a1ed23a3 (patch) | |
tree | a3a420828a321a520729b8882dac7fff1871fbfc | |
parent | 049325ca9662e1d5e6fb2fdc7006b9a68385d9f9 (diff) | |
download | php-git-855bb36fd0bad9ac99a176d75a2792e9a1ed23a3.tar.gz |
Add support for IPV6_V6ONLY on sockets
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/sockets/sockets.c | 4 | ||||
-rw-r--r-- | main/network.c | 6 | ||||
-rw-r--r-- | main/php_network.h | 8 | ||||
-rw-r--r-- | main/streams/xp_socket.c | 10 |
5 files changed, 28 insertions, 3 deletions
@@ -27,6 +27,9 @@ PHP NEWS . Fixed bug #70808 (array_merge_recursive corrupts memory of unset items). (Laruence) +- Streams/Socket + . Add IPV6_V6ONLY constant / make it usable in stream contexts. (Bob) + - XSL: . Fixed bug #70678 (PHP7 returns true when false is expected). (Felipe) diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 4385093fe9..39bfd2bf49 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -716,6 +716,10 @@ static PHP_MINIT_FUNCTION(sockets) REGISTER_LONG_CONSTANT("IPV6_MULTICAST_LOOP", IPV6_MULTICAST_LOOP, CONST_CS | CONST_PERSISTENT); #endif +#ifdef IPV6_V6ONLY + REGISTER_LONG_CONSTANT("IPV6_V6ONLY", IPV6_V6ONLY, CONST_CS | CONST_PERSISTENT); +#endif + #ifndef WIN32 # include "unix_socket_constants.h" #else diff --git a/main/network.c b/main/network.c index c08194bcd6..cb112464d1 100644 --- a/main/network.c +++ b/main/network.c @@ -472,6 +472,12 @@ php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned po #ifdef SO_REUSEADDR setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&sockoptval, sizeof(sockoptval)); #endif +#ifdef IPV6_V6ONLY + if (sockopts & STREAM_SOCKOP_IPV6_V6ONLY) { + int ipv6_val = !!(sockopts & STREAM_SOCKOP_IPV6_V6ONLY_ENABLED); + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6_val, sizeof(sockoptval)); + } +#endif #ifdef SO_REUSEPORT if (sockopts & STREAM_SOCKOP_SO_REUSEPORT) { setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char*)&sockoptval, sizeof(sockoptval)); diff --git a/main/php_network.h b/main/php_network.h index d17530208a..a0b87797b6 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -106,9 +106,11 @@ typedef int php_socket_t; # define SOCK_RECV_ERR -1 #endif -#define STREAM_SOCKOP_NONE 1 << 0 -#define STREAM_SOCKOP_SO_REUSEPORT 1 << 1 -#define STREAM_SOCKOP_SO_BROADCAST 1 << 2 +#define STREAM_SOCKOP_NONE (1 << 0) +#define STREAM_SOCKOP_SO_REUSEPORT (1 << 1) +#define STREAM_SOCKOP_SO_BROADCAST (1 << 2) +#define STREAM_SOCKOP_IPV6_V6ONLY (1 << 3) +#define STREAM_SOCKOP_IPV6_V6ONLY_ENABLED (1 << 4) /* uncomment this to debug poll(2) emulation on systems that have poll(2) */ diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index e88bb91208..be4edd76e9 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -635,6 +635,16 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t * return -1; } +#ifdef IPV6_V6ONLY + if (PHP_STREAM_CONTEXT(stream) + && (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "ipv6_v6only")) != NULL + && Z_TYPE_P(tmpzval) != IS_NULL + ) { + sockopts |= STREAM_SOCKOP_IPV6_V6ONLY; + sockopts |= STREAM_SOCKOP_IPV6_V6ONLY_ENABLED * zend_is_true(tmpzval); + } +#endif + #ifdef SO_REUSEPORT if (PHP_STREAM_CONTEXT(stream) && (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "so_reuseport")) != NULL |