Re: [PATCH] Add "FreeListen" to support IP_FREEBIND

2016-03-07 Thread William A Rowe Jr
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

2016-03-07 Thread Yehuda Katz
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

2016-03-07 Thread William A Rowe Jr
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

2016-03-07 Thread Jan Kaluža

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

2016-03-07 Thread Jim Jagielski
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

2016-03-07 Thread Jan Kaluža

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