DTLS Nonblocking Updates

1. Add a second select for tx.
2. Revised tcp_select to work for either rx or tx.
3. Updated client and server to use new tcp_select_tx() for checking the
tx socket if the nonblocking connect/accept would block on transmit.
This commit is contained in:
John Safranek
2018-12-14 11:30:03 -08:00
parent 63f6c1d280
commit 8356c3d7e2
3 changed files with 63 additions and 17 deletions

View File

@@ -138,13 +138,16 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
else else
#endif #endif
{ {
#ifdef WOLFSSL_DTLS if (error != WOLFSSL_ERROR_WANT_WRITE) {
currTimeout = wolfSSL_dtls_get_current_timeout(ssl); #ifdef WOLFSSL_DTLS
#endif currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
select_ret = tcp_select(sockfd, currTimeout); #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 #ifdef WOLFSSL_ASYNC_CRYPT
|| error == WC_PENDING_E || error == WC_PENDING_E
#endif #endif
@@ -156,6 +159,13 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
#endif #endif
error = wolfSSL_get_error(ssl, 0); error = wolfSSL_get_error(ssl, 0);
elapsedSec = 0; /* reset elapsed */ 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)) { else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
error = WOLFSSL_ERROR_WANT_READ; error = WOLFSSL_ERROR_WANT_READ;

View File

@@ -149,13 +149,16 @@ static int NonBlockingSSL_Accept(SSL* ssl)
else else
#endif #endif
{ {
#ifdef WOLFSSL_DTLS if (error != WOLFSSL_ERROR_WANT_WRITE) {
currTimeout = wolfSSL_dtls_get_current_timeout(ssl); #ifdef WOLFSSL_DTLS
#endif currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
select_ret = tcp_select(sockfd, currTimeout); #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 #ifdef WOLFSSL_ASYNC_CRYPT
|| error == WC_PENDING_E || error == WC_PENDING_E
#endif #endif
@@ -167,6 +170,12 @@ static int NonBlockingSSL_Accept(SSL* ssl)
srvHandShakeCB, srvTimeoutCB, srvTo); srvHandShakeCB, srvTimeoutCB, srvTo);
#endif #endif
error = SSL_get_error(ssl, 0); 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)) { else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
error = WOLFSSL_ERROR_WANT_READ; error = WOLFSSL_ERROR_WANT_READ;

View File

@@ -909,15 +909,18 @@ enum {
TEST_SELECT_FAIL, TEST_SELECT_FAIL,
TEST_TIMEOUT, TEST_TIMEOUT,
TEST_RECV_READY, TEST_RECV_READY,
TEST_SEND_READY,
TEST_ERROR_READY TEST_ERROR_READY
}; };
#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \ #if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_TCP_NET) && \
!defined(WOLFSSL_TIRTOS) !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; SOCKET_T nfds = socketfd + 1;
#if !defined(__INTEGRITY) #if !defined(__INTEGRITY)
struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0}; 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 #endif
int result; int result;
FD_ZERO(&recvfds); FD_ZERO(&fds);
FD_SET(socketfd, &recvfds); FD_SET(socketfd, &fds);
FD_ZERO(&errfds); FD_ZERO(&errfds);
FD_SET(socketfd, &errfds); FD_SET(socketfd, &errfds);
if (rx)
recvfds = &fds;
else
sendfds = &fds;
#if defined(__INTEGRITY) #if defined(__INTEGRITY)
timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0; timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0;
#endif #endif
result = select(nfds, &recvfds, NULL, &errfds, &timeout); result = select(nfds, recvfds, sendfds, &errfds, &timeout);
if (result == 0) if (result == 0)
return TEST_TIMEOUT; return TEST_TIMEOUT;
else if (result > 0) { else if (result > 0) {
if (FD_ISSET(socketfd, &recvfds)) if (FD_ISSET(socketfd, &fds)) {
return TEST_RECV_READY; if (rx)
return TEST_RECV_READY;
else
return TEST_SEND_READY;
}
else if(FD_ISSET(socketfd, &errfds)) else if(FD_ISSET(socketfd, &errfds))
return TEST_ERROR_READY; return TEST_ERROR_READY;
} }
return TEST_SELECT_FAIL; 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) #elif defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_KEIL_TCP_NET)
static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec) static WC_INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
{ {
return TEST_RECV_READY; 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 */ #endif /* !WOLFSSL_MDK_ARM */