serf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1708800 - /serf/trunk/buckets/ssl_buckets.c
Date Thu, 15 Oct 2015 11:39:09 GMT
Author: rhuijben
Date: Thu Oct 15 11:39:09 2015
New Revision: 1708800

URL: http://svn.apache.org/viewvc?rev=1708800&view=rev
Log:
Extract a bit of code from ssl_decrypt and ssl_encrypt to a separate
function, in preparation for adding another usage.

* serf-dev/dev/buckets/ssl_buckets.c
  (status_from_ssl_error): New function...
  (ssl_decrypt,
   ssl_encrypt): ... extracted from here.

Modified:
    serf/trunk/buckets/ssl_buckets.c

Modified: serf/trunk/buckets/ssl_buckets.c
URL: http://svn.apache.org/viewvc/serf/trunk/buckets/ssl_buckets.c?rev=1708800&r1=1708799&r2=1708800&view=diff
==============================================================================
--- serf/trunk/buckets/ssl_buckets.c (original)
+++ serf/trunk/buckets/ssl_buckets.c Thu Oct 15 11:39:09 2015
@@ -842,35 +842,23 @@ validate_server_certificate(int cert_val
     return cert_valid;
 }
 
-/* This function reads an encrypted stream and returns the decrypted stream.
-   Implements serf_databuf_reader_t */
-static apr_status_t ssl_decrypt(void *baton, apr_size_t bufsize,
-                                char *buf, apr_size_t *len)
+/* Helper function to convert the ssl error code contained in ret_code + the
+   ssl context to a proper serf status code.
+
+   If DO_WANT_READ is true, handle the SSL_ERROR_WANT_* as SERF_ERROR_WAIT_CONN
+   and set ctx->want_read.
+ */
+static apr_status_t status_from_ssl_error(serf_ssl_context_t *ctx,
+                                          int ret_code,
+                                          int do_want_read)
 {
-    serf_ssl_context_t *ctx = baton;
+    int ssl_err = SSL_get_error(ctx->ssl, ret_code);
     apr_status_t status;
-    int ssl_len;
 
-    if (ctx->fatal_err)
-        return ctx->fatal_err;
-
-    serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
-              "ssl_decrypt: begin %d\n", bufsize);
-
-    ctx->want_read = FALSE; /* Reading now */
-    ctx->crypt_status = APR_SUCCESS; /* Clear before calling SSL */
-
-    /* Is there some data waiting to be read? */
-    ssl_len = SSL_read(ctx->ssl, buf, bufsize);
-    if (ssl_len < 0) {
-        int ssl_err;
-
-        ssl_err = SSL_get_error(ctx->ssl, ssl_len);
-        switch (ssl_err) {
+    switch (ssl_err) {
         case SSL_ERROR_SYSCALL:
-            /* bio_bucket_read() or bio_bucket_write() returned -1. */
-            *len = 0;
-            /* Return the underlying status that caused OpenSSL to fail.
+            /* One of the bio functions returned a failure by returning -1.
+               Return the underlying status that caused OpenSSL to fail.
 
                There is no ssl status to log here, as the only reason
                the call failed is that our data delivery function didn't
@@ -878,13 +866,17 @@ static apr_status_t ssl_decrypt(void *ba
                callback if you turn up the logging level high enough. */
             status = ctx->crypt_status;
             break;
+
         case SSL_ERROR_WANT_READ:
+            if (do_want_read)
+                ctx->want_read = TRUE;
+            /* Fall through */
+
         case SSL_ERROR_WANT_WRITE:
-            *len = 0;
-            status = APR_EAGAIN;
+            status = do_want_read ? SERF_ERROR_WAIT_CONN : APR_EAGAIN;
             break;
+
         case SSL_ERROR_SSL:
-            *len = 0;
             if (ctx->pending_err) {
                 status = ctx->pending_err;
                 ctx->pending_err = APR_SUCCESS;
@@ -893,16 +885,45 @@ static apr_status_t ssl_decrypt(void *ba
                     ctx->fatal_err = SERF_ERROR_SSL_SETUP_FAILED;
                 else
                     ctx->fatal_err = SERF_ERROR_SSL_COMM_FAILED;
+
                 status = ctx->fatal_err;
                 log_ssl_error(ctx);
             }
             break;
         default:
-            *len = 0;
-            ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
+            status = ctx->fatal_err = SERF_ERROR_SSL_COMM_FAILED;
             log_ssl_error(ctx);
             break;
-        }
+    }
+
+    return status;
+}
+
+/* This function reads an encrypted stream and returns the decrypted stream.
+   Implements serf_databuf_reader_t */
+static apr_status_t ssl_decrypt(void *baton, apr_size_t bufsize,
+                                char *buf, apr_size_t *len)
+{
+    serf_ssl_context_t *ctx = baton;
+    apr_status_t status;
+    int ssl_len;
+
+    if (ctx->fatal_err)
+        return ctx->fatal_err;
+
+    serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
+              "ssl_decrypt: begin %d\n", bufsize);
+
+    ctx->want_read = FALSE; /* Reading now */
+    ctx->crypt_status = APR_SUCCESS; /* Clear before calling SSL */
+
+    /* Is there some data waiting to be read? */
+    ssl_len = SSL_read(ctx->ssl, buf, bufsize);
+    if (ssl_len < 0) {
+        int ssl_err;
+
+        *len = 0;
+        status = status_from_ssl_error(ctx, ssl_len, FALSE);
     } else if (ssl_len == 0) {
         /* The server shut down the connection. */
         int ssl_err, shutdown;
@@ -1053,8 +1074,7 @@ static apr_status_t ssl_encrypt(void *ba
                           "ssl_encrypt: SSL write: %d\n", ssl_len);
 
                 /* If we failed to write... */
-                if (ssl_len < 0) {
-                    int ssl_err;
+                if (ssl_len <= 0) {
 
                     /* Ah, bugger. We need to put that data back.
                        Note: use the copy here, we do not own the original iovec
@@ -1066,43 +1086,7 @@ static apr_status_t ssl_encrypt(void *ba
                     serf_bucket_aggregate_prepend(ctx->encrypt.stream,
                                                   vecs_copy);
 
-                    ssl_err = SSL_get_error(ctx->ssl, ssl_len);
-
-                    switch (ssl_err) {
-                    case SSL_ERROR_SYSCALL:
-                        /* bio_bucket_read() or bio_bucket_write() returned
-                           a failure by returning -1. */
-                        status = ctx->crypt_status;
-                        if (SERF_BUCKET_READ_ERROR(status)) {
-                            return status;
-                        }
-                        break;
-
-                    case SSL_ERROR_WANT_READ:
-                        ctx->want_read = TRUE;
-                        /* Fall through */
-                    case SSL_ERROR_WANT_WRITE:
-                        status = SERF_ERROR_WAIT_CONN;
-                        break;
-                    case SSL_ERROR_SSL:
-                        if (ctx->pending_err) {
-                            status = ctx->pending_err;
-                            ctx->pending_err = APR_SUCCESS;
-                        }
-                        else {
-                            if (SSL_in_init(ctx->ssl))
-                                ctx->fatal_err = SERF_ERROR_SSL_SETUP_FAILED;
-                            else
-                                ctx->fatal_err = SERF_ERROR_SSL_COMM_FAILED;
-                            status = ctx->fatal_err;
-                            log_ssl_error(ctx);
-                        }
-                        break;
-                    default:
-                        ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
-                        log_ssl_error(ctx);
-                        break;
-                    }
+                    status = status_from_ssl_error(ctx, ssl_len, TRUE);
                 } else {
                     /* We're done with this data. */
                     serf_bucket_mem_free(ctx->allocator, vecs_data);



Mime
View raw message