summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-11-06 21:41:51 +0100
committerBob Weinand <bobwei9@hotmail.com>2015-11-06 21:45:31 +0100
commit855bb36fd0bad9ac99a176d75a2792e9a1ed23a3 (patch)
treea3a420828a321a520729b8882dac7fff1871fbfc
parent049325ca9662e1d5e6fb2fdc7006b9a68385d9f9 (diff)
downloadphp-git-855bb36fd0bad9ac99a176d75a2792e9a1ed23a3.tar.gz
Add support for IPV6_V6ONLY on sockets
-rw-r--r--NEWS3
-rw-r--r--ext/sockets/sockets.c4
-rw-r--r--main/network.c6
-rw-r--r--main/php_network.h8
-rw-r--r--main/streams/xp_socket.c10
5 files changed, 28 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 0985ae6dda..9bac88ffc6 100644
--- a/NEWS
+++ b/NEWS
@@ -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