Merge pull request #5084 from julek-wolfssl/zd14101-dtls-want-write

DTLS fixes with WANT_WRITE simulations
This commit is contained in:
John Safranek
2022-05-12 09:36:40 -07:00
committed by GitHub
6 changed files with 112 additions and 26 deletions

View File

@ -201,7 +201,8 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
else
{
#ifdef WOLFSSL_DTLS
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
if (wolfSSL_dtls(ssl))
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
#endif
select_ret = tcp_select(sockfd, currTimeout);
}
@ -232,9 +233,13 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
}
}
#ifdef WOLFSSL_DTLS
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
wolfSSL_dtls_got_timeout(ssl) >= 0) {
error = WOLFSSL_ERROR_WANT_READ;
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl)) {
ret = wolfSSL_dtls_got_timeout(ssl);
if (ret != WOLFSSL_SUCCESS)
error = wolfSSL_get_error(ssl, ret);
else
error = WOLFSSL_ERROR_WANT_READ;
ret = WOLFSSL_FAILURE; /* Reset error so we loop */
}
#endif
else {
@ -3561,6 +3566,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
err_sys("error in setting fd");
}
if (simulateWantWrite) {
if (dtlsUDP) {
wolfSSL_SetIOWriteCtx(ssl, (void*)&sockfd);
udp_connect(&sockfd, host, port);
}
}
/* STARTTLS */
if (doSTARTTLS) {
if (StartTLS_Init(&sockfd) != WOLFSSL_SUCCESS) {
@ -4097,6 +4109,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
wolfSSL_CTX_free(ctx); ctx = NULL;
err_sys("error in setting fd");
}
if (simulateWantWrite) {
if (dtlsUDP) {
wolfSSL_SetIOWriteCtx(ssl, (void*)&sockfd);
udp_connect(&sockfd, host, port);
}
}
#ifdef HAVE_ALPN
if (alpnList != NULL) {
printf("ALPN accepted protocols list : %s\n", alpnList);

View File

@ -330,7 +330,8 @@ static int NonBlockingSSL_Accept(SSL* ssl)
}
else {
#ifdef WOLFSSL_DTLS
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
if (wolfSSL_dtls(ssl))
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
#endif
select_ret = tcp_select(sockfd, currTimeout);
}
@ -354,9 +355,13 @@ static int NonBlockingSSL_Accept(SSL* ssl)
error = WOLFSSL_ERROR_WANT_READ;
}
#ifdef WOLFSSL_DTLS
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
wolfSSL_dtls_got_timeout(ssl) >= 0) {
error = WOLFSSL_ERROR_WANT_READ;
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl)) {
ret = wolfSSL_dtls_got_timeout(ssl);
if (ret != WOLFSSL_SUCCESS)
error = wolfSSL_get_error(ssl, ret);
else
error = WOLFSSL_ERROR_WANT_READ;
ret = WOLFSSL_FAILURE; /* Reset error so we loop */
}
#endif
else {
@ -2958,6 +2963,17 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
else {
wolfSSL_dtls_set_peer(ssl, &client_addr, client_len);
}
if (simulateWantWrite) {
#ifdef USE_WOLFSSL_IO
/* connect on a udp to associate peer with this fd to make it
* simpler for SimulateWantWriteIOSendCb */
if (connect(clientfd, (struct sockaddr*)&client_addr,
client_len) != 0) {
err_sys_ex(catastrophic, "error in connecting to peer");
}
wolfSSL_SetIOWriteCtx(ssl, (void*)&sockfd);
#endif
}
}
#endif

View File

@ -8883,9 +8883,8 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
dataSz += DTLS_HANDSHAKE_HEADER_SZ;
AddHandShakeHeader(data,
inputSz, ssl->fragOffset, fragSz, type, ssl);
}
if (ssl->options.dtls)
ssl->keys.dtls_handshake_number--;
}
if (IsDtlsNotSctpMode(ssl) &&
(ret = DtlsMsgPoolSave(ssl, data,
fragSz + DTLS_HANDSHAKE_HEADER_SZ, type))
@ -17481,6 +17480,11 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
#endif
}
if (ret != 0
/* DoDtlsHandShakeMsg can return a WANT_WRITE when
* calling DtlsMsgPoolSend. This msg is done
* processing so let's move on. */
&& (!ssl->options.dtls
|| ret != WANT_WRITE)
#ifdef WOLFSSL_ASYNC_CRYPT
/* In async case, on pending, move onto next message.
* Current message should have been DtlsMsgStore'ed and
@ -26785,6 +26789,12 @@ int SendCertificateVerify(WOLFSSL* ssl)
if (args->output == NULL) {
ERROR_OUT(BUFFER_ERROR, exit_scv);
}
#ifdef WOLFSSL_DTLS
/* We have re-entered this funtion after a WANT_WRITE. Make sure
* the handshake number stays the same. */
if (ssl->options.dtls && ssl->fragOffset != 0)
ssl->keys.dtls_handshake_number--;
#endif
AddHeaders(args->output, (word32)args->length + args->extraSz +
VERIFY_HEADER, certificate_verify, ssl);
@ -28873,6 +28883,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case TLS_ASYNC_FINALIZE:
{
#ifdef WOLFSSL_DTLS
/* We have re-entered this funtion after a WANT_WRITE. Make sure
* the handshake number stays the same. */
if (ssl->options.dtls && ssl->fragOffset != 0)
ssl->keys.dtls_handshake_number--;
#endif
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)
if (ssl->specs.kea == ecdhe_psk_kea ||

View File

@ -11836,9 +11836,14 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
* fragment, fragOffset is zero again, and the state can be
* advanced. */
if (ssl->fragOffset == 0) {
ssl->options.connectState++;
WOLFSSL_MSG("connect state: "
"Advanced from last buffered fragment send");
if (ssl->options.connectState == CONNECT_BEGIN ||
ssl->options.connectState == HELLO_AGAIN ||
(ssl->options.connectState >= FIRST_REPLY_DONE &&
ssl->options.connectState <= FIRST_REPLY_FOURTH)) {
ssl->options.connectState++;
WOLFSSL_MSG("connect state: "
"Advanced from last buffered fragment send");
}
}
else {
WOLFSSL_MSG("connect state: "
@ -12303,9 +12308,19 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
* fragment, fragOffset is zero again, and the state can be
* advanced. */
if (ssl->fragOffset == 0) {
ssl->options.acceptState++;
WOLFSSL_MSG("accept state: "
"Advanced from last buffered fragment send");
if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
ssl->options.acceptState == SERVER_HELLO_SENT ||
ssl->options.acceptState == CERT_SENT ||
ssl->options.acceptState == CERT_STATUS_SENT ||
ssl->options.acceptState == KEY_EXCHANGE_SENT ||
ssl->options.acceptState == CERT_REQ_SENT ||
ssl->options.acceptState == ACCEPT_SECOND_REPLY_DONE ||
ssl->options.acceptState == TICKET_SENT ||
ssl->options.acceptState == CHANGE_CIPHER_SENT) {
ssl->options.acceptState++;
WOLFSSL_MSG("accept state: "
"Advanced from last buffered fragment send");
}
}
else {
WOLFSSL_MSG("accept state: "

View File

@ -8637,9 +8637,15 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
* fragment, fragOffset is zero again, and the state can be
* advanced. */
if (ssl->fragOffset == 0) {
ssl->options.connectState++;
WOLFSSL_MSG("connect state: "
"Advanced from last buffered fragment send");
/* Only increment from states in which we send data */
if (ssl->options.connectState == CONNECT_BEGIN ||
ssl->options.connectState == HELLO_AGAIN ||
(ssl->options.connectState >= FIRST_REPLY_DONE &&
ssl->options.connectState <= FIRST_REPLY_FOURTH)) {
ssl->options.connectState++;
WOLFSSL_MSG("connect state: "
"Advanced from last buffered fragment send");
}
}
else {
WOLFSSL_MSG("connect state: "
@ -9592,9 +9598,22 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
* fragment, fragOffset is zero again, and the state can be
* advanced. */
if (ssl->fragOffset == 0) {
ssl->options.acceptState++;
WOLFSSL_MSG("accept state: "
"Advanced from last buffered fragment send");
/* Only increment from states in which we send data */
if (ssl->options.acceptState == TLS13_ACCEPT_CLIENT_HELLO_DONE ||
ssl->options.acceptState == TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE ||
ssl->options.acceptState == TLS13_ACCEPT_SECOND_REPLY_DONE ||
ssl->options.acceptState == TLS13_SERVER_HELLO_SENT ||
ssl->options.acceptState == TLS13_ACCEPT_THIRD_REPLY_DONE ||
ssl->options.acceptState == TLS13_SERVER_EXTENSIONS_SENT ||
ssl->options.acceptState == TLS13_CERT_REQ_SENT ||
ssl->options.acceptState == TLS13_CERT_SENT ||
ssl->options.acceptState == TLS13_CERT_VERIFY_SENT ||
ssl->options.acceptState == TLS13_ACCEPT_FINISHED_SENT ||
ssl->options.acceptState == TLS13_ACCEPT_FINISHED_DONE) {
ssl->options.acceptState++;
WOLFSSL_MSG("accept state: "
"Advanced from last buffered fragment send");
}
}
else {
WOLFSSL_MSG("accept state: "

View File

@ -1856,9 +1856,11 @@ static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
static WC_INLINE void udp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
{
if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
SOCKADDR_IN_T addr;
build_addr(&addr, ip, port, 1, 0);
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
err_sys_with_errno("tcp connect failed");
}
@ -2052,7 +2054,7 @@ static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
err_sys_with_errno("tcp bind failed");
#if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS)
if (port == 0) {
socklen_t len = sizeof(addr);
if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
@ -2065,7 +2067,7 @@ static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd,
}
#endif
#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
/* signal ready to accept data */
{
tcp_ready* ready = args->signal;