serf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1708829 - /serf/trunk/buckets/ssl_buckets.c
Date Thu, 15 Oct 2015 14:46:08 GMT
Author: rhuijben
Date: Thu Oct 15 14:46:08 2015
New Revision: 1708829

URL: http://svn.apache.org/viewvc?rev=1708829&view=rev
Log:
Make the ssl buckets directly start the ssl handshake instead of waiting for
the first to be written data. This is needed to allow protocol negotiation
via ALPN to happen before the first write.

This change somehow changes the renegotiation test behavior for me. The
renegotiation now works ok, but we kill the connection and get in trouble
after that. I leave fixing that for a separate patch.

* buckets/ssl_buckets.c
  (serf_ssl_context_t): Add flag.
  (ssl_handshake): New function.
  (ssl_decrypt,
   ssl_encrypt): Call ssl_handshake if not done yet.
  (ssl_init_context): Initialize variable.

  (serf_ssl_set_config): Avoid an endless loop. Unrelated but required to
    keep the tests running without a stack overflow.

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=1708829&r1=1708828&r2=1708829&view=diff
==============================================================================
--- serf/trunk/buckets/ssl_buckets.c (original)
+++ serf/trunk/buckets/ssl_buckets.c Thu Oct 15 14:46:08 2015
@@ -140,6 +140,7 @@ struct serf_ssl_context_t {
 
     /* Should we read before we can write again? */
     int want_read;
+    int handshake_done;
 
     /* Client cert callbacks */
     serf_ssl_need_client_cert_t cert_callback;
@@ -899,6 +900,26 @@ static apr_status_t status_from_ssl_erro
     return status;
 }
 
+/* Explicitly perform the SSL handshake without waiting for the first
+   write */
+static apr_status_t ssl_handshake(serf_ssl_context_t *ctx,
+                                  int do_want_read)
+{
+    int ssl_result;
+
+    ssl_result = SSL_do_handshake(ctx->ssl);
+    if (ssl_result <= 0) {
+        apr_status_t status = status_from_ssl_error(ctx, ssl_result,
+                                                    do_want_read);
+
+        if (SERF_BUCKET_READ_ERROR(status)) {
+            return status;
+        }
+    }
+
+    return APR_SUCCESS;
+}
+
 /* 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,
@@ -911,6 +932,18 @@ static apr_status_t ssl_decrypt(void *ba
     if (ctx->fatal_err)
         return ctx->fatal_err;
 
+    if (!ctx->handshake_done) {
+
+        ctx->handshake_done = TRUE;
+
+        status = ssl_handshake(ctx, FALSE);
+
+        if (SERF_BUCKET_READ_ERROR(status)) {
+            *len = 0;
+            return status;
+        }
+    }
+
     serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
               "ssl_decrypt: begin %d\n", bufsize);
 
@@ -1006,6 +1039,17 @@ static apr_status_t ssl_encrypt(void *ba
     serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
               "ssl_encrypt: begin %d\n", bufsize);
 
+    if (!ctx->handshake_done) {
+
+        ctx->handshake_done = TRUE;
+
+        status = ssl_handshake(ctx, TRUE);
+
+        if (SERF_BUCKET_READ_ERROR(status)) {
+            return status;
+        }
+    }
+
     /* Try to read already encrypted but unread data first. */
     status = serf_bucket_read(ctx->encrypt_pending, bufsize, &data, len);
     if (SERF_BUCKET_READ_ERROR(status)) {
@@ -1542,6 +1586,7 @@ static serf_ssl_context_t *ssl_init_cont
 
     ssl_ctx->crypt_status = APR_SUCCESS;
     ssl_ctx->want_read = FALSE;
+    ssl_ctx->handshake_done = FALSE;
 
     return ssl_ctx;
 }
@@ -2242,6 +2287,9 @@ static apr_status_t serf_ssl_set_config(
     const char *pipelining;
     apr_status_t status;
 
+    if (ssl_ctx->config == config)
+        return APR_SUCCESS; /* Don't loop */
+
     ssl_ctx->config = config;
 
     /* Distribute the shared config as much as possible. */



Mime
View raw message