From 3ec17c41be728b9ee0c58316b28775ef6fce5fdf Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Sat, 2 Apr 2022 14:43:13 -0600 Subject: [PATCH] Handle MBEDTLS_ERR_NET_CONN_RESET errors --- mongoose.c | 29 +++++++++++++++++++++++------ src/sock.c | 10 ++++++++++ src/tls_mbed.c | 19 +++++++++++++------ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/mongoose.c b/mongoose.c index c3f624ef..6770093e 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3217,6 +3217,16 @@ bool mg_sock_would_block(void) { ; } +bool mg_sock_conn_reset(void); +bool mg_sock_conn_reset(void) { + int err = MG_SOCK_ERRNO; +#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK + return err == WSAECONNRESET; +#else + return err == EPIPE || err == ECONNRESET; +#endif +} + static void iolog(struct mg_connection *c, char *buf, long n, bool r) { if (n == 0) { // Do nothing @@ -4264,15 +4274,19 @@ void mg_tls_free(struct mg_connection *c) { } bool mg_sock_would_block(void); +bool mg_sock_conn_reset(void); static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) { struct mg_connection *c = (struct mg_connection *) ctx; int fd = (int) (size_t) c->fd; int n = (int) send(fd, buf, len, 0); MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno)); - if (n > 0) return n; - if (n < 0 && mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_WRITE; - return MBEDTLS_ERR_NET_SEND_FAILED; + if (n < 0) { + if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_WRITE; + if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET; + return MBEDTLS_ERR_NET_SEND_FAILED; + } + return n; } static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) { @@ -4280,9 +4294,12 @@ static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) { int n, fd = (int) (size_t) c->fd; n = (int) recv(fd, buf, len, 0); MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno)); - if (n > 0) return n; - if (n < 0 && mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_READ; - return MBEDTLS_ERR_NET_RECV_FAILED; + if (n < 0) { + if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_READ; + if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET; + return MBEDTLS_ERR_NET_RECV_FAILED; + } + return n; } void mg_tls_handshake(struct mg_connection *c) { diff --git a/src/sock.c b/src/sock.c index ce774fb9..49cdf339 100644 --- a/src/sock.c +++ b/src/sock.c @@ -88,6 +88,16 @@ bool mg_sock_would_block(void) { ; } +bool mg_sock_conn_reset(void); +bool mg_sock_conn_reset(void) { + int err = MG_SOCK_ERRNO; +#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK + return err == WSAECONNRESET; +#else + return err == EPIPE || err == ECONNRESET; +#endif +} + static void iolog(struct mg_connection *c, char *buf, long n, bool r) { if (n == 0) { // Do nothing diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 2391c33c..de9cbff5 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -24,15 +24,19 @@ void mg_tls_free(struct mg_connection *c) { } bool mg_sock_would_block(void); +bool mg_sock_conn_reset(void); static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) { struct mg_connection *c = (struct mg_connection *) ctx; int fd = (int) (size_t) c->fd; int n = (int) send(fd, buf, len, 0); MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno)); - if (n > 0) return n; - if (n < 0 && mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_WRITE; - return MBEDTLS_ERR_NET_SEND_FAILED; + if (n < 0) { + if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_WRITE; + if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET; + return MBEDTLS_ERR_NET_SEND_FAILED; + } + return n; } static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) { @@ -40,9 +44,12 @@ static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) { int n, fd = (int) (size_t) c->fd; n = (int) recv(fd, buf, len, 0); MG_VERBOSE(("%lu n=%d, errno=%d", c->id, n, errno)); - if (n > 0) return n; - if (n < 0 && mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_READ; - return MBEDTLS_ERR_NET_RECV_FAILED; + if (n < 0) { + if (mg_sock_would_block()) return MBEDTLS_ERR_SSL_WANT_READ; + if (mg_sock_conn_reset()) return MBEDTLS_ERR_NET_CONN_RESET; + return MBEDTLS_ERR_NET_RECV_FAILED; + } + return n; } void mg_tls_handshake(struct mg_connection *c) {