Merge pull request #2021 from ejohnstown/dtls-resume

DTLS Update
This commit is contained in:
toddouska 2019-01-21 15:35:40 -08:00 committed by GitHub
commit e87dac66ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 333 additions and 34 deletions

View File

@ -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;

View File

@ -115,6 +115,138 @@ static void err_sys_ex(int out, const char* msg)
}
}
#ifdef WOLFSSL_DTLS
/* Translates return codes returned from
* send() and recv() if need be.
*/
static WC_INLINE int TranslateReturnCode(int old, int sd)
{
(void)sd;
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
if (old == 0) {
errno = SOCKET_EWOULDBLOCK;
return -1; /* convert to BSD style wouldblock as error */
}
if (old < 0) {
errno = RTCS_geterror(sd);
if (errno == RTCSERR_TCP_CONN_CLOSING)
return 0; /* convert to BSD style closing */
if (errno == RTCSERR_TCP_CONN_RLSD)
errno = SOCKET_ECONNRESET;
if (errno == RTCSERR_TCP_TIMED_OUT)
errno = SOCKET_EAGAIN;
}
#endif
return old;
}
static WC_INLINE int wolfSSL_LastError(void)
{
#ifdef USE_WINDOWS_API
return WSAGetLastError();
#elif defined(EBSNET)
return xn_getlasterror();
#else
return errno;
#endif
}
/* wolfSSL Sock Addr */
struct WOLFSSL_TEST_SOCKADDR {
unsigned int sz; /* sockaddr size */
SOCKADDR_IN_T sa; /* pointer to the sockaddr_in or sockaddr_in6 */
};
typedef struct WOLFSSL_TEST_DTLS_CTX {
struct WOLFSSL_TEST_SOCKADDR peer;
int rfd;
int wfd;
int failOnce;
word32 blockSeq;
} WOLFSSL_TEST_DTLS_CTX;
static WC_INLINE int PeekSeq(const char* buf, word32* seq)
{
const char* c = buf + 3;
if ((c[0] | c[1] | c[2] | c[3]) == 0) {
*seq = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | c[7];
return 1;
}
return 0;
}
/* The send embedded callback
* return : nb bytes sent, or error
*/
static int TestEmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
{
WOLFSSL_TEST_DTLS_CTX* dtlsCtx = (WOLFSSL_TEST_DTLS_CTX*)ctx;
int sd = dtlsCtx->wfd;
int sent;
int len = sz;
int err;
(void)ssl;
WOLFSSL_ENTER("TestEmbedSendTo()");
if (dtlsCtx->failOnce) {
word32 seq = 0;
if (PeekSeq(buf, &seq) && seq == dtlsCtx->blockSeq) {
dtlsCtx->failOnce = 0;
WOLFSSL_MSG("Forcing WANT_WRITE");
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
}
sent = (int)sendto(sd, &buf[sz - len], len, 0,
(const SOCKADDR*)&dtlsCtx->peer.sa,
dtlsCtx->peer.sz);
sent = TranslateReturnCode(sent, sd);
if (sent < 0) {
err = wolfSSL_LastError();
WOLFSSL_MSG("Embed Send To error");
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
WOLFSSL_MSG("\tWould Block");
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
else if (err == SOCKET_ECONNRESET) {
WOLFSSL_MSG("\tConnection reset");
return WOLFSSL_CBIO_ERR_CONN_RST;
}
else if (err == SOCKET_EINTR) {
WOLFSSL_MSG("\tSocket interrupted");
return WOLFSSL_CBIO_ERR_ISR;
}
else if (err == SOCKET_EPIPE) {
WOLFSSL_MSG("\tSocket EPIPE");
return WOLFSSL_CBIO_ERR_CONN_CLOSE;
}
else {
WOLFSSL_MSG("\tGeneral error");
return WOLFSSL_CBIO_ERR_GENERAL;
}
}
return sent;
}
#endif /* WOLFSSL_DTLS */
static int NonBlockingSSL_Accept(SSL* ssl)
{
#ifndef WOLFSSL_CALLBACKS
@ -149,13 +281,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 +302,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;
@ -678,6 +819,9 @@ static void Usage(void)
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
printf("-2 Disable DH Prime check\n");
#endif
#ifdef WOLFSSL_DTLS
printf("-4 <seq> DTLS fake would-block for message seq\n");
#endif
#ifdef WOLFSSL_MULTICAST
printf("%s", msg[++msgId]); /* -3 */
#endif
@ -719,6 +863,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
int dtlsUDP = 0;
int dtlsSCTP = 0;
int doMcast = 0;
#ifdef WOLFSSL_DTLS
int doBlockSeq = 0;
WOLFSSL_TEST_DTLS_CTX dtlsCtx;
#endif
int needDH = 0;
int useNtruKey = 0;
int nonBlocking = 0;
@ -863,7 +1011,7 @@ 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:GH:IJKL:MNO:PQR:S:TUVYZ:"
"01:23:")) != -1) {
"01:23:4:")) != -1) {
switch (ch) {
case '?' :
if(myoptarg!=NULL) {
@ -1219,6 +1367,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
break;
case '4' :
#ifdef WOLFSSL_DTLS
XMEMSET(&dtlsCtx, 0, sizeof(dtlsCtx));
doBlockSeq = 1;
dtlsCtx.blockSeq = atoi(myoptarg);
#endif
break;
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -1598,6 +1754,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
}
if (doDTLS && dtlsUDP) {
#ifdef WOLFSSL_DTLS
if (doBlockSeq) {
wolfSSL_CTX_SetIOSend(ctx, TestEmbedSendTo);
}
#endif
}
#ifdef HAVE_PK_CALLBACKS
if (pkCallbacks)
SetupPkCallbacks(ctx);
@ -1807,12 +1971,22 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
/* For DTLS, peek at the next datagram so we can get the client's
* address and set it into the ssl object later to generate the
* cookie. */
n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
n = (int)recvfrom(clientfd, (char*)b, sizeof(b), MSG_PEEK,
(struct sockaddr*)&cliaddr, &len);
if (n <= 0)
err_sys_ex(runWithErrors, "recvfrom failed");
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
if (doBlockSeq) {
XMEMCPY(&dtlsCtx.peer.sa, &cliaddr, len);
dtlsCtx.peer.sz = len;
dtlsCtx.wfd = clientfd;
dtlsCtx.failOnce = 1;
wolfSSL_SetIOWriteCtx(ssl, &dtlsCtx);
}
else {
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
}
}
#endif
if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL

View File

@ -6003,8 +6003,12 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
DtlsMsg* item;
int ret = 0;
if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ)
WOLFSSL_ENTER("DtlsMsgPoolSave()");
if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ) {
WOLFSSL_ERROR(DTLS_POOL_SZ_E);
return DTLS_POOL_SZ_E;
}
item = DtlsMsgNew(dataSz, ssl->heap);
@ -6027,6 +6031,7 @@ int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
else
ret = MEMORY_E;
WOLFSSL_LEAVE("DtlsMsgPoolSave()", ret);
return ret;
}
@ -6039,6 +6044,7 @@ int DtlsMsgPoolTimeout(WOLFSSL* ssl)
ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
result = 0;
}
WOLFSSL_LEAVE("DtlsMsgPoolTimeout()", result);
return result;
}
@ -6047,9 +6053,11 @@ int DtlsMsgPoolTimeout(WOLFSSL* ssl)
* value. */
void DtlsMsgPoolReset(WOLFSSL* ssl)
{
WOLFSSL_ENTER("DtlsMsgPoolReset()");
if (ssl->dtls_tx_msg_list) {
DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap);
ssl->dtls_tx_msg_list = NULL;
ssl->dtls_tx_msg = NULL;
ssl->dtls_tx_msg_list_sz = 0;
ssl->dtls_timeout = ssl->dtls_timeout_init;
}
@ -6078,9 +6086,25 @@ int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset)
int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
{
int ret = 0;
DtlsMsg* pool = ssl->dtls_tx_msg_list;
DtlsMsg* pool;
WOLFSSL_ENTER("DtlsMsgPoolSend()");
pool = ssl->dtls_tx_msg == NULL ? ssl->dtls_tx_msg_list : ssl->dtls_tx_msg;
if (pool != NULL) {
if ((ssl->options.side == WOLFSSL_SERVER_END &&
!(ssl->options.acceptState == SERVER_HELLO_DONE ||
ssl->options.acceptState == ACCEPT_FINISHED_DONE)) ||
(ssl->options.side == WOLFSSL_CLIENT_END &&
!(ssl->options.connectState == CLIENT_HELLO_SENT ||
ssl->options.connectState == HELLO_AGAIN_REPLY ||
ssl->options.connectState == FINISHED_DONE))) {
WOLFSSL_ERROR(DTLS_RETX_OVER_TX);
ssl->error = DTLS_RETX_OVER_TX;
return WOLFSSL_FATAL_ERROR;
}
while (pool != NULL) {
if (pool->seq == 0) {
@ -6098,8 +6122,10 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
WriteSEQ(ssl, epochOrder, dtls->sequence_number);
DtlsSEQIncrement(ssl, epochOrder);
if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0)
if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0) {
WOLFSSL_ERROR(ret);
return ret;
}
XMEMCPY(ssl->buffers.outputBuffer.buffer,
pool->buf, pool->sz);
@ -6115,21 +6141,26 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
inputSz = pool->sz;
sendSz = inputSz + MAX_MSG_EXTRA;
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
WOLFSSL_ERROR(ret);
return ret;
}
output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 0, 0, 0);
if (sendSz < 0)
if (sendSz < 0) {
WOLFSSL_ERROR(BUILD_MSG_ERROR);
return BUILD_MSG_ERROR;
}
ssl->buffers.outputBuffer.length += sendSz;
}
ret = SendBuffered(ssl);
if (ret < 0) {
WOLFSSL_ERROR(ret);
return ret;
}
@ -6148,9 +6179,11 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
}
else
pool = pool->next;
ssl->dtls_tx_msg = pool;
}
}
WOLFSSL_LEAVE("DtlsMsgPoolSend()", ret);
return ret;
}
@ -7094,6 +7127,7 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (IsDtlsNotSctpMode(ssl) &&
(!DtlsCheckWindow(ssl) ||
(ssl->options.handShakeDone && ssl->keys.curEpoch == 0))) {
WOLFSSL_LEAVE("GetRecordHeader()", SEQUENCE_ERROR);
return SEQUENCE_ERROR;
}
#endif
@ -7186,8 +7220,10 @@ static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
word32 idx = *inOutIdx;
*inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
if (*inOutIdx > totalSz)
if (*inOutIdx > totalSz) {
WOLFSSL_ERROR(BUFFER_E);
return BUFFER_E;
}
*type = input[idx++];
c24to32(input + idx, size);
@ -7203,8 +7239,10 @@ static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
if (ssl->curRL.pvMajor != ssl->version.major ||
ssl->curRL.pvMinor != ssl->version.minor) {
if (*type != client_hello && *type != hello_verify_request)
if (*type != client_hello && *type != hello_verify_request) {
WOLFSSL_ERROR(VERSION_ERROR);
return VERSION_ERROR;
}
else {
WOLFSSL_MSG("DTLS Handshake ignoring hello or verify version");
}
@ -10551,10 +10589,17 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
#ifndef NO_WOLFSSL_CLIENT
if (ssl->options.side == WOLFSSL_CLIENT_END) {
if (!ssl->options.resuming &&
ssl->msgsReceived.got_server_hello_done == 0) {
WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
return OUT_OF_ORDER_E;
if (!ssl->options.resuming) {
if (ssl->msgsReceived.got_server_hello_done == 0) {
WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
return OUT_OF_ORDER_E;
}
}
else {
if (ssl->msgsReceived.got_server_hello == 0) {
WOLFSSL_MSG("No ServerHello before ChangeCipher on Resume");
return OUT_OF_ORDER_E;
}
}
#ifdef HAVE_SESSION_TICKET
if (ssl->expect_session_ticket) {
@ -11240,6 +11285,8 @@ static int DtlsMsgDrain(WOLFSSL* ssl)
DtlsMsg* item = ssl->dtls_rx_msg_list;
int ret = 0;
WOLFSSL_ENTER("DtlsMsgDrain()");
/* While there is an item in the store list, and it is the expected
* message, and it is complete, and there hasn't been an error in the
* last message... */
@ -11263,6 +11310,7 @@ static int DtlsMsgDrain(WOLFSSL* ssl)
ssl->dtls_rx_msg_list_sz--;
}
WOLFSSL_LEAVE("DtlsMsgDrain()", ret);
return ret;
}
@ -11290,12 +11338,16 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
/* parse header */
if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
&size, &fragOffset, &fragSz, totalSz) != 0)
&size, &fragOffset, &fragSz, totalSz) != 0) {
WOLFSSL_ERROR(PARSE_ERROR);
return PARSE_ERROR;
}
/* check that we have complete fragment */
if (*inOutIdx + fragSz > totalSz)
if (*inOutIdx + fragSz > totalSz) {
WOLFSSL_ERROR(INCOMPLETE_DATA);
return INCOMPLETE_DATA;
}
/* Check the handshake sequence number first. If out of order,
* add the current message to the list. If the message is in order,
@ -11340,6 +11392,7 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
*inOutIdx += fragSz;
if(type == finished ) {
if (*inOutIdx + ssl->keys.padSz > totalSz) {
WOLFSSL_ERROR(BUFFER_E);
return BUFFER_E;
}
*inOutIdx += ssl->keys.padSz;
@ -13170,8 +13223,10 @@ int ProcessReply(WOLFSSL* ssl)
ret = BUFFER_ERROR;
#endif
}
if (ret != 0)
if (ret != 0) {
WOLFSSL_ERROR(ret);
return ret;
}
break;
case change_cipher_spec:
@ -13446,6 +13501,7 @@ int SendChangeCipher(WOLFSSL* ssl)
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
DtlsSEQIncrement(ssl, CUR_ORDER);
if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
@ -15796,6 +15852,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case EXT_MISSING:
return "Required TLS extension missing";
case DTLS_RETX_OVER_TX:
return "DTLS interrupting flight transmit with retransmit";
default :
return "unknown error number";
}

View File

@ -8768,6 +8768,8 @@ int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
int timeout = 0;
if (ssl)
timeout = ssl->dtls_timeout;
WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout()", timeout);
return timeout;
}
@ -8810,6 +8812,7 @@ int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
{
int result = WOLFSSL_SUCCESS;
WOLFSSL_ENTER("wolfSSL_dtls_got_timeout()");
if (ssl == NULL)
return WOLFSSL_FATAL_ERROR;
@ -8819,9 +8822,32 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
result = WOLFSSL_FATAL_ERROR;
}
WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout()", result);
return result;
}
/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_dtls_retransmit()");
if (ssl == NULL)
return WOLFSSL_FATAL_ERROR;
if (!ssl->options.handShakeDone) {
int result = DtlsMsgPoolSend(ssl, 0);
if (result < 0) {
ssl->error = result;
WOLFSSL_ERROR(result);
return WOLFSSL_FATAL_ERROR;
}
}
return 0;
}
#endif /* DTLS */
#endif /* LEANPSK */

View File

@ -163,6 +163,7 @@ enum wolfSSL_ErrorCodes {
EXT_MISSING = -428, /* Required extension not found */
UNSUPPORTED_EXTENSION = -429, /* TLSX not requested by client */
PRF_MISSING = -430, /* PRF not compiled in */
DTLS_RETX_OVER_TX = -431, /* Retransmit DTLS flight over */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */

View File

@ -3741,6 +3741,7 @@ struct WOLFSSL {
word32 dtls_tx_msg_list_sz;
word32 dtls_rx_msg_list_sz;
DtlsMsg* dtls_tx_msg_list;
DtlsMsg* dtls_tx_msg;
DtlsMsg* dtls_rx_msg_list;
void* IOCB_CookieCtx; /* gen cookie ctx */
word32 dtls_expected_rx;

View File

@ -723,6 +723,7 @@ WOLFSSL_API int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int);
WOLFSSL_API int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int);
WOLFSSL_API int wolfSSL_dtls_got_timeout(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_dtls_retransmit(WOLFSSL*);
WOLFSSL_API int wolfSSL_dtls(WOLFSSL* ssl);
WOLFSSL_API int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int);

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