Folks,

the patch below cannot be literally backported to 2.0.x.  Everyone would
agree that the echo filter is inherently a DoS attack even when it's
working as expected.  But other protocol module authors have based their
code on this module; and it was dangerous precident to never establish
any timeout.

We could, obviously, throw the same hack as mod_ftp's code in mod_echo,
prior to the first get_brigade invocation;

     client_socket = ap_get_module_config(cdata->conn_config,
                                          &core_module);
     apr_socket_timeout_set(client_socket, cdata->base_server->timeout);

but that's hackish, and truly does nothing for any existing borked
protocol module out there, written by unsuspecting authors.

Here's a proposed patch for 2.0 that would move the -initial- timeout
setting from underneath NET_TIME.  Yet it would retain the NET_TIME
filter for managing keep-alive time outs, thus maintaining all binary
and nearly identical behavior compatibility in the 2.0.x branch.

Comments?

Index: server/core.c
===================================================================
--- server/core.c	(revision 307178)
+++ server/core.c	(working copy)
@@ -3671,11 +3671,9 @@
     }
 
     if (mode != AP_MODE_INIT && mode != AP_MODE_EATCRLF) {
-        if (ctx->first_line) {
-            apr_socket_timeout_set(ctx->csd, 
-                                   keptalive
-                                      ? f->c->base_server->keep_alive_timeout
-                                      : f->c->base_server->timeout);
+        if (keptalive && ctx->first_line) {
+            apr_socket_timeout_set(ctx->csd,
+                                   f->c->base_server->keep_alive_timeout);
             ctx->first_line = 0;
         }
         else {
@@ -4485,10 +4483,9 @@
 static int core_pre_connection(conn_rec *c, void *csd)
 {
     core_net_rec *net = apr_palloc(c->pool, sizeof(*net));
+    apr_status_t rv;
 
 #ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
-    apr_status_t rv;
-
     /* BillS says perhaps this should be moved to the MPMs. Some OSes
      * allow listening socket attributes to be inherited by the
      * accept sockets which means this call only needs to be made
@@ -4510,6 +4507,20 @@
                       "apr_socket_opt_set(APR_TCP_NODELAY)");
     }
 #endif
+
+    /* The core filter requires the timeout mode to be set, which
+     * incidentally sets the socket to be nonblocking.  If this
+     * is not initialized correctly, Linux - for example - will
+     * be initially blocking, while Solaris will be non blocking
+     * and any initial read will fail.
+     */
+    rv = apr_socket_timeout_set(csd, c->base_server->timeout);
+    if (rv != APR_SUCCESS) {
+        /* expected cause is that the client disconnected already */
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, c,
+                     "apr_socket_timeout_set");
+    }
+
     net->c = c;
     net->in_ctx = NULL;
     net->out_ctx = NULL;

Reply via email to