diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en index e7af21d..01d54b7 100644 --- a/docs/manual/mod/mpm_common.html.en +++ b/docs/manual/mod/mpm_common.html.en @@ -42,6 +42,7 @@ more than one multi-processing module (MPM)
  • EnableExceptionHook
  • GracefulShutdownTimeout
  • Listen
  • +
  • ListenFree
  • ListenBackLog
  • ListenCoresBucketsRatio
  • MaxConnectionsPerChild
  • @@ -244,6 +245,31 @@ discussion of the Address already in use error message, including other causes. + +
    top
    +

    ListenFree Directive

    + + + + + + + +
    Description:IP addresses and ports that the server +listens to. Doesn't require IP address to be up
    Syntax:ListenFree [IP-address:]portnumber [protocol]
    Context:server config
    Status:MPM
    Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
    Compatibility:This directive is currently available only in Red Hat Enterprise Linux
    +

    The ListenFree directive is + identical to the Listen directive. + The only difference is in the usage of the IP_FREEBIND socket + option, which is enabled by default with ListenFree. + If IP_FREEBIND is enabled, it allows httpd to bind to an IP + address that is nonlocal or does not (yet) exist. This allows httpd to + listen on a socket without requiring the underlying network interface + or the specified dynamic IP address to be up at the time when httpd + is trying to bind to it. +

    +
    + +
    top

    ListenBackLog Directive

    diff --git a/include/ap_listen.h b/include/ap_listen.h index 58c2574..1a53292 100644 --- a/include/ap_listen.h +++ b/include/ap_listen.h @@ -137,6 +137,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg); AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, int argc, char *const argv[]); +AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy, + int argc, char *const argv[]); + AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, const char *arg); AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, @@ -150,6 +153,8 @@ 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, \ "A port number or a numeric IP address and a port number, and an optional protocol"), \ +AP_INIT_TAKE_ARGV("ListenFree", ap_set_freelistener, NULL, 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, \ diff --git a/server/listen.c b/server/listen.c index e2e028a..6ef664b 100644 --- a/server/listen.c +++ b/server/listen.c @@ -63,6 +63,7 @@ static int ap_listenbacklog; static int ap_listencbratio; static int send_buffer_size; static int receive_buffer_size; +static int ap_listenfreebind; #ifdef HAVE_SYSTEMD static int use_systemd = -1; #endif @@ -162,6 +163,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_ } #endif + +#if defined(APR_SO_FREEBIND) + if (ap_listenfreebind) { + if (apr_socket_opt_set(s, APR_SO_FREEBIND, one) < 0) { + stat = apr_get_netos_error(); + ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02182) + "make_sock: apr_socket_opt_set: " + "error setting APR_SO_FREEBIND"); + apr_socket_close(s); + return stat; + } + } +#endif + + if (do_bind_listen) { #if APR_HAVE_IPV6 if (server->bind_addr->family == APR_INET6) { @@ -956,6 +972,7 @@ AP_DECLARE(void) ap_listen_pre_config(void) } } + AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, int argc, char *const argv[]) { @@ -1016,6 +1033,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, return alloc_listener(cmd->server->process, host, port, proto, NULL); } +AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy, + int argc, + char *const argv[]) +{ + ap_listenfreebind = 1; + return ap_set_listener(cmd, dummy, argc, argv); +} + AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg)