To Apache Flood development team:

As part of our work on the Flood code (in our usage of it as par of an
enterprise product), I have been instructed to contribute back our changes
on a daily basis so we can both contribute them back to the product and
get back inportant feedback on these changes.

Other than some small touch-ups, these changes to flood_net_ssl.c involve
1) taking recursive function code out of socket read/write functions,
(replacing with do .. while loop) resulting in
a) more robust code, with less possibility of stack-related issues.
b) errors returned in recursively-called code were not being propagated.
c) with iterative code it is easier to set limits on the amount of
iteration, if necessary. I have not changed the logic here (yet).

and
2) the addition of certain cases which should cause a continuation of
reading.

The -u3 diff is taken from the current directory holding the modified file
and the \flood-1.1 directory holding the original from Apache project, and
is attached here as fns.diff since as inline the mailer would modify the
text.

-Norman Tuttle, OpenDemand Systems Developer [EMAIL PROTECTED]
--- flood_net_ssl.c     2003-10-13 09:30:48.000000000 -0400
+++ \flood-1.1\flood_net_ssl.c  2003-10-08 19:25:02.000000000 -0400
@@ -84,8 +84,8 @@
 #if APR_HAS_THREADS
 apr_thread_mutex_t **ssl_locks;
 
-typedef struct CRYPTO_dynlock_value {
-    apr_thread_mutex_t *lock;
+typedef struct CRYPTO_dynlock_value { 
+    apr_thread_mutex_t *lock; 
 } CRYPTO_dynlock_value;
 
 static CRYPTO_dynlock_value *ssl_dyn_create(const char* file, int line)
@@ -101,7 +101,7 @@
     return l;
 }
 
-static void ssl_dyn_lock(int mode, CRYPTO_dynlock_value *l, const char *file,
+static void ssl_dyn_lock(int mode, CRYPTO_dynlock_value *l, const char *file, 
                          int line)
 {
     if (mode & CRYPTO_LOCK) {
@@ -131,7 +131,7 @@
 static unsigned long ssl_id(void)
 {
     /* FIXME: This is lame and not portable. -aaron */
-    return (unsigned long) apr_os_thread_current();
+    return (unsigned long) apr_os_thread_current(); 
 }
 #endif
 
@@ -213,7 +213,7 @@
 void ssl_read_socket_handshake(ssl_socket_t *s);
 
 ssl_socket_t* ssl_open_socket(apr_pool_t *pool, request_t *r,
-                              apr_status_t *status)
+                              apr_status_t *status) 
 {
     apr_os_sock_t ossock;
     int e, sslError;
@@ -222,7 +222,7 @@
 
     /* Open our TCP-based connection */
     ssl_socket->socket = open_socket(pool, r, status);
-
+    
     if (!ssl_socket->socket)
         return NULL;
 
@@ -260,7 +260,7 @@
             break;
         default:
             ERR_print_errors_fp(stderr);
-            return NULL;
+            return NULL; 
         }
     }
 
@@ -281,52 +281,45 @@
     int sslError;
     apr_int32_t socketsRead;
 
-    do
-    {
-
-      /* Wait until there is something to read. */
-      if (SSL_pending(s->ssl_connection) < *buflen) {
+    /* Wait until there is something to read. */
+    if (SSL_pending(s->ssl_connection) < *buflen) {
         e = apr_poll(&s->socket->read_pollset, 1, &socketsRead,
                      LOCAL_SOCKET_TIMEOUT);
 
         if (socketsRead != 1)
             return APR_TIMEUP;
-      }
+    }
 
-      e = SSL_read(s->ssl_connection, buf, *buflen);
-      sslError = SSL_get_error(s->ssl_connection, e);
-      if (sslError!=SSL_ERROR_WANT_READ) *buflen = 0;
+    e = SSL_read(s->ssl_connection, buf, *buflen);
+    sslError = SSL_get_error(s->ssl_connection, e);
 
-      switch (sslError)
-      {
-        case SSL_ERROR_NONE:
-          *buflen = e;
-          break;
-        case SSL_ERROR_WANT_READ:
-        case SSL_ERROR_WANT_WRITE:
-        case SSL_ERROR_WANT_X509_LOOKUP:
-//          ssl_read_socket(s, buf, buflen); // Now uses do-while loop to do 
this properly!
-          break;
-        case SSL_ERROR_ZERO_RETURN: /* Peer closed connection. */
-          return APR_EOF;
-        case SSL_ERROR_SYSCALL: /* Look at errno. */
-          if (errno == 0)
+    switch (sslError)
+    {
+    case SSL_ERROR_NONE:
+        *buflen = e;
+        break;
+    case SSL_ERROR_WANT_READ:
+        ssl_read_socket(s, buf, buflen);
+        break;
+    case SSL_ERROR_ZERO_RETURN: /* Peer closed connection. */
+        return APR_EOF; 
+    case SSL_ERROR_SYSCALL: /* Look at errno. */
+        if (errno == 0)
             return APR_EOF;
-          /* Continue through with the error case. */
-//    case SSL_ERROR_WANT_WRITE:  /* Technically, not an error. */ // (this is 
also in default) // Moved up now!
-        default:
-          ERR_print_errors_fp(stderr);
-          return APR_EGENERAL;
-      }
+        /* Continue through with the error case. */   
+    case SSL_ERROR_WANT_WRITE:  /* Technically, not an error. */
+    default:
+        ERR_print_errors_fp(stderr);
+        return APR_EGENERAL; 
     }
-    while (sslError != SSL_ERROR_NONE); // to get out of this loop, need no 
errors!
+
     return APR_SUCCESS;
 }
 
 void ssl_read_socket_handshake(ssl_socket_t *s)
 {
     char buf[1];
-    int buflen = 1;
+    int buflen = 1; 
     /* Wait until there is something to read. */
     apr_int32_t socketsRead;
     apr_status_t e;
@@ -341,28 +334,26 @@
     apr_status_t e;
     int sslError;
 
-    do
-    {
     /* Returns an error. */
-      e = SSL_write(s->ssl_connection, r->rbuf, r->rbufsize);
+    e = SSL_write(s->ssl_connection, r->rbuf, r->rbufsize);
 
-      sslError = SSL_get_error(s->ssl_connection, e);
-      switch (sslError)
-      {
-        case SSL_ERROR_NONE:
-        case SSL_ERROR_WANT_WRITE:
-          break;
-        case SSL_ERROR_WANT_READ:
-          ssl_read_socket_handshake(s);
-//          ssl_write_socket(s, r); // handled by while-do loop
-          break;
-        default:
-          ERR_print_errors_fp(stderr);
-          return APR_EGENERAL;
-      }
+    sslError = SSL_get_error(s->ssl_connection, e);
+    switch (sslError)
+    {
+    case SSL_ERROR_NONE:
+        break;
+    case SSL_ERROR_WANT_READ:
+        ssl_read_socket_handshake(s);
+        ssl_write_socket(s, r);
+        break;
+    case SSL_ERROR_WANT_WRITE:
+        break;
+    default:
+        ERR_print_errors_fp(stderr);
+        return APR_EGENERAL; 
     }
-    while (sslError == SSL_ERROR_WANT_READ); // to get out of this loop, need 
no errors! (WANT_WRITE not considered error)
-    return APR_SUCCESS;
+
+    return APR_SUCCESS;     
 }
 
 #else /* FLOOD_HAS_OPENSSL */

Reply via email to