Browse Source

Add testing/docs for blocking write

- Fix case where message grouping can make CheckAvailableSize return a WANT_WRITE
- CheckAvailableSize in tls13.c will not return a WANT_WRITE since it only does so for DTLS <=1.2
Juliusz Sosinowicz 1 year ago
parent
commit
50c0b3d2a2

+ 3 - 1
examples/client/client.c

@@ -1055,7 +1055,8 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
             }
             else
         #endif
-            if (err != WOLFSSL_ERROR_WANT_READ && err != APP_DATA_READY) {
+            if (err != WOLFSSL_ERROR_WANT_READ &&
+                    err != WOLFSSL_ERROR_WANT_WRITE && err != APP_DATA_READY) {
                 fprintf(stderr, "SSL_read reply error %d, %s\n", err,
                                          wolfSSL_ERR_error_string(err, buffer));
                 if (!exitWithRet) {
@@ -1076,6 +1077,7 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
             }
         }
     } while ((mustRead && err == WOLFSSL_ERROR_WANT_READ)
+        || err == WOLFSSL_ERROR_WANT_WRITE
     #ifdef WOLFSSL_ASYNC_CRYPT
         || err == WC_PENDING_E
     #endif

+ 2 - 0
examples/server/server.c

@@ -533,6 +533,8 @@ static void ServerRead(WOLFSSL* ssl, char* input, int inputLen)
             else
         #endif
             if (err != WOLFSSL_ERROR_WANT_READ
+                    && err != WOLFSSL_ERROR_WANT_WRITE /* Can happen during
+                                                        * handshake */
         #ifdef HAVE_SECURE_RENEGOTIATION
                     && err != APP_DATA_READY
         #endif

+ 95 - 26
src/internal.c

@@ -8864,7 +8864,7 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
         WOLFSSL_MSG("Can't use output buffer for input in SendHandshakeMsg");
         return BAD_FUNC_ARG;
     }
-    if (ssl->fragOffset == 0) {
+    if (!ssl->options.buildingMsg) {
         /* Hash it before the loop as we modify the input with
          * encryption on */
         ret = HashOutput(ssl, input, headerSz + (int)inputSz, 0);
@@ -8882,6 +8882,9 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
         int outputSz;
         byte* data = input + ssl->fragOffset + headerSz;
         word32 fragSz = (word32)maxFrag;
+
+        ssl->options.buildingMsg = 1;
+
         if (inputSz - ssl->fragOffset < fragSz)
             fragSz = inputSz - ssl->fragOffset;
 
@@ -8967,6 +8970,7 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
         ssl->keys.dtls_handshake_number++;
 #endif
     ssl->fragOffset = 0;
+    ssl->options.buildingMsg = 0;
     return ret;
 }
 #endif /* !NO_WOLFSSL_SERVER || (!NO_WOLFSSL_CLIENT && !NO_CERTS &&
@@ -18188,6 +18192,10 @@ int SendChangeCipher(WOLFSSL* ssl)
         sendSz += MAX_MSG_EXTRA;
     }
 
+    /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+     * is not advanced yet */
+    ssl->options.buildingMsg = 1;
+
     /* check for available size */
     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
         return ret;
@@ -18247,6 +18255,8 @@ int SendChangeCipher(WOLFSSL* ssl)
     #endif
     }
 
+    ssl->options.buildingMsg = 0;
+
     if (ssl->options.groupMessages)
         return 0;
     #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_DEBUG_DTLS)
@@ -19043,6 +19053,11 @@ int SendFinished(WOLFSSL* ssl)
 
     /* check for available size */
     outputSz = sizeof(input) + MAX_MSG_EXTRA;
+
+    /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+     * is not advanced yet */
+    ssl->options.buildingMsg = 1;
+
     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
         return ret;
 
@@ -19145,6 +19160,8 @@ int SendFinished(WOLFSSL* ssl)
 
     ret = SendBuffered(ssl);
 
+    ssl->options.buildingMsg = 0;
+
 #ifdef WOLFSSL_DTLS
     if ((!ssl->options.resuming &&
             ssl->options.side == WOLFSSL_SERVER_END) ||
@@ -19394,6 +19411,8 @@ int SendCertificate(WOLFSSL* ssl)
         word32 i = RECORD_HEADER_SZ;
         int    sendSz = RECORD_HEADER_SZ;
 
+        ssl->options.buildingMsg = 1;
+
         if (!ssl->options.dtls) {
             if (ssl->fragOffset == 0)  {
                 if (headerSz + certSz + certChainSz <=
@@ -19434,6 +19453,9 @@ int SendCertificate(WOLFSSL* ssl)
         output = ssl->buffers.outputBuffer.buffer +
                  ssl->buffers.outputBuffer.length;
 
+        /* Safe to use ssl->fragOffset since it will be incremented immediately
+         * after this block. This block needs to be entered only once to not
+         * hash the cert msg twice. */
         if (ssl->fragOffset == 0) {
             if (!ssl->options.dtls) {
                 AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
@@ -19583,6 +19605,7 @@ int SendCertificate(WOLFSSL* ssl)
 
     if (ret != WANT_WRITE) {
         /* Clean up the fragment offset. */
+        ssl->options.buildingMsg = 0;
         ssl->fragOffset = 0;
         #ifdef WOLFSSL_DTLS
             if (ssl->options.dtls)
@@ -19657,6 +19680,10 @@ int SendCertificateRequest(WOLFSSL* ssl)
     if (IsEncryptionOn(ssl, 1))
         sendSz += cipherExtraData(ssl);
 
+    /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+     * is not advanced yet */
+    ssl->options.buildingMsg = 1;
+
     /* check for available size */
     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
         return ret;
@@ -19772,6 +19799,8 @@ int SendCertificateRequest(WOLFSSL* ssl)
     else
         ret = SendBuffered(ssl);
 
+    ssl->options.buildingMsg = 0;
+
     WOLFSSL_LEAVE("SendCertificateRequest", ret);
     WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_SEND);
 
@@ -19812,6 +19841,10 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
     if (ssl->keys.encryptionOn)
         sendSz += MAX_MSG_EXTRA;
 
+    /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+     * is not advanced yet */
+    ssl->options.buildingMsg = 1;
+
     if ((ret = CheckAvailableSize(ssl, sendSz)) == 0) {
         output = ssl->buffers.outputBuffer.buffer +
                  ssl->buffers.outputBuffer.length;
@@ -19876,6 +19909,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
     #endif
 
         if (ret == 0) {
+            ssl->options.buildingMsg = 0;
             ssl->buffers.outputBuffer.length += sendSz;
             if (!ssl->options.groupMessages)
                 ret = SendBuffered(ssl);
@@ -20574,8 +20608,16 @@ int SendAlert(WOLFSSL* ssl, int severity, int type)
 
     /* check for available size */
     outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
-    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
-        return ret;
+    if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) {
+        /* If CheckAvailableSize returned WANT_WRITE due to a blocking write
+         * then discard pending output and just send the alert. */
+        if (ret != WANT_WRITE || severity != alert_fatal)
+            return ret;
+        ShrinkOutputBuffer(ssl);
+        if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) {
+            return ret;
+        }
+    }
 
     /* Check output buffer */
     if (ssl->buffers.outputBuffer.buffer == NULL)
@@ -23310,6 +23352,10 @@ exit_dpk:
         if (IsEncryptionOn(ssl, 1))
             sendSz += MAX_MSG_EXTRA;
 
+        /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+         * is not advanced yet */
+        ssl->options.buildingMsg = 1;
+
         /* check for available size */
         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
             return ret;
@@ -23470,6 +23516,8 @@ exit_dpk:
                           WRITE_PROTO, ssl->heap);
 #endif
 
+        ssl->options.buildingMsg = 0;
+
         ssl->buffers.outputBuffer.length += sendSz;
 
         ret = SendBuffered(ssl);
@@ -25631,7 +25679,7 @@ static void FreeSckeArgs(WOLFSSL* ssl, void* pArgs)
 int SendClientKeyExchange(WOLFSSL* ssl)
 {
     int ret = 0;
-#ifdef WOLFSSL_ASYNC_CRYPT
+#ifdef WOLFSSL_ASYNC_IO
     SckeArgs* args = NULL;
     WOLFSSL_ASSERT_SIZEOF_GE(ssl->async->args, *args);
 #else
@@ -25648,7 +25696,7 @@ int SendClientKeyExchange(WOLFSSL* ssl)
         ssl->CBIS(ssl, SSL_CB_CONNECT_LOOP, SSL_SUCCESS);
 #endif
 
-#ifdef WOLFSSL_ASYNC_CRYPT
+#ifdef WOLFSSL_ASYNC_IO
     if (ssl->async == NULL) {
         ssl->async = (struct WOLFSSL_ASYNC*)
                 XMALLOC(sizeof(struct WOLFSSL_ASYNC), ssl->heap,
@@ -25658,6 +25706,7 @@ int SendClientKeyExchange(WOLFSSL* ssl)
     }
     args = (SckeArgs*)ssl->async->args;
 
+#ifdef WOLFSSL_ASYNC_CRYPT
     ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
     if (ret != WC_NOT_PENDING_E) {
         /* Check for error */
@@ -25665,13 +25714,21 @@ int SendClientKeyExchange(WOLFSSL* ssl)
             goto exit_scke;
     }
     else
+#endif
+    if (ssl->options.buildingMsg) {
+        /* Continue building the message */
+    }
+    else
 #endif
     {
         /* Reset state */
         ret = 0;
         ssl->options.asyncState = TLS_ASYNC_BEGIN;
         XMEMSET(args, 0, sizeof(SckeArgs));
-    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+         * is not advanced yet */
+        ssl->options.buildingMsg = 1;
+    #ifdef WOLFSSL_ASYNC_IO
         ssl->async->freeArgs = FreeSckeArgs;
     #endif
     }
@@ -26680,9 +26737,8 @@ int SendClientKeyExchange(WOLFSSL* ssl)
             }
 
             /* check for available size */
-            if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
+            if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0)
                 goto exit_scke;
-            }
 
             /* get output buffer */
             args->output = ssl->buffers.outputBuffer.buffer +
@@ -26773,6 +26829,7 @@ int SendClientKeyExchange(WOLFSSL* ssl)
                     ret = tmpRet;   /* save WANT_WRITE unless more serious */
                 }
                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
+                ssl->options.buildingMsg = 0;
             }
         #if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
             if (ssl->keyLogCb != NULL) {
@@ -26794,10 +26851,14 @@ exit_scke:
     WOLFSSL_LEAVE("SendClientKeyExchange", ret);
     WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
 
-#ifdef WOLFSSL_ASYNC_CRYPT
+#ifdef WOLFSSL_ASYNC_IO
     /* Handle async operation */
-    if (ret == WC_PENDING_E)
-        return ret;
+    if (ret == WC_PENDING_E || ret == WANT_WRITE) {
+        if (ssl->options.buildingMsg)
+            return ret;
+        /* If we have completed all states then we will not enter this function
+         * again. We need to do clean up now. */
+    }
 #endif
 
     /* No further need for PMS */
@@ -26807,7 +26868,7 @@ exit_scke:
     ssl->arrays->preMasterSz = 0;
 
     /* Final cleanup */
-#ifdef WOLFSSL_ASYNC_CRYPT
+#ifdef WOLFSSL_ASYNC_IO
     /* Cleanup async */
     FreeAsyncCtx(ssl, 0);
 #else
@@ -26894,7 +26955,7 @@ int SendCertificateVerify(WOLFSSL* ssl)
     }
     else
 #endif
-    if (ssl->fragOffset != 0) {
+    if (ssl->options.buildingMsg) {
         /* We should be in the sending state. */
         if (ssl->options.asyncState != TLS_ASYNC_END) {
             ret = BAD_STATE_E;
@@ -27225,12 +27286,6 @@ int SendCertificateVerify(WOLFSSL* ssl)
             if (args->output == NULL) {
                 ERROR_OUT(BUFFER_ERROR, exit_scv);
             }
-        #ifdef WOLFSSL_DTLS
-            /* We have re-entered this funtion after a WANT_WRITE. Make sure
-             * the handshake number stays the same. */
-            if (ssl->options.dtls && ssl->fragOffset != 0)
-                ssl->keys.dtls_handshake_number--;
-        #endif
             AddHeaders(args->output, (word32)args->length + args->extraSz +
                                         VERIFY_HEADER, certificate_verify, ssl);
 
@@ -27615,6 +27670,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
         if (IsEncryptionOn(ssl, 1))
             sendSz += MAX_MSG_EXTRA;
 
+        /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+         * is not advanced yet */
+        ssl->options.buildingMsg = 1;
+
         /* check for available size */
         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
             return ret;
@@ -27769,6 +27828,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
     #endif
 
         ssl->options.serverState = SERVER_HELLO_COMPLETE;
+        ssl->options.buildingMsg = 0;
         ssl->buffers.outputBuffer.length += sendSz;
 
         if (ssl->options.groupMessages)
@@ -27885,7 +27945,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
         }
         else
     #endif
-        if (ssl->fragOffset != 0) {
+        if (ssl->options.buildingMsg) {
             /* We should be in the sending state. */
             if (ssl->options.asyncState != TLS_ASYNC_END) {
                 ret = BAD_STATE_E;
@@ -29344,12 +29404,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
 
             case TLS_ASYNC_FINALIZE:
             {
-            #ifdef WOLFSSL_DTLS
-                /* We have re-entered this funtion after a WANT_WRITE. Make sure
-                 * the handshake number stays the same. */
-                if (ssl->options.dtls && ssl->fragOffset != 0)
-                    ssl->keys.dtls_handshake_number--;
-            #endif
             #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
                                                           defined(HAVE_CURVE448)
                 if (ssl->specs.kea == ecdhe_psk_kea ||
@@ -31060,6 +31114,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
         if (IsEncryptionOn(ssl, 1))
             sendSz += MAX_MSG_EXTRA;
 
+        /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+         * is not advanced yet */
+        ssl->options.buildingMsg = 1;
+
         /* check for available size */
         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
             return ret;
@@ -31120,6 +31178,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
                     WRITE_PROTO, ssl->heap);
     #endif
         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
+        ssl->options.buildingMsg = 0;
 
         ssl->buffers.outputBuffer.length += sendSz;
 
@@ -31544,6 +31603,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
         if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
             sendSz += cipherExtraData(ssl);
 
+        /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+         * is not advanced yet */
+        ssl->options.buildingMsg = 1;
+
         /* check for available size */
         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
             return ret;
@@ -31601,6 +31664,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
         }
 
         ssl->buffers.outputBuffer.length += sendSz;
+        ssl->options.buildingMsg = 0;
 
         if (!ssl->options.groupMessages)
             ret = SendBuffered(ssl);
@@ -32065,6 +32129,10 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
         if (ssl->options.dtls)
             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
 
+        /* Set this in case CheckAvailableSize returns a WANT_WRITE so that state
+         * is not advanced yet */
+        ssl->options.buildingMsg = 1;
+
         /* check for available size */
         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
             return ret;
@@ -32106,6 +32174,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
         }
 
         ssl->buffers.outputBuffer.length += sendSz;
+        ssl->options.buildingMsg = 0;
 
         ret = SendBuffered(ssl);
 

+ 2 - 2
src/ssl.c

@@ -11850,7 +11850,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
                 /* fragOffset is non-zero when sending fragments. On the last
                  * fragment, fragOffset is zero again, and the state can be
                  * advanced. */
-                if (ssl->fragOffset == 0) {
+                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
                     if (ssl->options.connectState == CONNECT_BEGIN ||
                         ssl->options.connectState == HELLO_AGAIN ||
                        (ssl->options.connectState >= FIRST_REPLY_DONE &&
@@ -12330,7 +12330,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
                 /* fragOffset is non-zero when sending fragments. On the last
                  * fragment, fragOffset is zero again, and the state can be
                  * advanced. */
-                if (ssl->fragOffset == 0) {
+                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
                     if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
                         ssl->options.acceptState == SERVER_HELLO_SENT ||
                         ssl->options.acceptState == CERT_SENT ||

+ 5 - 2
src/tls13.c

@@ -5932,6 +5932,8 @@ static int SendTls13Certificate(WOLFSSL* ssl)
         word32 i = RECORD_HEADER_SZ;
         int    sendSz = RECORD_HEADER_SZ;
 
+        ssl->options.buildingMsg = 1;
+
         if (ssl->fragOffset == 0) {
             if (headerSz + certSz + extSz + certChainSz <=
                                             maxFragment - HANDSHAKE_HEADER_SZ) {
@@ -6053,6 +6055,7 @@ static int SendTls13Certificate(WOLFSSL* ssl)
 
     if (ret != WANT_WRITE) {
         /* Clean up the fragment offset. */
+        ssl->options.buildingMsg = 0;
         ssl->fragOffset = 0;
         if (ssl->options.side == WOLFSSL_SERVER_END)
             ssl->options.serverState = SERVER_CERT_COMPLETE;
@@ -8720,7 +8723,7 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
             /* fragOffset is non-zero when sending fragments. On the last
              * fragment, fragOffset is zero again, and the state can be
              * advanced. */
-            if (ssl->fragOffset == 0) {
+            if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
                 /* Only increment from states in which we send data */
                 if (ssl->options.connectState == CONNECT_BEGIN ||
                     ssl->options.connectState == HELLO_AGAIN ||
@@ -9688,7 +9691,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
             /* fragOffset is non-zero when sending fragments. On the last
              * fragment, fragOffset is zero again, and the state can be
              * advanced. */
-            if (ssl->fragOffset == 0) {
+            if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
                 /* Only increment from states in which we send data */
                 if (ssl->options.acceptState == TLS13_ACCEPT_CLIENT_HELLO_DONE ||
                     ssl->options.acceptState == TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE ||

+ 14 - 0
tests/test-dtls-mtu.conf

@@ -3521,3 +3521,17 @@
 -f
 -v 3
 -l AES256-SHA256
+
+# server DTLSv1.2 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 with write blocking
+-u 512
+-6
+-f
+-v 3
+-l TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+
+# client DTLSv1.2 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 with write blocking
+-u 512
+-6
+-f
+-v 3
+-l TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256

+ 16 - 0
tests/test-dtls-reneg-server.conf

@@ -1061,3 +1061,19 @@
 -a
 -v 2
 -l ADH-AES128-SHA
+
+# server DTLSv1.2 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 with non-blocking write
+-m
+-u 512
+-v 3
+-6
+-l TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+-f
+
+# client DTLSv1.2 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 with non-blocking write
+-R
+-u 512
+-v 3
+-6
+-l TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+-f

+ 11 - 0
tests/test-maxfrag.conf

@@ -177,3 +177,14 @@
 -v 3
 -l DHE-RSA-AES256-GCM-SHA384
 -F 6
+
+# server TLSv1.2 DHE-RSA-AES256-GCM-SHA384
+-v 3
+-l DHE-RSA-AES256-GCM-SHA384
+-6
+
+# client TLSv1.2 DHE-RSA-AES256-GCM-SHA384
+-v 3
+-l DHE-RSA-AES256-GCM-SHA384
+-F 1
+-6

+ 10 - 0
tests/test.conf

@@ -2070,3 +2070,13 @@
 -v 3
 -l ECDHE-RSA-AES128-SHA256
 
+# server test with a blocking write socket
+-v 3
+-6
+-l TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+
+# client test with a blocking write socket
+-v 3
+-6
+-l TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+

+ 2 - 1
wolfssl/internal.h

@@ -3505,7 +3505,6 @@ enum AcceptState {
     ACCEPT_HELLO_RETRY_REQUEST_DONE,
     ACCEPT_FIRST_REPLY_DONE,
     SERVER_HELLO_SENT,
-    SERVER_EXTENSIONS_SENT,
     CERT_SENT,
     CERT_VERIFY_SENT,
     CERT_STATUS_SENT,
@@ -3773,6 +3772,8 @@ typedef struct Options {
     word16            buildArgsSet:1;         /* buildArgs are set and need to
                                                * be free'd */
 #endif
+    word16            buildingMsg:1;      /* If set then we need to re-enter the
+                                           * handshake logic. */
 
     /* need full byte values for this section */
     byte            processReply;           /* nonblocking resume */