I basically copied the way the FreeBSD filters are used. This does a setsockopt to turn on TCP_DEFER_ACCEPT on 2.4 linux kernels. In Order for everything to compile correctly, use "-DTCP_DEFER_ACCEPT" in your CFLAGS.
-- Brian Akins Systems Engineer III CNN Internet Technologies
diff -pru ./src/include/http_conf_globals.h ../apache_1.3.22-defer/src/include/http_conf_globals.h --- ./src/include/http_conf_globals.h Fri Jul 13 03:32:35 2001 +++ ../apache_1.3.22-defer/src/include/http_conf_globals.h Tue Jan 15 08:31:44 2002 @@ -93,6 +93,10 @@ extern int ap_listenbacklog; #ifdef SO_ACCEPTFILTER extern int ap_acceptfilter; #endif +#ifdef TCP_DEFER_ACCEPT +extern int ap_deferaccept; +extern int ap_deferaccept_timeout; +#endif extern int ap_dump_settings; extern API_VAR_EXPORT int ap_extended_status; diff -pru ./src/main/http_core.c ../apache_1.3.22-defer/src/main/http_core.c --- ./src/main/http_core.c Tue Sep 4 14:15:15 2001 +++ ../apache_1.3.22-defer/src/main/http_core.c Tue Jan 15 09:45:22 2002 @@ -2540,6 +2540,22 @@ static const char *set_acceptfilter(cmd_ return NULL; } +/*Use the TCP_DEFER_ACCEPT socket option on Linux*/ +static const char *set_deferaccept(cmd_parms *cmd, void *dummy, int flag) +{ +#ifdef TCP_DEFER_ACCEPT + ap_deferaccept = flag; +#endif + return NULL; +} +static const char *set_deferaccept_timeout(cmd_parms *cmd, void *dummy, char *timeout) +{ +#ifdef TCP_DEFER_ACCEPT + ap_deferaccept_timeout = atoi(timeout); +#endif + return NULL; +} + static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips) { listen_rec *new; @@ -3191,6 +3207,26 @@ static const command_rec core_cmds[] = { "is ignored." #endif }, +{ "DeferAccept", set_deferaccept, NULL, RSRC_CONF, FLAG, + "Switch DeferAccept on/off (default is " +#ifdef AP_DEFERACCEPT_OFF + "off" +#else + "on" +#endif + ")." +#ifndef TCP_DEFER_ACCEPT + "This feature is currently not compiled in; so this directive " + "is ignored." +#endif + }, +{ "DeferAcceptTimeout", set_deferaccept_timeout, NULL, RSRC_CONF, TAKE1, + "Set DeferAccept timeout (default is 30" +#ifndef TCP_DEFER_ACCEPT + "This feature is currently not compiled in; so this directive " + "is ignored." +#endif + }, { "CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF, TAKE1, "The location of the directory Apache changes to before dumping core" }, { "Include", include_config, NULL, (RSRC_CONF | ACCESS_CONF), TAKE1, diff -pru ./src/main/http_main.c ../apache_1.3.22-defer/src/main/http_main.c --- ./src/main/http_main.c Fri Oct 5 22:21:11 2001 +++ ../apache_1.3.22-defer/src/main/http_main.c Tue Jan 15 09:50:05 2002 @@ -272,12 +272,23 @@ accept_mutex_methods_s *amutex; #ifdef SO_ACCEPTFILTER int ap_acceptfilter = #ifdef AP_ACCEPTFILTER_OFF - 0; + 0; #else 1; #endif #endif +#ifdef TCP_DEFER_ACCEPT +int ap_deferaccept_timeout = 30; +int ap_deferaccept = +#ifdef AP_DEFERACCEPT_OFF + 0; +#else + 1; +#endif +#endif + + int ap_dump_settings = 0; API_VAR_EXPORT int ap_extended_status = 0; @@ -3679,6 +3690,21 @@ static int make_sock(pool *p, const stru } #endif +#ifdef TCP_DEFER_ACCEPT + if (ap_deferaccept) { + + if (setsockopt(s, SOL_TCP, TCP_DEFER_ACCEPT, &ap_deferaccept_timeout, sizeof(int)) < 0) { + if (errno == ENOPROTOOPT) { + ap_log_error(APLOG_MARK, APLOG_INFO | APLOG_NOERRNO, server_conf, + "socket option TCP_DEFER_ACCEPT unkown on this machine. Continuing."); + } else { + ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, server_conf, + "make_sock: for %s, setsockopt: (TCP_DEFER_ACCEPT) failed", addr); + } + } + } +#endif + #ifdef WORKAROUND_SOLARIS_BUG s = ap_slack(s, AP_SLACK_HIGH); @@ -3987,6 +4013,12 @@ static void show_compile_settings(void) #endif #ifdef AP_ACCEPTFILTER_OFF printf(" -D AP_ACCEPTFILTER_OFF\n"); +#endif +#ifdef TCP_DEFER_ACCEPT + printf(" -D DEFER_ACCEPT\n"); +#endif +#ifdef AP_DEFERACCEPT_OFF + printf(" -D AP_DEFERACCEPT_OFF\n"); #endif