Re: [PATCH] Add "FreeListen" to support IP_FREEBIND
On Mar 7, 2016 21:59, "Yehuda Katz" wrote: > > On Mon, Mar 7, 2016 at 9:06 PM, William A Rowe Jr wrote: >> >> On Mar 7, 2016 13:54, "Jan Kaluža" wrote: >> > >> > On 03/07/2016 04:17 PM, Jim Jagielski wrote: >> >> >> >> Intstead of adding YAD (yet another directive ;) ), would it >> >> be possible to somehow leverage Listen itself, maybe with some >> >> sort of flag? >> > >> > >> > Yes, that would be quite possible. I was thinking about that way, but I have chosen YAD as a first approach. If you think adding flag to Listen is better way, I can rework my patch. >> > >> > Regards, >> > Jan Kaluza >> > >> >> Reviewing the behavior, an unadorned new directive makes more sense to me than cluttering Listen, which already takes one optional protocol behavior argument. >> >> The same handler can process both directives. > > A benefit of using a flag is: what happens if the default changes at some point? YAD would need to be created to go back to the old behavior - which would make things more complicated. Is it possible to use something like a plus/minus or question mark symbol with each address:port which would allow the default to be changed at some future point without requiring having this discussion again? > > Example: > Listen ?192.170.2.1:80 # Use IP_FREEBIND to listen when IP is available (new behavior) > Listen +192.170.2.5:8000 # Require IP to be available (old behavior) > Listen [2001:db8::a00:20ff:fea7:ccea]:80 # Current default behavior (old) Interesting point, I raised the same consideration for piped logging syntax some years ago. But at that time it was the consensus that the default would change with the next major version. I see small probably that this would become a default behavior, from the perspective of robustness alone. I see that you simply suggest a tri-state (and trailing '?' Vs '!' makes more intuitive sense to me), but I'm not seeing a consensus yet that the default would change in the future. The same can be accomplished by adding a third 'FixedListen' directive, leaving Listen itself free to switch behaviors. But from the migration perspective, I'd be loath to switch any default Listen behavior without the admin's explicit intervention. POLS.
Re: [PATCH] Add "FreeListen" to support IP_FREEBIND
On Mon, Mar 7, 2016 at 9:06 PM, William A Rowe Jr wrote: > On Mar 7, 2016 13:54, "Jan Kaluža" wrote: > > > > On 03/07/2016 04:17 PM, Jim Jagielski wrote: > >> > >> Intstead of adding YAD (yet another directive ;) ), would it > >> be possible to somehow leverage Listen itself, maybe with some > >> sort of flag? > > > > > > Yes, that would be quite possible. I was thinking about that way, but I > have chosen YAD as a first approach. If you think adding flag to Listen is > better way, I can rework my patch. > > > > Regards, > > Jan Kaluza > > > Reviewing the behavior, an unadorned new directive makes more sense to me > than cluttering Listen, which already takes one optional protocol behavior > argument. > > The same handler can process both directives. > A benefit of using a flag is: what happens if the default changes at some point? YAD would need to be created to go back to the old behavior - which would make things more complicated. Is it possible to use something like a plus/minus or question mark symbol with each address:port which would allow the default to be changed at some future point without requiring having this discussion again? Example: Listen ?192.170.2.1:80 # Use IP_FREEBIND to listen when IP is available (new behavior) Listen +192.170.2.5:8000 # Require IP to be available (old behavior) Listen [2001:db8::a00:20ff:fea7:ccea]:80 # Current default behavior (old) - Y
Re: [PATCH] Add "FreeListen" to support IP_FREEBIND
On Mar 7, 2016 13:54, "Jan Kaluža" wrote: > > On 03/07/2016 04:17 PM, Jim Jagielski wrote: >> >> Intstead of adding YAD (yet another directive ;) ), would it >> be possible to somehow leverage Listen itself, maybe with some >> sort of flag? > > > Yes, that would be quite possible. I was thinking about that way, but I have chosen YAD as a first approach. If you think adding flag to Listen is better way, I can rework my patch. > > Regards, > Jan Kaluza > > >>> On Mar 7, 2016, at 6:41 AM, Jan Kaluža wrote: >>> >>> Hi, >>> >>> attached patch adds new "FreeListen" directive. The difference between "Listen" and "FreeListen" is that "FreeListen" sets the IP_FREEBIND socket option on platforms where this is available. >>> >>> It is therefore possible to start the server even when particular IP address set in the "FreeListen" is not configured yet. >>> >>> This is needed for httpd startup with systemd when one wants to use particular IP address to bind. There is no way how to start httpd after the IP address has been configured in systemd and according to systemd developers, the applications should become more robust to handle network changes like that. The full reasoning is explained here [1]. >>> >>> The patch needs latest APR-trunk currently, but it could be rewritten to set IP_FREEBIND directly instead of using APR API (We use that way for REUSEADDR socket option). >>> >>> Do you think FreeListen is good name for this feature, or would you name/implement it differently? >>> >>> [1] https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ >>> >>> Regards, >>> Jan Kaluza >>> Reviewing the behavior, an unadorned new directive makes more sense to me than cluttering Listen, which already takes one optional protocol behavior argument. The same handler can process both directives.
Re: [PATCH] Add "FreeListen" to support IP_FREEBIND
On 03/07/2016 04:17 PM, Jim Jagielski wrote: Intstead of adding YAD (yet another directive ;) ), would it be possible to somehow leverage Listen itself, maybe with some sort of flag? Yes, that would be quite possible. I was thinking about that way, but I have chosen YAD as a first approach. If you think adding flag to Listen is better way, I can rework my patch. Regards, Jan Kaluza On Mar 7, 2016, at 6:41 AM, Jan Kaluža wrote: Hi, attached patch adds new "FreeListen" directive. The difference between "Listen" and "FreeListen" is that "FreeListen" sets the IP_FREEBIND socket option on platforms where this is available. It is therefore possible to start the server even when particular IP address set in the "FreeListen" is not configured yet. This is needed for httpd startup with systemd when one wants to use particular IP address to bind. There is no way how to start httpd after the IP address has been configured in systemd and according to systemd developers, the applications should become more robust to handle network changes like that. The full reasoning is explained here [1]. The patch needs latest APR-trunk currently, but it could be rewritten to set IP_FREEBIND directly instead of using APR API (We use that way for REUSEADDR socket option). Do you think FreeListen is good name for this feature, or would you name/implement it differently? [1] https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ Regards, Jan Kaluza
Re: [PATCH] Add "FreeListen" to support IP_FREEBIND
Intstead of adding YAD (yet another directive ;) ), would it be possible to somehow leverage Listen itself, maybe with some sort of flag? > On Mar 7, 2016, at 6:41 AM, Jan Kaluža wrote: > > Hi, > > attached patch adds new "FreeListen" directive. The difference between > "Listen" and "FreeListen" is that "FreeListen" sets the IP_FREEBIND socket > option on platforms where this is available. > > It is therefore possible to start the server even when particular IP address > set in the "FreeListen" is not configured yet. > > This is needed for httpd startup with systemd when one wants to use > particular IP address to bind. There is no way how to start httpd after the > IP address has been configured in systemd and according to systemd > developers, the applications should become more robust to handle network > changes like that. The full reasoning is explained here [1]. > > The patch needs latest APR-trunk currently, but it could be rewritten to set > IP_FREEBIND directly instead of using APR API (We use that way for REUSEADDR > socket option). > > Do you think FreeListen is good name for this feature, or would you > name/implement it differently? > > [1] https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ > > Regards, > Jan Kaluza >
[PATCH] Add "FreeListen" to support IP_FREEBIND
Hi, attached patch adds new "FreeListen" directive. The difference between "Listen" and "FreeListen" is that "FreeListen" sets the IP_FREEBIND socket option on platforms where this is available. It is therefore possible to start the server even when particular IP address set in the "FreeListen" is not configured yet. This is needed for httpd startup with systemd when one wants to use particular IP address to bind. There is no way how to start httpd after the IP address has been configured in systemd and according to systemd developers, the applications should become more robust to handle network changes like that. The full reasoning is explained here [1]. The patch needs latest APR-trunk currently, but it could be rewritten to set IP_FREEBIND directly instead of using APR API (We use that way for REUSEADDR socket option). Do you think FreeListen is good name for this feature, or would you name/implement it differently? [1] https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ Regards, Jan Kaluza Index: docs/manual/mod/mpm_common.xml === --- docs/manual/mod/mpm_common.xml (revision 1733461) +++ docs/manual/mod/mpm_common.xml (working copy) @@ -104,6 +104,31 @@ +FreeListen +IP addresses and ports that the server +listens to +FreeListen [IP-address:]portnumber [protocol] +server config +eventworker +preforkmpm_winnt +mpm_netwarempmt_os2 + + + +The FreeListen directive has the same meaning +as the Listen directive. The difference between +these two directives is that FreeListen directive +sets the IP_FREEBIND socket option on platforms where this +option is available. + +It is therefore possible to start the server even when particular IP +address set in the FreeListen directive is not +configured yet. + +Listen + + + GracefulShutdownTimeout Specify a timeout after which a gracefully shutdown server will exit. @@ -241,6 +266,7 @@ +FreeListen DNS Issues Setting which addresses and ports Apache HTTP Server uses Index: include/ap_listen.h === --- include/ap_listen.h (revision 1733461) +++ include/ap_listen.h (working copy) @@ -71,6 +71,10 @@ const char* protocol; ap_slave_t *slave; +/** + * Whether use APR_SO_FREEBIND. + */ +int free_bind; }; /** @@ -148,8 +152,10 @@ "Maximum length of the queue of pending connections, as used by listen(2)"), \ AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF, \ "Ratio between the number of CPU cores (online) and the number of listeners buckets"), \ -AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \ +AP_INIT_TAKE_ARGV("Listen", ap_set_listener, (void *) 0, RSRC_CONF, \ "A port number or a numeric IP address and a port number, and an optional protocol"), \ +AP_INIT_TAKE_ARGV("FreeListen", ap_set_listener, (void *) 1, RSRC_CONF, \ + "A port number or a numeric IP address and a port number, and an optional protocol"), \ AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \ "Send buffer size in bytes"), \ AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ Index: server/listen.c === --- server/listen.c (revision 1733461) +++ server/listen.c (working copy) @@ -68,7 +68,8 @@ #endif /* TODO: make_sock is just begging and screaming for APR abstraction */ -static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen) +static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, + int do_bind_listen) { apr_socket_t *s = server->sd; int one = 1; @@ -162,6 +163,21 @@ } #endif + if (server->free_bind) { +#if defined(APR_SO_FREEBIND) +stat = apr_socket_opt_set(s, APR_SO_FREEBIND, one); +if (stat != APR_SUCCESS) { +ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, APLOGNO(00071) + "make_sock: failed to set set IP_FREEBIND socket option"); +return stat; +} +#else +ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, APLOGNO(00071) +"make_sock: FreeListen not supported by the system"); +return APR_ENOTIMPL; +#endif +} + if (do_bind_listen) { #if APR_HAVE_IPV6 if (server->bind_addr->family == APR_INET6) { @@ -348,6 +364,7 @@ rec = apr_palloc(process->pool, sizeof(ap_listen_rec)); rec->active = 0; rec->next = 0; +rec->free_bind = 0; rv = apr_os_sock_make(&rec->sd, &si, process->pool); if (rv != APR_SUCCESS) { @@ -406,7 +423,7 @@ static const char *alloc_listener(process_rec *process, char *addr, apr_port_t port, const char* proto, - void *slave) +