From 0f5ab29d787c7fb444908797d5ea746cb4311be4 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 15 Apr 2021 19:50:20 +0200 Subject: [PATCH] Fix buffer shrinking logic in UTCP. Don't set the maximum size to low values; keep it at the minimum of the previous size or of the default maximum size. If it is set to something smaller than one MTU, this would prevent receiving packets from the peer, and channel traffic would not progress and not close properly. We also don't move memory when shrinking the internal buffer, so we should keep the size large enough so the last byte in the buffer is covered when the offset is non-zero. --- src/utcp.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/utcp.c b/src/utcp.c index c21e7067..8b3509ef 100644 --- a/src/utcp.c +++ b/src/utcp.c @@ -470,8 +470,13 @@ static void set_buffer_storage(struct buffer *buf, char *data, size_t size) { buf->external = false; } else { + // Don't do anything if the buffer wraps + if(buffer_wraps(buf)) { + return; + } + // Realloc internal storage - size_t minsize = buf->used <= DEFAULT_SNDBUFSIZE ? DEFAULT_SNDBUFSIZE : buf->used; + size_t minsize = max(DEFAULT_SNDBUFSIZE, buf->offset + buf->used); if(minsize) { data = realloc(buf->data, minsize); @@ -2108,8 +2113,8 @@ static bool reset_connection(struct utcp_connection *c) { } static void set_reapable(struct utcp_connection *c) { - set_buffer_storage(&c->sndbuf, NULL, DEFAULT_MTU); - set_buffer_storage(&c->rcvbuf, NULL, DEFAULT_MTU); + set_buffer_storage(&c->sndbuf, NULL, min(c->sndbuf.maxsize, DEFAULT_MAXSNDBUFSIZE)); + set_buffer_storage(&c->rcvbuf, NULL, min(c->rcvbuf.maxsize, DEFAULT_MAXRCVBUFSIZE)); c->recv = NULL; c->poll = NULL; -- 2.39.2