You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Tom Gilbert <to...@linuxbrit.co.uk> on 2001/10/31 21:46:41 UTC

[PATCH] read request timeout (against 1.3.22)

Hey,

Not sure if this is wanted or useful. I only just joined the ml.

We have some clients whose apps take a long time to create content, so
we have to run apache with Timeout set to 600. (They actually want more
- yuck).

Anyway, on our internal network (large, international), we have problems
with buggy clients connecting to apache and then not sending a request.
This hogs an apache child - unfortunately they often do this in crazy
doses - our primary production server with a MaxClients of 700 gets
DoS'd all to hell as all 700 children are sat trying to read a request
from a bad client. (The bad clients commonly spawn 300+ connections in
only a few seconds).

Server status looks a lot like:
9-1111010/142/628 R 0.95 99 2 0.0 0.22 0.88 ? ? ..reading..
One for each child.

The reads don't time out for 10 minutes - a classic DoS.

Further to this, unless I'm missing something crucial, 700 people
telnetting to port 80 or one guy with a 6 line perl script can DoS the
webserver quite easily.

We needed to fix this without affecting the main Timeout setting - the
apps are still slow...

Fixing the buggy clients is not an option, I'm afraid.

I've fixed this for us by adding a new timeout setting,
ReadRequestTimeout, which only applies during the period apache is trying
to read a request from the client.

I thought I'd send in the patch - even if you don't want it, feedback on
a better way to tackle this problem would be welcome.

ReadRequestTimeout in this patch defaults to DEFAULT_TIMEOUT (300), so
existing installations will be unaffected. The changes are minor, as
seen in the patch below.

Many thanks, I love apache :)

========================================================================

diff -ru apache_1.3.22.vanilla/src/include/httpd.h apache_1.3.22/src/include/httpd.h
--- apache_1.3.22.vanilla/src/include/httpd.h	Tue Oct  9 04:56:05 2001
+++ apache_1.3.22/src/include/httpd.h	Wed Oct 31 20:15:00 2001
@@ -958,6 +958,7 @@
 
     server_addr_rec *addrs;
     int timeout;		/* Timeout, in seconds, before we give up */
+    int read_request_timeout;		/* Seconds, we'll wait for an initial request */
     int keep_alive_timeout;	/* Seconds we'll wait for another request */
     int keep_alive_max;		/* Maximum requests per connection */
     int keep_alive;		/* Use persistent connections? */
diff -ru apache_1.3.22.vanilla/src/main/http_config.c apache_1.3.22/src/main/http_config.c
--- apache_1.3.22.vanilla/src/main/http_config.c	Fri Jun 22 13:43:54 2001
+++ apache_1.3.22/src/main/http_config.c	Wed Oct 31 20:13:03 2001
@@ -1417,6 +1417,7 @@
     s->srm_confname = NULL;
     s->access_confname = NULL;
     s->timeout = 0;
+    s->read_request_timeout = 0;
     s->keep_alive_timeout = 0;
     s->keep_alive = -1;
     s->keep_alive_max = -1;
@@ -1469,6 +1470,9 @@
 
 	if (virt->timeout == 0)
 	    virt->timeout = main_server->timeout;
+  
+	if (virt->read_request_timeout == 0)
+	    virt->read_request_timeout = main_server->read_request_timeout;
 
 	if (virt->keep_alive_timeout == 0)
 	    virt->keep_alive_timeout = main_server->keep_alive_timeout;
@@ -1537,6 +1541,7 @@
     s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
     s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
     s->timeout = DEFAULT_TIMEOUT;
+    s->read_request_timeout = DEFAULT_TIMEOUT;
     s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
     s->keep_alive_max = DEFAULT_KEEPALIVE;
     s->keep_alive = 1;
diff -ru apache_1.3.22.vanilla/src/main/http_core.c apache_1.3.22/src/main/http_core.c
--- apache_1.3.22.vanilla/src/main/http_core.c	Tue Sep  4 19:15:15 2001
+++ apache_1.3.22/src/main/http_core.c	Wed Oct 31 20:16:42 2001
@@ -2129,6 +2129,17 @@
     return NULL;
 }
 
+static const char *set_read_request_timeout(cmd_parms *cmd, void *dummy, char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
+    if (err != NULL) {
+        return err;
+    }
+
+    cmd->server->read_request_timeout = atoi(arg);
+    return NULL;
+}
+
 static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy,
 					  char *arg)
 {
@@ -3263,6 +3274,7 @@
     "'On': enable or default='Off': disable the EBCDIC Debugging MIME Header" },
 #endif
 #endif /* CHARSET_EBCDIC */
+{ "ReadRequestTimeout", set_read_request_timeout, NULL, RSRC_CONF, TAKE1, "Initial request timeout duration (sec)" },
 
 { NULL }
 };
diff -ru apache_1.3.22.vanilla/src/main/http_main.c apache_1.3.22/src/main/http_main.c
--- apache_1.3.22.vanilla/src/main/http_main.c	Sat Oct  6 03:21:11 2001
+++ apache_1.3.22/src/main/http_main.c	Wed Oct 31 20:11:18 2001
@@ -1612,7 +1612,7 @@
     if (r->connection->keptalive)
 	to = r->server->keep_alive_timeout;
     else
-	to = r->server->timeout;
+	to = r->server->read_request_timeout;
     ap_set_callback_and_alarm(timeout, to);
 }


Tom.
-- 
   .^.    .-------------------------------------------------------.
   /V\    | Tom Gilbert, London, England | http://linuxbrit.co.uk |
 /(   )\  | Open Source/UNIX consultant  | tom@linuxbrit.co.uk    |
  ^^-^^   `-------------------------------------------------------'

Re: [PATCH] read request timeout (against 1.3.22)

Posted by Martin Kraemer <Ma...@Fujitsu-Siemens.com>.
On Wed, Oct 31, 2001 at 08:46:41PM +0000, Tom Gilbert wrote:
> Hey,
> 
> Not sure if this is wanted or useful. I only just joined the ml.

Thanks! I put it into
 http://httpd.apache.org/dist/httpd/contrib/patches/1.3/apache_1.3.22-ReadRequestTimeout-directive.patch
so it won't get lost. Others will be delighted, even if it breaks their
binary compatibility.

   Martin
-- 
<Ma...@Fujitsu-Siemens.com>         |     Fujitsu Siemens
Fon: +49-89-636-46021, FAX: +49-89-636-47655 | 81730  Munich,  Germany