From e035eb8f8ace8c6bbb7b8ee4d84a4a37794d87f4 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Mon, 2 Nov 2020 08:23:36 -0600 Subject: [PATCH 1/3] Add an option to the example client to simulate WANT_WRITE errors. - Add this option as "-6." - Turn on non-blocking mode if WANT_WRITE simulation is enabled. - Create a send IO callback that gets registered when this option is turned on. This callback alternates between letting the TX through and returning a WANT_WRITE error. --- examples/client/client.c | 34 ++++++++++++++++++++++------------ wolfssl/test.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 23c8214df..92aee8c9d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -184,10 +184,15 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl) else #endif { - if (error != WOLFSSL_ERROR_WANT_WRITE) { - #ifdef WOLFSSL_DTLS - currTimeout = wolfSSL_dtls_get_current_timeout(ssl); - #endif + #ifdef WOLFSSL_DTLS + currTimeout = wolfSSL_dtls_get_current_timeout(ssl); + #endif + if (error == WOLFSSL_ERROR_WANT_WRITE) { + select_ret = tcp_select_tx(sockfd, currTimeout); + + } + else + { select_ret = tcp_select(sockfd, currTimeout); } } @@ -206,13 +211,6 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl) #endif error = wolfSSL_get_error(ssl, 0); elapsedSec = 0; /* reset elapsed */ - if (error == WOLFSSL_ERROR_WANT_WRITE) { - /* Do a send select here. */ - select_ret = tcp_select_tx(sockfd, 1); - if (select_ret == TEST_TIMEOUT) { - error = WOLFSSL_FATAL_ERROR; - } - } } else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) { error = WOLFSSL_ERROR_WANT_READ; @@ -1108,6 +1106,7 @@ static const char* client_usage_msg[][66] = { #ifdef HAVE_TRUSTED_CA "-5 Use Trusted CA Key Indication\n", /* 63 */ #endif + "-6 Simulate WANT_WRITE errors on every other IO send\n", #ifdef HAVE_CURVE448 "-8 Use X448 for key exchange\n", /* 66 */ #endif @@ -1485,6 +1484,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int matchName = 0; int doPeerCheck = 1; int nonBlocking = 0; + int simulateWantWrite = 0; int resumeSession = 0; int wc_shutdown = 0; int disableCRL = 0; @@ -1660,7 +1660,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "ab:c:defgh:i;jk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:" - "01:23:458" + "01:23:4568" "@#")) != -1) { switch (ch) { case '?' : @@ -2116,6 +2116,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif /* HAVE_TRUSTED_CA */ break; + case '6' : + nonBlocking = 1; + simulateWantWrite = 1; + break; + case '8' : #ifdef HAVE_CURVE448 useX448 = 1; @@ -2387,6 +2392,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("unable to get ctx"); #endif + if (simulateWantWrite) + { + wolfSSL_CTX_SetIOSend(ctx, SimulateWantWriteIOSendCb); + } + #ifdef SINGLE_THREADED if (wolfSSL_CTX_new_rng(ctx) != WOLFSSL_SUCCESS) { wolfSSL_CTX_free(ctx); ctx = NULL; diff --git a/wolfssl/test.h b/wolfssl/test.h index a781a4e08..b4543c1c2 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3805,8 +3805,48 @@ static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx) #endif /* HAVE_PK_CALLBACKS */ +static WC_INLINE int SimulateWantWriteIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + static int wantWriteFlag = 1; + int sent; + int sd = *(int*)ctx; + (void)ssl; + + if (!wantWriteFlag) + { + wantWriteFlag = 1; + + sent = wolfIO_Send(sd, buf, sz, 0); + if (sent < 0) { + int err = errno; + + if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } + else if (err == SOCKET_ECONNRESET) { + return WOLFSSL_CBIO_ERR_CONN_RST; + } + else if (err == SOCKET_EINTR) { + return WOLFSSL_CBIO_ERR_ISR; + } + else if (err == SOCKET_EPIPE) { + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + } + else { + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + + return sent; + } + else + { + wantWriteFlag = 0; + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } +} #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \ || defined(_MSC_VER) From 2fc594d31948aa1832387d2442595c224599e568 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Mon, 2 Nov 2020 14:57:37 -0600 Subject: [PATCH 2/3] Modify example server to be resilient to WANT_WRITE errors. --- examples/client/client.c | 6 +++--- examples/server/server.c | 29 +++++++++++++++++++---------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 92aee8c9d..02d1dfae2 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -184,15 +184,15 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl) else #endif { - #ifdef WOLFSSL_DTLS - currTimeout = wolfSSL_dtls_get_current_timeout(ssl); - #endif if (error == WOLFSSL_ERROR_WANT_WRITE) { select_ret = tcp_select_tx(sockfd, currTimeout); } else { + #ifdef WOLFSSL_DTLS + currTimeout = wolfSSL_dtls_get_current_timeout(ssl); + #endif select_ret = tcp_select(sockfd, currTimeout); } } diff --git a/examples/server/server.c b/examples/server/server.c index 0bd6efd2c..00480583c 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -137,7 +137,6 @@ static int lng_index = 0; } #endif - static void err_sys_ex(int out, const char* msg) { if (out == 1) { /* if server is running w/ -x flag, print error w/o exit */ @@ -312,7 +311,11 @@ static int NonBlockingSSL_Accept(SSL* ssl) else #endif { - if (error != WOLFSSL_ERROR_WANT_WRITE) { + if (error == WOLFSSL_ERROR_WANT_WRITE) + { + select_ret = tcp_select_tx(sockfd, currTimeout); + } + else { #ifdef WOLFSSL_DTLS currTimeout = wolfSSL_dtls_get_current_timeout(ssl); #endif @@ -333,12 +336,6 @@ static int NonBlockingSSL_Accept(SSL* ssl) srvHandShakeCB, srvTimeoutCB, srvTo); #endif error = SSL_get_error(ssl, 0); - if (error == WOLFSSL_ERROR_WANT_WRITE) { - /* Do a select here. */ - select_ret = tcp_select_tx(sockfd, 1); - if (select_ret == TEST_TIMEOUT) - error = WOLFSSL_FATAL_ERROR; - } } else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) { error = WOLFSSL_ERROR_WANT_READ; @@ -694,6 +691,7 @@ static const char* server_usage_msg[][56] = { #ifdef HAVE_TRUSTED_CA "-5 Use Trusted CA Key Indication\n", /* 53 */ #endif + "-6 Simulate WANT_WRITE errors on every other IO send\n", #ifdef HAVE_CURVE448 "-8 Pre-generate Key share using Curve448 only\n", /* 55 */ #endif @@ -984,6 +982,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; + int simulateWantWrite = 0; int fewerPackets = 0; #ifdef HAVE_PK_CALLBACKS int pkCallbacks = 0; @@ -1157,8 +1156,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "abc:defgijk:l:mnop:q:rstuv:wxy" "A:B:C:D:E:FGH:IJKL:MNO:PQR:S:TUVYZ:" - "01:23:4:58" - "@#")) != -1) { + "01:23:4:568" + "@#")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1549,6 +1548,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif /* HAVE_TRUSTED_CA */ break; + case '6' : + nonBlocking = 1; + simulateWantWrite = 1; + break; + case '8' : #ifdef HAVE_CURVE448 useX448 = 1; @@ -1730,6 +1734,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) if (ctx == NULL) err_sys_ex(catastrophic, "unable to get ctx"); + if (simulateWantWrite) + { + wolfSSL_CTX_SetIOSend(ctx, SimulateWantWriteIOSendCb); + } + #if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \ defined(HAVE_POLY1305) if (TicketInit() != 0) From 3d5c747ed590f531691bfc275d05e8addb22d1eb Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Tue, 3 Nov 2020 16:05:12 -0600 Subject: [PATCH 3/3] Modify a couple tests to use WANT_WRITE simulation. --- tests/test-tls13.conf | 2 ++ tests/test.conf | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/test-tls13.conf b/tests/test-tls13.conf index f946cdcf4..0900b41a6 100644 --- a/tests/test-tls13.conf +++ b/tests/test-tls13.conf @@ -9,10 +9,12 @@ # server TLSv1.3 TLS13-AES128-GCM-SHA256 -v 4 -l TLS13-AES128-GCM-SHA256 +-6 # client TLSv1.3 TLS13-AES128-GCM-SHA256 -v 4 -l TLS13-AES128-GCM-SHA256 +-6 # server TLSv1.3 TLS13-AES256-GCM-SHA384 -v 4 diff --git a/tests/test.conf b/tests/test.conf index 83c228bc3..9f6c2db1b 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2152,10 +2152,12 @@ # client TLSv1.2 with block cipher -v 3 -l ECDHE-RSA-AES128-SHA256 +-6 # server TLSv1.2 with block cipher -v 3 -l ECDHE-RSA-AES128-SHA256 +-6 # client TLSv1.2 with block cipher and no ETM -v 3