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;
}