diff --git a/changes-entries/listentcpdeferaccept.txt b/changes-entries/listentcpdeferaccept.txt new file mode 100644 index 00000000000..87dec8ff0c5 --- /dev/null +++ b/changes-entries/listentcpdeferaccept.txt @@ -0,0 +1,3 @@ + *) mpm_common: Add new ListenTCPDeferAccept directive that allows to specify + the value set for the TCP_DEFER_ACCEPT socket option on listen sockets. + [Ruediger Pluem] diff --git a/docs/manual/mod/mpm_common.xml b/docs/manual/mod/mpm_common.xml index cab75eed306..252890851e8 100644 --- a/docs/manual/mod/mpm_common.xml +++ b/docs/manual/mod/mpm_common.xml @@ -363,6 +363,29 @@ in *BSDs. + +ListenTCPDeferAccept +Value set for the socket option TCP_DEFER_ACCEPT if it is set +ListenTCPDeferAccept integer +ListenTCPDeferAccept 30 +server config +eventworker +prefork + +Available in Apache HTTP Server 2.5.1 and later + + +

The value specified here is set as a value for the socket option + TCP_DEFER_ACCEPT if it is set on the listen socket. + This happens when running on Linux and AcceptFilter is set to anything besides + none. In any other cases this setting is ignored. + For more details see the Linux + + tcp(7) man page.

+
+
+ MaxRequestWorkers Maximum number of connections that will be processed diff --git a/include/ap_listen.h b/include/ap_listen.h index d5ed9685c54..9b3431e0cb3 100644 --- a/include/ap_listen.h +++ b/include/ap_listen.h @@ -135,6 +135,7 @@ AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *); * called. */ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg); +AP_DECLARE_NONSTD(const char *) ap_set_listentcpdeferaccept(cmd_parms *cmd, void *dummy, const char *arg); 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[]); @@ -163,7 +164,9 @@ AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \ 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, \ - RSRC_CONF, "Receive buffer size in bytes") + RSRC_CONF, "Receive buffer size in bytes"), \ +AP_INIT_TAKE1("ListenTCPDeferAccept", ap_set_listentcpdeferaccept, NULL, RSRC_CONF, \ + "Value set for the socket option TCP_DEFER_ACCEPT if it is set") #ifdef __cplusplus } diff --git a/include/mpm_common.h b/include/mpm_common.h index 539d6401bb3..6b3d1f536fb 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -63,6 +63,14 @@ extern "C" { #define DEFAULT_LISTENBACKLOG 511 #endif +/* + * Define the default value set for the socket option TCP_DEFER_ACCEPT + * if it is set. + */ +#ifndef DEFAULT_TCP_DEFER_ACCEPT +#define DEFAULT_TCP_DEFER_ACCEPT 30 +#endif + /* Signal used to gracefully restart */ #define AP_SIG_GRACEFUL SIGUSR1 diff --git a/server/listen.c b/server/listen.c index cb7e59eb34c..aff5348d9a6 100644 --- a/server/listen.c +++ b/server/listen.c @@ -57,6 +57,7 @@ AP_DECLARE_DATA int ap_have_so_reuseport = -1; static ap_listen_rec *old_listeners; static int ap_listenbacklog; +static int ap_listentcpdeferaccept; static int ap_listencbratio; static int send_buffer_size; static int receive_buffer_size; @@ -268,7 +269,7 @@ static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis, accf); } #else - rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 30); + rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, ap_listentcpdeferaccept); if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) { ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p, APLOGNO(00076) "Failed to enable APR_TCP_DEFER_ACCEPT"); @@ -947,6 +948,7 @@ AP_DECLARE(void) ap_listen_pre_config(void) ap_listen_buckets = NULL; ap_num_listen_buckets = 0; ap_listenbacklog = DEFAULT_LISTENBACKLOG; + ap_listentcpdeferaccept = DEFAULT_TCP_DEFER_ACCEPT; ap_listencbratio = 0; /* Check once whether or not SO_REUSEPORT is supported. */ @@ -1076,6 +1078,26 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, return NULL; } +AP_DECLARE_NONSTD(const char *) ap_set_listentcpdeferaccept(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + int b; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + b = atoi(arg); + if (b < 1) { + return "ListenTCPDeferAccept must be > 0"; + } + + ap_listentcpdeferaccept = b; + return NULL; +} + AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg)