From d03c0d4145b42faaf236443ea59b906bd8f5f2fb Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Tue, 15 Apr 2025 09:18:48 +0100 Subject: [PATCH] DTLS: Detect connection issues Supports upstream reconnection attempt detections. --- src/coap_gnutls.c | 2 ++ src/coap_mbedtls.c | 2 ++ src/coap_openssl.c | 5 ++++- src/coap_tinydtls.c | 7 +++++-- src/coap_wolfssl.c | 4 ++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/coap_gnutls.c b/src/coap_gnutls.c index c0e41bb6..cc682993 100644 --- a/src/coap_gnutls.c +++ b/src/coap_gnutls.c @@ -2052,6 +2052,8 @@ coap_dgram_write(gnutls_transport_ptr_t context, const void *send_buffer, result, send_buffer_length); errno = keep_errno; if (result < 0) { + if (errno == ENOTCONN || errno == ECONNREFUSED) + c_session->dtls_event = COAP_EVENT_DTLS_ERROR; return -1; } else { result = 0; diff --git a/src/coap_mbedtls.c b/src/coap_mbedtls.c index d60cc6a7..ee34a59f 100644 --- a/src/coap_mbedtls.c +++ b/src/coap_mbedtls.c @@ -251,6 +251,8 @@ coap_dgram_write(void *ctx, const unsigned char *send_buffer, result, send_buffer_length); errno = keep_errno; if (result < 0) { + if (errno == ENOTCONN || errno == ECONNREFUSED) + c_session->dtls_event = COAP_EVENT_DTLS_ERROR; return -1; } else { result = 0; diff --git a/src/coap_openssl.c b/src/coap_openssl.c index f15d7af7..382f18c4 100644 --- a/src/coap_openssl.c +++ b/src/coap_openssl.c @@ -636,8 +636,11 @@ coap_dgram_write(BIO *a, const char *in, int inl) { (const uint8_t *)in, inl); BIO_clear_retry_flags(a); - if (ret <= 0) + if (ret <= 0) { + if (ret < 0 && (errno == ENOTCONN || errno == ECONNREFUSED)) + data->session->dtls_event = COAP_EVENT_DTLS_ERROR; BIO_set_retry_write(a); + } } else { BIO_clear_retry_flags(a); ret = -1; diff --git a/src/coap_tinydtls.c b/src/coap_tinydtls.c index d8c6b11e..6e8d2f8a 100644 --- a/src/coap_tinydtls.c +++ b/src/coap_tinydtls.c @@ -365,6 +365,7 @@ dtls_send_to_peer(struct dtls_context_t *dtls_context, coap_context_t *coap_context = t_context ? t_context->coap_context : NULL; coap_session_t *coap_session; coap_address_t remote_addr; + int ret; assert(coap_context); get_session_addr(dtls_session, &remote_addr); @@ -373,8 +374,10 @@ dtls_send_to_peer(struct dtls_context_t *dtls_context, coap_log_warn("dtls_send_to_peer: cannot find local interface\n"); return -3; } - return (int)coap_session->sock.lfunc[COAP_LAYER_TLS].l_write(coap_session, - data, len); + ret = (int)coap_session->sock.lfunc[COAP_LAYER_TLS].l_write(coap_session, data, len); + if (ret == -1 && (errno == ENOTCONN || errno == ECONNREFUSED)) + coap_session->dtls_event = COAP_EVENT_DTLS_ERROR; + return ret; } static int diff --git a/src/coap_wolfssl.c b/src/coap_wolfssl.c index aee215b0..08a403d5 100644 --- a/src/coap_wolfssl.c +++ b/src/coap_wolfssl.c @@ -559,6 +559,9 @@ coap_dgram_write(WOLFSSL *ssl, char *in, int inl, void *ctx) { if (ret > 0) { coap_ticks(&now); w_env->last_timeout = now; + } else if (ret < 0) { + if (errno == ENOTCONN || errno == ECONNREFUSED) + data->session->dtls_event = COAP_EVENT_DTLS_ERROR; } } else { ret = -1; @@ -2218,6 +2221,7 @@ coap_dtls_free_session(coap_session_t *session) { coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CLOSED, session); } coap_dtls_free_wolfssl_env(w_env); + session->tls = NULL; } ssize_t