diff --git a/mongoose.c b/mongoose.c index 27673eb4..daf8205e 100644 --- a/mongoose.c +++ b/mongoose.c @@ -7529,9 +7529,13 @@ static void read_conn(struct mg_connection *c) { if (!ioalloc(c, &c->rtls)) return; n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], c->rtls.size - c->rtls.len); - if (n == MG_IO_ERR && mg_tls_pending(c) == 0) { - // Close only if we have fully drained both raw (rtls) and TLS buffers - c->is_closing = 1; + if (n == MG_IO_ERR) { + if (c->rtls.len == 0 || c->is_io_err) { + // Close only when we have fully drained both rtls and TLS buffers + c->is_closing = 1; // or there's nothing we can do about it. + } else { // TLS buffer is capped to max record size, mark and + c->is_io_err = 1; // give TLS a chance to process that. + } } else { if (n > 0) c->rtls.len += (size_t) n; if (c->is_tls_hs) mg_tls_handshake(c); diff --git a/mongoose.h b/mongoose.h index 86de9e8c..a4e34926 100644 --- a/mongoose.h +++ b/mongoose.h @@ -2157,6 +2157,7 @@ struct mg_connection { unsigned is_resp : 1; // Response is still being generated unsigned is_readable : 1; // Connection is ready to read unsigned is_writable : 1; // Connection is ready to write + unsigned is_io_err : 1; // Remember IO_ERR condition for later use }; void mg_mgr_poll(struct mg_mgr *, int ms); diff --git a/src/net.h b/src/net.h index 679dc5b2..c59f6216 100644 --- a/src/net.h +++ b/src/net.h @@ -76,6 +76,7 @@ struct mg_connection { unsigned is_resp : 1; // Response is still being generated unsigned is_readable : 1; // Connection is ready to read unsigned is_writable : 1; // Connection is ready to write + unsigned is_io_err : 1; // Remember IO_ERR condition for later use }; void mg_mgr_poll(struct mg_mgr *, int ms); diff --git a/src/sock.c b/src/sock.c index 0805adaf..fcc66eeb 100644 --- a/src/sock.c +++ b/src/sock.c @@ -282,9 +282,13 @@ static void read_conn(struct mg_connection *c) { if (!ioalloc(c, &c->rtls)) return; n = recv_raw(c, (char *) &c->rtls.buf[c->rtls.len], c->rtls.size - c->rtls.len); - if (n == MG_IO_ERR && mg_tls_pending(c) == 0) { - // Close only if we have fully drained both raw (rtls) and TLS buffers - c->is_closing = 1; + if (n == MG_IO_ERR) { + if (c->rtls.len == 0 || c->is_io_err) { + // Close only when we have fully drained both rtls and TLS buffers + c->is_closing = 1; // or there's nothing we can do about it. + } else { // TLS buffer is capped to max record size, mark and + c->is_io_err = 1; // give TLS a chance to process that. + } } else { if (n > 0) c->rtls.len += (size_t) n; if (c->is_tls_hs) mg_tls_handshake(c);