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 6632be3..c10ca19 100644 --- a/server/listen.c +++ b/server/listen.c @@ -64,6 +64,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 @@ -163,6 +164,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) { @@ -1004,6 +1020,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[]) { @@ -1069,6 +1086,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, scope_id, NULL, cmd->temp_pool); } +AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy, + int argc, + char *const argv[]) +{ + ap_listenfreebind = 1; + ap_set_listener(cmd, dummy, argc, argv); +} + AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg)