See below for explanation of change; attached diff now correct.

-Norman Tuttle, OpenDemand Systems Developer [EMAIL PROTECTED]

On Mon, 13 Oct 2003, Norman Tuttle wrote:

> To Apache Flood development team:
> 
> 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.


--- \flood-1.1\flood_net_ssl.c  2003-10-08 19:25:02.000000000 -0400
+++ flood_net_ssl.c     2003-11-04 12:06:16.000000000 -0500
@@ -281,37 +281,41 @@
     int sslError;
     apr_int32_t socketsRead;
 
-    /* Wait until there is something to read. */
-    if (SSL_pending(s->ssl_connection) < *buflen) {
+    do
+    {
+
+      /* 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);
+      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:
-        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)
+      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:
+          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. */
-    default:
-        ERR_print_errors_fp(stderr);
-        return APR_EGENERAL; 
-    }
+          /* else Continue through with the error case. */
+        default:
+          ERR_print_errors_fp(stderr);
+          return APR_EGENERAL;
+      }
+    } while (sslError != SSL_ERROR_NONE); /* to exit loop: need no error */
 
     return APR_SUCCESS;
 }
@@ -334,24 +338,27 @@
     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:
-        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; 
-    }
+      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);
+          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;     
 }

Reply via email to