diff --git a/cyassl/test.h b/cyassl/test.h index 84e66fbf0..6c62c04c9 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -401,6 +401,40 @@ static INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz) } +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + +static INLINE int tcp_select(SOCKET_T socketfd, unsigned int to_sec) +{ + fd_set recvfds, errfds; + SOCKET_T nfds = socketfd + 1; + struct timeval timeout = {to_sec, 0}; + int result; + + FD_ZERO(&recvfds); + FD_SET(socketfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, &timeout); + + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(socketfd, &recvfds)) + return TEST_RECV_READY; + else if(FD_ISSET(socketfd, &errfds)) + return TEST_ERROR_READY; + } + + return TEST_SELECT_FAIL; +} + + static INLINE void tcp_listen(SOCKET_T* sockfd, int port, int useAnyAddr, int udp) { diff --git a/examples/client/client.c b/examples/client/client.c index d2e9c7ce4..2c00a6144 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -48,42 +48,39 @@ int ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout); #endif int error = CyaSSL_get_error(ssl, 0); - int timeout_count = CyaSSL_dtls_get_current_timeout(ssl) * 10; + SOCKET_T sockfd = (SOCKET_T)CyaSSL_get_fd(ssl); + int select_ret; + while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) { - (void)timeout_count; if (error == SSL_ERROR_WANT_READ) printf("... client would read block\n"); else printf("... client would write block\n"); - #ifdef USE_WINDOWS_API - Sleep(100); - #else - #ifdef CYASSL_DTLS - usleep(100000); /* 100ms */ + + if (CyaSSL_dtls(ssl)) + select_ret = tcp_select(sockfd, + CyaSSL_dtls_get_current_timeout(ssl)); + else + select_ret = tcp_select(sockfd, 1); + + if ((select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + #ifndef CYASSL_CALLBACKS + ret = CyaSSL_connect(ssl); #else - sleep(1); + ret = CyaSSL_connect_ex(ssl,handShakeCB,timeoutCB,timeout); #endif - #endif - #ifndef CYASSL_CALLBACKS - ret = CyaSSL_connect(ssl); - #else - ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout); - #endif - error = CyaSSL_get_error(ssl, 0); - #ifdef CYASSL_DTLS - if (timeout_count-- <= 0) { - timeout_count = CyaSSL_dtls_got_timeout(ssl); - if (timeout_count < 0) { - error = SSL_FATAL_ERROR; - } - else { - printf("... updating timeout\n"); - timeout_count = - CyaSSL_dtls_get_current_timeout(ssl) * 10; - } - } - #endif + error = CyaSSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT && + (!CyaSSL_dtls(ssl) || + (CyaSSL_dtls_got_timeout(ssl) >= 0))) { + error = SSL_ERROR_WANT_READ; + } + else { + error = SSL_FATAL_ERROR; + } } if (ret != SSL_SUCCESS) err_sys("SSL_connect failed"); diff --git a/examples/server/server.c b/examples/server/server.c index 161cfc53b..0a414dbdc 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -44,20 +44,37 @@ int ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB, srvTo); #endif int error = SSL_get_error(ssl, 0); + SOCKET_T sockfd = (SOCKET_T)CyaSSL_get_fd(ssl); + int select_ret; + while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) { printf("... server would block\n"); - #ifdef USE_WINDOWS_API - Sleep(1000); - #else - sleep(1); - #endif - #ifndef CYASSL_CALLBACKS - ret = SSL_accept(ssl); - #else - ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB,srvTo); - #endif - error = SSL_get_error(ssl, 0); + + if (CyaSSL_dtls(ssl)) + select_ret = tcp_select(sockfd, + CyaSSL_dtls_get_current_timeout(ssl)); + else + select_ret = tcp_select(sockfd, 1); + + if ((select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + #ifndef CYASSL_CALLBACKS + ret = SSL_accept(ssl); + #else + ret = CyaSSL_accept_ex(ssl, + srvHandShakeCB, srvTimeoutCB, srvTo); + #endif + error = SSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT && + (!CyaSSL_dtls(ssl) || + (CyaSSL_dtls_got_timeout(ssl) >= 0))) { + error = SSL_ERROR_WANT_READ; + } + else { + error = SSL_FATAL_ERROR; + } } if (ret != SSL_SUCCESS) err_sys("SSL_accept failed");