]> git.meshlink.io Git - meshlink/commitdiff
Fix buffer shrinking logic in UTCP.
authorGuus Sliepen <guus@meshlink.io>
Thu, 15 Apr 2021 17:50:20 +0000 (19:50 +0200)
committerGuus Sliepen <guus@meshlink.io>
Thu, 15 Apr 2021 18:25:29 +0000 (20:25 +0200)
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

index c21e7067b89610c17182eae3dce57b58a9dfa274..8b3509ef0f5c376ee7b37640cb3c82dba1819df4 100644 (file)
@@ -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;