summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bühler <stbuehler@web.de>2009-04-26 17:59:55 +0000
committerStefan Bühler <stbuehler@web.de>2009-04-26 17:59:55 +0000
commit7fe64444f133085870bb31d88ae3602f79d43a68 (patch)
tree7776b3c519a224b5c9239e7c2a05903c52807d84
parentab063770d4350a3b7bc9924912eee884f98deb44 (diff)
downloadlighttpd-git-7fe64444f133085870bb31d88ae3602f79d43a68.tar.gz
Add option to enable TCP_DEFER_ACCEPT (fixes #1447)
git-svn-id: svn+ssh://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2479 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--NEWS1
-rw-r--r--doc/configuration.txt6
-rw-r--r--src/base.h1
-rw-r--r--src/configfile.c3
-rw-r--r--src/network.c17
5 files changed, 20 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index 1d6a86d4..ce6836d1 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,7 @@ NEWS
* Change name/version separator back to "/" (affects every place where the version is printed)
* Fix bug with FastCGI request id overflow under high load; just use always id 1 as we don't use multiplexing. (thx jgray)
* Add some dirlisting enhancements (fixes #1458)
+ * Add option to enable TCP_DEFER_ACCEPT (fixes #1447)
- 1.4.22 - 2009-03-07
* Fix wrong lua type for CACHE_MISS/CACHE_HIT in mod_cml (fixes #533)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index ed836ecc..3d49f7ff 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -281,6 +281,12 @@ server.port
server.use-ipv6
bind to the IPv6 socket
+server.defer-accept
+ set TCP_DEFER_ACCEPT to the specified value on the socket if the value is > 0
+ and TCP_DEFER_ACCEPT is available on the platform (linux2.4+)
+
+ default: 0
+
server.tag
set the string returned by the Server: response header
diff --git a/src/base.h b/src/base.h
index 4057ab66..f35eadc7 100644
--- a/src/base.h
+++ b/src/base.h
@@ -274,6 +274,7 @@ typedef struct {
unsigned short ssl_use_sslv2;
unsigned short use_ipv6;
+ unsigned short defer_accept;
unsigned short is_ssl;
unsigned short allow_http11;
unsigned short etag_use_inode;
diff --git a/src/configfile.c b/src/configfile.c
index e45db852..11117e7c 100644
--- a/src/configfile.c
+++ b/src/configfile.c
@@ -96,6 +96,7 @@ static int config_insert(server *srv) {
{ "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */
{ "server.reject-expect-100-with-417", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */
{ "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */
+ { "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */
{ "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
@@ -164,6 +165,7 @@ static int config_insert(server *srv) {
s->is_ssl = 0;
s->ssl_use_sslv2 = 0;
s->use_ipv6 = 0;
+ s->defer_accept = 0;
#ifdef HAVE_LSTAT
s->follow_symlink = 1;
#endif
@@ -182,6 +184,7 @@ static int config_insert(server *srv) {
cv[7].destination = s->server_tag;
cv[8].destination = &(s->use_ipv6);
+ cv[54].destination = &(s->defer_accept);
/* 13 max-worker */
diff --git a/src/network.c b/src/network.c
index a886cf5e..e2d5f0b9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -73,10 +73,6 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
int is_unix_domain_socket = 0;
int fd;
-#ifdef SO_ACCEPTFILTER
- struct accept_filter_arg afa;
-#endif
-
#ifdef __WIN32
WORD wVersionRequested;
WSADATA wsaData;
@@ -396,12 +392,17 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
return -1;
#endif
+#ifdef TCP_DEFER_ACCEPT
+ } else if (s->defer_accept) {
+ int v = s->defer_accept;
+ if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno));
+ }
+#endif
} else {
#ifdef SO_ACCEPTFILTER
- /*
- * FreeBSD accf_http filter
- *
- */
+ /* FreeBSD accf_http filter */
+ struct accept_filter_arg afa;
memset(&afa, 0, sizeof(afa));
strcpy(afa.af_name, "httpready");
if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {