Re: com php-src: Add SO_REUSEPORT + SO_BROADCAST support via socket stream context option: ext/ftp/ftp.c main/network.c main/php_network.h
main/streams/xp_socket.c
| From: | Dmitry Stogov | Date: | Mon, 11 Aug 2014 07:09:39 +0000 |
| Subject: | Re: com php-src: Add SO_REUSEPORT + SO_BROADCAST support via socket stream context option: ext/ftp/ftp.c main/network.c main/php_network.h main/streams/xp_socket.c |
||
| References: | 1 | Groups: | php.cvs |
| Request: | Send a blank email to php-cvs+get-79797@lists.php.net to get a copy of this message | ||
Hi Daniel,
The following line from your patch looks wrong for me.
main/streams/xp_socket.c:(614) if (&php_stream_udp_socket_ops /*
SO_BROADCAST is only applica...
You probably meant - stream->ops == &php_stream_udp_socket_ops
Thanks. Dmitry.
On Wed, Aug 6, 2014 at 6:43 AM, <rdlowrey@php.net> wrote:
> Commit: 60552a887104e83c7e6425f0625ffa9d19e5a8dc
> Author: Daniel Lowrey <rdlowrey@php.net> Mon, 4 Aug 2014
> 12:41:51 -0400
> Parents: 29eb0ea68605e81822e34d5a95443f2c176b2c73
> Branches: master
>
> Link:
> /£
> êÝ]Mu ™B%°ÆåQhttp://git.php.net/?p=php-src.git;a=commitdiff;h=60552a887104e83c7e6425f0625ffa9d19e5a8dc
>
> Log:
> Add SO_REUSEPORT + SO_BROADCAST support via socket stream context option
>
> Changed paths:
> M ext/ftp/ftp.c
> M main/network.c
> M main/php_network.h
> M main/streams/xp_socket.c
>
>
> Diff:
> diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
> index 558463b..d05f0ee 100644
> --- a/ext/ftp/ftp.c
> +++ b/ext/ftp/ftp.c
> @@ -136,7 +136,7 @@ ftp_open(const char *host, short port, long
> timeout_sec TSRMLS_DC)
>
> ftp->fd = php_network_connect_socket_to_host(host,
> (unsigned short) (port ? port : 21), SOCK_STREAM,
> - 0, &tv, NULL, NULL, NULL, 0 TSRMLS_CC);
> + 0, &tv, NULL, NULL, NULL, 0, STREAM_SOCKOP_NONE
> TSRMLS_CC);
> if (ftp->fd == -1) {
> goto bail;
> }
> diff --git a/main/network.c b/main/network.c
> index fc2a94b..39f5a22 100644
> --- a/main/network.c
> +++ b/main/network.c
> @@ -416,13 +416,14 @@ static inline void sub_times(struct timeval a,
> struct timeval b, struct timeval
> * */
> /* {{{ php_network_bind_socket_to_local_addr */
> php_socket_t php_network_bind_socket_to_local_addr(const char *host,
> unsigned port,
> - int socktype, char **error_string, int *error_code
> + int socktype, long sockopts, char **error_string, int
> *error_code
> TSRMLS_DC)
> {
> int num_addrs, n, err = 0;
> php_socket_t sock;
> struct sockaddr **sal, **psal, *sa;
> socklen_t socklen;
> + int sockoptval = 1;
>
> num_addrs = php_network_getaddresses(host, socktype, &psal,
> error_string TSRMLS_CC);
>
> @@ -464,9 +465,16 @@ php_socket_t
> php_network_bind_socket_to_local_addr(const char *host, unsigned po
> /* attempt to bind */
>
> #ifdef SO_REUSEADDR
> - {
> - int val = 1;
> - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
> (char*)&val, sizeof(val));
> + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
> (char*)&sockoptval, sizeof(sockoptval));
> +#endif
> +#ifdef SO_REUSEPORT
> + if (sockopts & STREAM_SOCKOP_SO_REUSEPORT) {
> + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT,
> (char*)&sockoptval, sizeof(sockoptval));
> + }
> +#endif
> +#ifdef SO_BROADCAST
> + if (sockopts & STREAM_SOCKOP_SO_BROADCAST) {
> + setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
> (char*)&sockoptval, sizeof(sockoptval));
> }
> #endif
>
> @@ -762,7 +770,7 @@ PHPAPI php_socket_t
> php_network_accept_incoming(php_socket_t srvsock,
> /* {{{ php_network_connect_socket_to_host */
> php_socket_t php_network_connect_socket_to_host(const char *host,
> unsigned short port,
> int socktype, int asynchronous, struct timeval *timeout,
> char **error_string,
> - int *error_code, char *bindto, unsigned short bindport
> + int *error_code, char *bindto, unsigned short bindport,
> long sockopts
> TSRMLS_DC)
> {
> int num_addrs, n, fatal = 0;
> @@ -864,6 +872,7 @@ php_socket_t php_network_connect_socket_to_host(const
> char *host, unsigned short
> }
> }
> #endif
> +
> if (!local_address || bind(sock,
> local_address, local_address_len)) {
> php_error_docref(NULL TSRMLS_CC,
> E_WARNING, "failed to bind to '%s:%d', system said: %s", bindto, bindport,
> strerror(errno));
> }
> @@ -878,6 +887,14 @@ skip_bind:
> *error_string = NULL;
> }
>
> +#ifdef SO_BROADCAST
> + {
> + int val = 1;
> + if (sockopts & STREAM_SOCKOP_SO_BROADCAST)
> {
> + setsockopt(sock, SOL_SOCKET,
> SO_BROADCAST, (char*)&val, sizeof(val));
> + }
> + }
> +#endif
> n = php_network_connect_socket(sock, sa, socklen,
> asynchronous,
> timeout ? &working_timeout : NULL,
> error_string, error_code);
> diff --git a/main/php_network.h b/main/php_network.h
> index d69bba3..95299e6 100644
> --- a/main/php_network.h
> +++ b/main/php_network.h
> @@ -105,6 +105,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
> +
> +
> /* uncomment this to debug poll(2) emulation on systems that have poll(2)
> */
> /* #define PHP_USE_POLL_2_EMULATION 1 */
>
> @@ -229,7 +234,7 @@ PHPAPI void php_network_freeaddresses(struct sockaddr
> **sal);
>
> PHPAPI php_socket_t php_network_connect_socket_to_host(const char *host,
> unsigned short port,
> int socktype, int asynchronous, struct timeval *timeout,
> char **error_string,
> - int *error_code, char *bindto, unsigned short bindport
> + int *error_code, char *bindto, unsigned short bindport,
> long sockopts
> TSRMLS_DC);
>
> PHPAPI int php_network_connect_socket(php_socket_t sockfd,
> @@ -244,7 +249,7 @@ PHPAPI int php_network_connect_socket(php_socket_t
> sockfd,
> php_network_connect_socket((sock), (addr), (addrlen), 0,
> (timeout), NULL, NULL)
>
> PHPAPI php_socket_t php_network_bind_socket_to_local_addr(const char
> *host, unsigned port,
> - int socktype, char **error_string, int *error_code
> + int socktype, long sockopts, char **error_string, int
> *error_code
> TSRMLS_DC);
>
> PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock,
> diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c
> index a6dc115..c7b5a70 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;
>
>
> --
> PHP CVS Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>