mirror of https://github.com/wolfSSL/wolfssl.git
DTLS fixes with WANT_WRITE simulations
- WANT_WRITE could be returned in unexpected places. This patch takes care of that. - Change state after SendBuffered only if in a sending state to begin with. - Adapt client and server to simulate WANT_WRITE with DTLSpull/5084/head
parent
798d81723b
commit
a31b76878f
|
@ -232,9 +232,12 @@ static int NonBlockingSSL_Connect(WOLFSSL* ssl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
|
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl)) {
|
||||||
wolfSSL_dtls_got_timeout(ssl) >= 0) {
|
ret = wolfSSL_dtls_got_timeout(ssl);
|
||||||
error = WOLFSSL_ERROR_WANT_READ;
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
error = wolfSSL_get_error(ssl, ret);
|
||||||
|
else
|
||||||
|
error = WOLFSSL_ERROR_WANT_READ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
|
@ -3561,6 +3564,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||||
err_sys("error in setting fd");
|
err_sys("error in setting fd");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (simulateWantWrite) {
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl, (void*)&sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
/* STARTTLS */
|
/* STARTTLS */
|
||||||
if (doSTARTTLS) {
|
if (doSTARTTLS) {
|
||||||
if (StartTLS_Init(&sockfd) != WOLFSSL_SUCCESS) {
|
if (StartTLS_Init(&sockfd) != WOLFSSL_SUCCESS) {
|
||||||
|
|
|
@ -354,9 +354,12 @@ static int NonBlockingSSL_Accept(SSL* ssl)
|
||||||
error = WOLFSSL_ERROR_WANT_READ;
|
error = WOLFSSL_ERROR_WANT_READ;
|
||||||
}
|
}
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
|
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl)) {
|
||||||
wolfSSL_dtls_got_timeout(ssl) >= 0) {
|
ret = wolfSSL_dtls_got_timeout(ssl);
|
||||||
error = WOLFSSL_ERROR_WANT_READ;
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
error = wolfSSL_get_error(ssl, ret);
|
||||||
|
else
|
||||||
|
error = WOLFSSL_ERROR_WANT_READ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
|
@ -2958,6 +2961,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||||
else {
|
else {
|
||||||
wolfSSL_dtls_set_peer(ssl, &client_addr, client_len);
|
wolfSSL_dtls_set_peer(ssl, &client_addr, client_len);
|
||||||
}
|
}
|
||||||
|
if (simulateWantWrite) {
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
|
|
@ -8883,9 +8883,8 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
|
||||||
dataSz += DTLS_HANDSHAKE_HEADER_SZ;
|
dataSz += DTLS_HANDSHAKE_HEADER_SZ;
|
||||||
AddHandShakeHeader(data,
|
AddHandShakeHeader(data,
|
||||||
inputSz, ssl->fragOffset, fragSz, type, ssl);
|
inputSz, ssl->fragOffset, fragSz, type, ssl);
|
||||||
}
|
|
||||||
if (ssl->options.dtls)
|
|
||||||
ssl->keys.dtls_handshake_number--;
|
ssl->keys.dtls_handshake_number--;
|
||||||
|
}
|
||||||
if (IsDtlsNotSctpMode(ssl) &&
|
if (IsDtlsNotSctpMode(ssl) &&
|
||||||
(ret = DtlsMsgPoolSave(ssl, data,
|
(ret = DtlsMsgPoolSave(ssl, data,
|
||||||
fragSz + DTLS_HANDSHAKE_HEADER_SZ, type))
|
fragSz + DTLS_HANDSHAKE_HEADER_SZ, type))
|
||||||
|
@ -17479,6 +17478,11 @@ int ProcessReplyEx(WOLFSSL* ssl, int allowSocketErr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (ret != 0
|
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
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||||
/* In async case, on pending, move onto next message.
|
/* In async case, on pending, move onto next message.
|
||||||
* Current message should have been DtlsMsgStore'ed and
|
* Current message should have been DtlsMsgStore'ed and
|
||||||
|
@ -26783,6 +26787,12 @@ int SendCertificateVerify(WOLFSSL* ssl)
|
||||||
if (args->output == NULL) {
|
if (args->output == NULL) {
|
||||||
ERROR_OUT(BUFFER_ERROR, exit_scv);
|
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 +
|
AddHeaders(args->output, (word32)args->length + args->extraSz +
|
||||||
VERIFY_HEADER, certificate_verify, ssl);
|
VERIFY_HEADER, certificate_verify, ssl);
|
||||||
|
|
||||||
|
@ -28871,6 +28881,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
|
|
||||||
case TLS_ASYNC_FINALIZE:
|
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) || \
|
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
|
||||||
defined(HAVE_CURVE448)
|
defined(HAVE_CURVE448)
|
||||||
if (ssl->specs.kea == ecdhe_psk_kea ||
|
if (ssl->specs.kea == ecdhe_psk_kea ||
|
||||||
|
|
30
src/ssl.c
30
src/ssl.c
|
@ -11836,9 +11836,17 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||||
* fragment, fragOffset is zero again, and the state can be
|
* fragment, fragOffset is zero again, and the state can be
|
||||||
* advanced. */
|
* advanced. */
|
||||||
if (ssl->fragOffset == 0) {
|
if (ssl->fragOffset == 0) {
|
||||||
ssl->options.connectState++;
|
if (ssl->options.connectState == CONNECT_BEGIN ||
|
||||||
WOLFSSL_MSG("connect state: "
|
ssl->options.connectState == HELLO_AGAIN ||
|
||||||
"Advanced from last buffered fragment send");
|
ssl->options.connectState == FIRST_REPLY_DONE ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_FIRST ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_SECOND ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_THIRD ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_FOURTH) {
|
||||||
|
ssl->options.connectState++;
|
||||||
|
WOLFSSL_MSG("connect state: "
|
||||||
|
"Advanced from last buffered fragment send");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("connect state: "
|
WOLFSSL_MSG("connect state: "
|
||||||
|
@ -12303,9 +12311,19 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
||||||
* fragment, fragOffset is zero again, and the state can be
|
* fragment, fragOffset is zero again, and the state can be
|
||||||
* advanced. */
|
* advanced. */
|
||||||
if (ssl->fragOffset == 0) {
|
if (ssl->fragOffset == 0) {
|
||||||
ssl->options.acceptState++;
|
if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
|
||||||
WOLFSSL_MSG("accept state: "
|
ssl->options.acceptState == SERVER_HELLO_SENT ||
|
||||||
"Advanced from last buffered fragment send");
|
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 {
|
else {
|
||||||
WOLFSSL_MSG("accept state: "
|
WOLFSSL_MSG("accept state: "
|
||||||
|
|
34
src/tls13.c
34
src/tls13.c
|
@ -8637,9 +8637,18 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||||
* fragment, fragOffset is zero again, and the state can be
|
* fragment, fragOffset is zero again, and the state can be
|
||||||
* advanced. */
|
* advanced. */
|
||||||
if (ssl->fragOffset == 0) {
|
if (ssl->fragOffset == 0) {
|
||||||
ssl->options.connectState++;
|
/* Only increment from states in which we send data */
|
||||||
WOLFSSL_MSG("connect state: "
|
if (ssl->options.connectState == CONNECT_BEGIN ||
|
||||||
"Advanced from last buffered fragment send");
|
ssl->options.connectState == HELLO_AGAIN ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_DONE ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_FIRST ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_SECOND ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_THIRD ||
|
||||||
|
ssl->options.connectState == FIRST_REPLY_FOURTH) {
|
||||||
|
ssl->options.connectState++;
|
||||||
|
WOLFSSL_MSG("connect state: "
|
||||||
|
"Advanced from last buffered fragment send");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("connect state: "
|
WOLFSSL_MSG("connect state: "
|
||||||
|
@ -9592,9 +9601,22 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
|
||||||
* fragment, fragOffset is zero again, and the state can be
|
* fragment, fragOffset is zero again, and the state can be
|
||||||
* advanced. */
|
* advanced. */
|
||||||
if (ssl->fragOffset == 0) {
|
if (ssl->fragOffset == 0) {
|
||||||
ssl->options.acceptState++;
|
/* Only increment from states in which we send data */
|
||||||
WOLFSSL_MSG("accept state: "
|
if (ssl->options.acceptState == TLS13_ACCEPT_CLIENT_HELLO_DONE ||
|
||||||
"Advanced from last buffered fragment send");
|
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 {
|
else {
|
||||||
WOLFSSL_MSG("accept state: "
|
WOLFSSL_MSG("accept state: "
|
||||||
|
|
|
@ -1847,10 +1847,8 @@ static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
|
||||||
}
|
}
|
||||||
tcp_socket(sockfd, udp, sctp);
|
tcp_socket(sockfd, udp, sctp);
|
||||||
|
|
||||||
if (!udp) {
|
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
|
||||||
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
|
err_sys_with_errno("tcp connect failed");
|
||||||
err_sys_with_errno("tcp connect failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
|
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
|
||||||
|
|
Loading…
Reference in New Issue