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
#endif
{
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;

View File

@ -149,13 +149,16 @@ static int NonBlockingSSL_Accept(SSL* ssl)
else
#endif
{
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;

View File

@ -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))
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 */