Add support for IPV6_V6ONLY on sockets

This commit is contained in:
Bob Weinand 2015-11-06 21:41:51 +01:00
parent 049325ca96
commit 855bb36fd0
5 changed files with 28 additions and 3 deletions

3
NEWS
View file

@ -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)

View file

@ -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

View file

@ -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));

View file

@ -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) */

View file

@ -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