diff --git a/examples/client/client.c b/examples/client/client.c index 35a61f05c..3aba5f458 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -138,13 +138,16 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl) else #endif { - #ifdef WOLFSSL_DTLS - currTimeout = wolfSSL_dtls_get_current_timeout(ssl); - #endif - select_ret = tcp_select(sockfd, currTimeout); + if (error != WOLFSSL_ERROR_WANT_WRITE) { + #ifdef WOLFSSL_DTLS + currTimeout = wolfSSL_dtls_get_current_timeout(ssl); + #endif + select_ret = tcp_select(sockfd, currTimeout); + } } - if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_ERROR_READY) + if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_SEND_READY) + || (select_ret == TEST_ERROR_READY) #ifdef WOLFSSL_ASYNC_CRYPT || error == WC_PENDING_E #endif @@ -156,6 +159,13 @@ 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; diff --git a/examples/server/server.c b/examples/server/server.c index a64f2cfda..1e8695fbb 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -149,13 +149,16 @@ static int NonBlockingSSL_Accept(SSL* ssl) else #endif { - #ifdef WOLFSSL_DTLS - currTimeout = wolfSSL_dtls_get_current_timeout(ssl); - #endif - select_ret = tcp_select(sockfd, currTimeout); + if (error != WOLFSSL_ERROR_WANT_WRITE) { + #ifdef WOLFSSL_DTLS + currTimeout = wolfSSL_dtls_get_current_timeout(ssl); + #endif + select_ret = tcp_select(sockfd, currTimeout); + } } - if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_ERROR_READY) + if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_SEND_READY) + || (select_ret == TEST_ERROR_READY) #ifdef WOLFSSL_ASYNC_CRYPT || error == WC_PENDING_E #endif @@ -167,6 +170,12 @@ 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; diff --git a/wolfssl/test.h b/wolfssl/test.h index 1c61f23af..a9cc4e868 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -909,15 +909,18 @@ enum { TEST_SELECT_FAIL, TEST_TIMEOUT, TEST_RECV_READY, + TEST_SEND_READY, TEST_ERROR_READY }; #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \ !defined(WOLFSSL_TIRTOS) -static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) +static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx) { - fd_set recvfds, errfds; + fd_set fds, errfds; + fd_set* recvfds = NULL; + fd_set* sendfds = NULL; SOCKET_T nfds = socketfd + 1; #if !defined(__INTEGRITY) struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0}; @@ -926,32 +929,56 @@ static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) #endif int result; - FD_ZERO(&recvfds); - FD_SET(socketfd, &recvfds); + FD_ZERO(&fds); + FD_SET(socketfd, &fds); FD_ZERO(&errfds); FD_SET(socketfd, &errfds); + if (rx) + recvfds = &fds; + else + sendfds = &fds; + #if defined(__INTEGRITY) timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0; #endif - result = select(nfds, &recvfds, NULL, &errfds, &timeout); + result = select(nfds, recvfds, sendfds, &errfds, &timeout); if (result == 0) return TEST_TIMEOUT; else if (result > 0) { - if (FD_ISSET(socketfd, &recvfds)) - return TEST_RECV_READY; + if (FD_ISSET(socketfd, &fds)) { + if (rx) + return TEST_RECV_READY; + else + return TEST_SEND_READY; + } else if(FD_ISSET(socketfd, &errfds)) return TEST_ERROR_READY; } return TEST_SELECT_FAIL; } + +static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) +{ + return tcp_select_ex(socketfd, to_sec, 1); +} + +static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec) +{ + return tcp_select_ex(socketfd, to_sec, 0); +} + #elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET) static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) { return TEST_RECV_READY; } +static WC_INLINE int tcp_select_tx(SOCKET_T socketfd, int to_sec) +{ + return TEST_SEND_READY; +} #endif /* !WOLFSSL_MDK_ARM */