]> granicus.if.org Git - apache/commitdiff
errno? EINTR? what planet was this code on :-? Normalize the
authorWilliam A. Rowe Jr <wrowe@apache.org>
Wed, 6 Nov 2002 07:21:47 +0000 (07:21 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Wed, 6 Nov 2002 07:21:47 +0000 (07:21 +0000)
  ssl_io_filter_connect code to follow the filter read and write.
  Notice that it's buck ugly, but we will extract an rc first from
  the input BIO if it was written, and then try the output bio if
  it was APR_SUCCESS, during _connect processing.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97422 13f79535-47bb-0310-9956-ffa450edef68

modules/ssl/ssl_engine_io.c

index 5776135f74ac5ce807740023f789fe7ae05adc64..c2f0ce824d87eb13cbd17c27022a8cd5e02f5c61 100644 (file)
@@ -640,13 +640,11 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
              */
             if (APR_STATUS_IS_EAGAIN(inctx->rc)
                     || APR_STATUS_IS_EINTR(inctx->rc)) {
-                if (inctx->block == APR_NONBLOCK_READ) {
-                    /* Already read something, return APR_SUCCESS instead. */
-                    if (*len > 0) {
-                        inctx->rc = APR_SUCCESS;
-                    }
-                    break;
+                /* Already read something, return APR_SUCCESS instead. */
+                if (*len > 0) {
+                    inctx->rc = APR_SUCCESS;
                 }
+                break;
             }
             else {
                 if (*len > 0) {
@@ -683,8 +681,18 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
                 continue; /* try again */
             }
             else if (ssl_err == SSL_ERROR_SYSCALL) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, inctx->rc, c->base_server,
-                            "SSL filter in error reading data");
+                if (APR_STATUS_IS_EAGAIN(inctx->rc)
+                        || APR_STATUS_IS_EINTR(inctx->rc)) {
+                    /* Already read something, return APR_SUCCESS instead. */
+                    if (*len > 0) {
+                        inctx->rc = APR_SUCCESS;
+                    }
+                    break;
+                }
+                else {
+                    ap_log_error(APLOG_MARK, APLOG_ERR, inctx->rc, c->base_server,
+                                "SSL input filter read failed.");
+                }
             }
             else /* if (ssl_err == SSL_ERROR_SSL) */ {
                 /*
@@ -773,6 +781,7 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
 
     if (res < 0) {
         int ssl_err = SSL_get_error(filter_ctx->pssl, res);
+        conn_rec *c = (conn_rec*)SSL_get_app_data(outctx->filter_ctx->pssl);
 
         if (ssl_err == SSL_ERROR_WANT_WRITE) {
             /*
@@ -786,19 +795,16 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
             outctx->rc = APR_EAGAIN;
         }
         else if (ssl_err == SSL_ERROR_SYSCALL) {
-            conn_rec *c = (conn_rec*)SSL_get_app_data(outctx->filter_ctx->pssl);
             ap_log_error(APLOG_MARK, APLOG_ERR, outctx->rc, c->base_server,
-                        "SSL filter out error writing data");
+                        "SSL output filter write failed.");
         }
         else /* if (ssl_err == SSL_ERROR_SSL) */ {
             /*
              * Log SSL errors
              */
-            conn_rec *c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl);
             ap_log_error(APLOG_MARK, APLOG_ERR, outctx->rc, c->base_server,
-                    "SSL library out error writing data");
+                         "SSL library error %d writing data", ssl_err);
             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
-
         }
         if (outctx->rc == APR_SUCCESS) {
             outctx->rc = APR_EGENERAL;
@@ -1014,7 +1020,8 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
     SSLConnRec *sslconn = myConnConfig(c);
     SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
     X509 *cert;
-    int n, err;
+    int n;
+    int ssl_err;
     long verify_result;
 
     if (SSL_is_init_finished(filter_ctx->pssl)) {
@@ -1034,24 +1041,30 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
     }
 
     if ((n = SSL_accept(filter_ctx->pssl)) <= 0) {
-        err = SSL_get_error(filter_ctx->pssl, n);
-
-        if (err == SSL_ERROR_ZERO_RETURN) {
+        bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)
+                                     (filter_ctx->pbioRead->ptr);
+        bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)
+                                       (filter_ctx->pbioWrite->ptr);
+        apr_status_t rc = inctx->rc ? inctx->rc : outctx->rc ;
+        ssl_err = SSL_get_error(filter_ctx->pssl, n);
+        
+        if (ssl_err == SSL_ERROR_ZERO_RETURN) {
             /*
              * The case where the connection was closed before any data
              * was transferred. That's not a real error and can occur
              * sporadically with some clients.
              */
-            ap_log_error(APLOG_MARK, APLOG_INFO, 0,
+            ap_log_error(APLOG_MARK, APLOG_INFO, rc,
                          c->base_server,
                          "SSL handshake stopped: connection was closed");
         }
-        else if (err == SSL_ERROR_WANT_READ) {
+        else if (ssl_err == SSL_ERROR_WANT_READ) {
             /*
              * This is in addition to what was present earlier. It is 
              * borrowed from openssl_state_machine.c [mod_tls].
              * TBD.
              */
+            outctx->rc = APR_EAGAIN;
             return SSL_ERROR_WANT_READ;
         }
         else if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
@@ -1063,35 +1076,25 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
              */
             return HTTP_BAD_REQUEST;
         }
-        else if ((SSL_get_error(filter_ctx->pssl, n) == SSL_ERROR_SYSCALL) &&
-                 (errno != EINTR))
-        {
-            if (errno > 0) {
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0,
-                             c->base_server,
-                             "SSL handshake interrupted by system "
-                             "[Hint: Stop button pressed in browser?!]");
-                ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
-            }
-            else {
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, 
-                             c->base_server,
-                             "Spurious SSL handshake interrupt [Hint: "
-                             "Usually just one of those OpenSSL "
-                             "confusions!?]");
-                ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
-            }
+        else if (ssl_err == SSL_ERROR_SYSCALL) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, rc, c->base_server,
+                         "SSL handshake interrupted by system "
+                         "[Hint: Stop button pressed in browser?!]");
         }
-        else {
+        else /* if (ssl_err == SSL_ERROR_SSL) */ {
             /*
-             * Ok, anything else is a fatal error
+             * Log SSL errors and any unexpected conditions.
              */
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, 
-                         c->base_server,
-                         "SSL handshake failed (server %s, client %s)",
+            ap_log_error(APLOG_MARK, APLOG_ERR, rc, c->base_server,
+                         "SSL library error %d in handshake "
+                         "(server %s, client %s)", ssl_err,
                          ssl_util_vhostid(c->pool, c->base_server),
                          c->remote_ip ? c->remote_ip : "unknown");
             ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
+
+        }
+        if (inctx->rc == APR_SUCCESS) {
+            inctx->rc = APR_EGENERAL;
         }
 
         return ssl_filter_io_shutdown(filter_ctx, c, 1);
@@ -1204,9 +1207,7 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
      * AP_MODE_INIT for protocols that may upgrade the connection
      * rather than have SSLEngine On configured.
      */
-    status = ssl_io_filter_connect(inctx->filter_ctx);
-
-    if (status != APR_SUCCESS) {
+    if ((status = ssl_io_filter_connect(inctx->filter_ctx)) != APR_SUCCESS) {
         return ssl_io_filter_error(f, bb, status);
     }
 
@@ -1265,7 +1266,7 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f,
     }
 
     if ((status = ssl_io_filter_connect(filter_ctx)) != APR_SUCCESS) {
-        return status;
+        return ssl_io_filter_error(f, bb, status);
     }
 
     while (!APR_BRIGADE_EMPTY(bb)) {