]> git.meshlink.io Git - utcp/commitdiff
Prevent FIN bit from being sent too early.
authorGuus Sliepen <guus@meshlink.io>
Mon, 8 Dec 2014 15:18:30 +0000 (16:18 +0100)
committerGuus Sliepen <guus@meshlink.io>
Mon, 8 Dec 2014 15:18:30 +0000 (16:18 +0100)
Due to a logic bug in ack(), the FIN bit could be set on a too early packet,
if utcp_shutdown() was called with a full send buffer.

utcp.c

diff --git a/utcp.c b/utcp.c
index 186b63e90bba16798f7fe4d897c40e4c554cfd19..1d8f4b2a9e3a7865e8813d9032d6510b51cb3a8c 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -366,7 +366,7 @@ static void ack(struct utcp_connection *c, bool sendatleastone) {
                c->snd.nxt += seglen;
                left -= seglen;
 
-               if(c->state != ESTABLISHED && !left && seglen) {
+               if(c->state != ESTABLISHED && seglen && c->snd.nxt == c->snd.last) {
                        switch(c->state) {
                        case FIN_WAIT_1:
                        case CLOSING:
@@ -954,7 +954,7 @@ reset:
 }
 
 int utcp_shutdown(struct utcp_connection *c, int dir) {
-       debug("%p shutdown %d\n", c ? c->utcp : NULL, dir);
+       debug("%p shutdown %d at %u\n", c ? c->utcp : NULL, dir, c->snd.last);
        if(!c) {
                errno = EFAULT;
                return -1;
@@ -967,6 +967,7 @@ int utcp_shutdown(struct utcp_connection *c, int dir) {
        }
 
        // TODO: handle dir
+       // TODO: check that repeated calls with the same parameters should have no effect
 
        switch(c->state) {
        case CLOSED: