summaryrefslogtreecommitdiff
path: root/main/streams
diff options
context:
space:
mode:
authorDaniel Lowrey <rdlowrey@php.net>2014-08-04 12:41:51 -0400
committerDaniel Lowrey <rdlowrey@php.net>2014-08-05 23:13:04 -0400
commita51bf0cadf7862d10b2cc19cae2c991d24d670b1 (patch)
tree249332785260201b944727d852f0bb84315acc9d /main/streams
parent29eb0ea68605e81822e34d5a95443f2c176b2c73 (diff)
downloadphp-git-a51bf0cadf7862d10b2cc19cae2c991d24d670b1.tar.gz
Add SO_REUSEPORT + SO_BROADCAST support via socket stream context option
Diffstat (limited to 'main/streams')
-rw-r--r--main/streams/xp_socket.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c
index a6dc115962..c7b5a7098d 100644
--- a/main/streams/xp_socket.c
+++ b/main/streams/xp_socket.c
@@ -570,6 +570,8 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t *
{
char *host = NULL;
int portno, err;
+ long sockopts = STREAM_SOCKOP_NONE;
+ zval **tmpzval = NULL;
#ifdef AF_UNIX
if (stream->ops == &php_stream_unix_socket_ops || stream->ops == &php_stream_unixdg_socket_ops) {
@@ -599,8 +601,28 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t *
return -1;
}
+#ifdef SO_REUSEPORT
+ if (stream->context
+ && php_stream_context_get_option(stream->context, "socket", "so_reuseport", &tmpzval) == SUCCESS
+ && zend_is_true(*tmpzval)
+ ) {
+ sockopts |= STREAM_SOCKOP_SO_REUSEPORT;
+ }
+#endif
+
+#ifdef SO_BROADCAST
+ if (&php_stream_udp_socket_ops /* SO_BROADCAST is only applicable for UDP */
+ && stream->context
+ && php_stream_context_get_option(stream->context, "socket", "so_broadcast", &tmpzval) == SUCCESS
+ && zend_is_true(*tmpzval)
+ ) {
+ sockopts |= STREAM_SOCKOP_SO_BROADCAST;
+ }
+#endif
+
sock->socket = php_network_bind_socket_to_local_addr(host, portno,
stream->ops == &php_stream_udp_socket_ops ? SOCK_DGRAM : SOCK_STREAM,
+ sockopts,
xparam->want_errortext ? &xparam->outputs.error_text : NULL,
&err
TSRMLS_CC);
@@ -620,6 +642,7 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
int err = 0;
int ret;
zval **tmpzval = NULL;
+ long sockopts = STREAM_SOCKOP_NONE;
#ifdef AF_UNIX
if (stream->ops == &php_stream_unix_socket_ops || stream->ops == &php_stream_unixdg_socket_ops) {
@@ -665,6 +688,16 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
bindto = parse_ip_address_ex(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), &bindport, xparam->want_errortext, &xparam->outputs.error_text TSRMLS_CC);
}
+#ifdef SO_BROADCAST
+ if (&php_stream_udp_socket_ops /* SO_BROADCAST is only applicable for UDP */
+ && stream->context
+ && php_stream_context_get_option(stream->context, "socket", "so_broadcast", &tmpzval) == SUCCESS
+ && zend_is_true(*tmpzval)
+ ) {
+ sockopts |= STREAM_SOCKOP_SO_BROADCAST;
+ }
+#endif
+
/* Note: the test here for php_stream_udp_socket_ops is important, because we
* want the default to be TCP sockets so that the openssl extension can
* re-use this code. */
@@ -676,7 +709,8 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_
xparam->want_errortext ? &xparam->outputs.error_text : NULL,
&err,
bindto,
- bindport
+ bindport,
+ sockopts
TSRMLS_CC);
ret = sock->socket == -1 ? -1 : 0;