From 416dc7beae907cf99b51dfeef3800fcfb9a34973 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Fri, 5 Jun 2026 16:59:44 -0300 Subject: [PATCH] fix no room --- mongoose.c | 13 ++++++++----- src/net_builtin.c | 9 ++++++--- src/tls_mbed.c | 2 +- src/tls_openssl.c | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/mongoose.c b/mongoose.c index c8b91d25..4ebfe2f8 100644 --- a/mongoose.c +++ b/mongoose.c @@ -8712,13 +8712,16 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) { } static void handle_tls_recv(struct mg_connection *c) { - size_t avail = mg_tls_pending(c); + size_t avail = mg_tls_pending(c); // will change after mg_tls_recv() size_t min = avail > MG_MAX_RECV_SIZE ? MG_MAX_RECV_SIZE : avail; - struct mg_iobuf *io = &c->recv; + struct mg_iobuf *io = &c->recv; // allocated on first avail > 0 if (io->size - io->len < min && !mg_iobuf_resize(io, io->len + min)) { mg_error(c, "oom"); } else { - // Decrypt data directly into c->recv + // Decrypt data directly into c->recv. If io->buf = NULL or + // io->len = io->size (no room), there can be outstanding data that can't be + // moved (mg_tls_pending() > 0 after mg_tls_recv() returns). So mg_tls_recv() + // takes care of returning 0 in this case (commented as "MIP") long n = mg_tls_recv(c, io->buf != NULL ? &io->buf[io->len] : io->buf, io->size - io->len); if (n == MG_IO_ERR) { @@ -19631,7 +19634,7 @@ size_t mg_tls_pending(struct mg_connection *c) { long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) { struct mg_tls *tls = (struct mg_tls *) c->tls; long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len); - if (!c->is_tls_hs && buf == NULL && n == 0) return 0; // TODO(): MIP + if (!c->is_tls_hs && (buf == NULL || len == 0) && n == 0) return 0; // MIP if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_IO_WAIT; #if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) @@ -20027,7 +20030,7 @@ size_t mg_tls_pending(struct mg_connection *c) { long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) { struct mg_tls *tls = (struct mg_tls *) c->tls; int n = SSL_read(tls->ssl, buf, (int) len); - if (!c->is_tls_hs && buf == NULL && n == 0) return 0; // TODO(): MIP + if (!c->is_tls_hs && (buf == NULL || len == 0) && n == 0) return 0; // MIP if (n < 0 && mg_tls_err(c, tls, n) == 0) return MG_IO_WAIT; if (n <= 0) return MG_IO_ERR; return n; diff --git a/src/net_builtin.c b/src/net_builtin.c index de8907a9..8ee87d26 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -1403,13 +1403,16 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) { } static void handle_tls_recv(struct mg_connection *c) { - size_t avail = mg_tls_pending(c); + size_t avail = mg_tls_pending(c); // will change after mg_tls_recv() size_t min = avail > MG_MAX_RECV_SIZE ? MG_MAX_RECV_SIZE : avail; - struct mg_iobuf *io = &c->recv; + struct mg_iobuf *io = &c->recv; // allocated on first avail > 0 if (io->size - io->len < min && !mg_iobuf_resize(io, io->len + min)) { mg_error(c, "oom"); } else { - // Decrypt data directly into c->recv + // Decrypt data directly into c->recv. If io->buf = NULL or + // io->len = io->size (no room), there can be outstanding data that can't be + // moved (mg_tls_pending() > 0 after mg_tls_recv() returns). So mg_tls_recv() + // takes care of returning 0 in this case (commented as "MIP") long n = mg_tls_recv(c, io->buf != NULL ? &io->buf[io->len] : io->buf, io->size - io->len); if (n == MG_IO_ERR) { diff --git a/src/tls_mbed.c b/src/tls_mbed.c index 1bee87a0..19778d2b 100644 --- a/src/tls_mbed.c +++ b/src/tls_mbed.c @@ -201,7 +201,7 @@ size_t mg_tls_pending(struct mg_connection *c) { long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) { struct mg_tls *tls = (struct mg_tls *) c->tls; long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len); - if (!c->is_tls_hs && buf == NULL && n == 0) return 0; // TODO(): MIP + if (!c->is_tls_hs && (buf == NULL || len == 0) && n == 0) return 0; // MIP if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_IO_WAIT; #if defined(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 6faaf0b6..c64f70b4 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -293,7 +293,7 @@ size_t mg_tls_pending(struct mg_connection *c) { long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) { struct mg_tls *tls = (struct mg_tls *) c->tls; int n = SSL_read(tls->ssl, buf, (int) len); - if (!c->is_tls_hs && buf == NULL && n == 0) return 0; // TODO(): MIP + if (!c->is_tls_hs && (buf == NULL || len == 0) && n == 0) return 0; // MIP if (n < 0 && mg_tls_err(c, tls, n) == 0) return MG_IO_WAIT; if (n <= 0) return MG_IO_ERR; return n;