]> git.meshlink.io Git - utcp/blobdiff - utcp.c
Handle FIN_WAIT_1 state when retransmitting.
[utcp] / utcp.c
diff --git a/utcp.c b/utcp.c
index 436c9e8cdcd4703e39e88401fe35fa02a47c0934..65885287f599631b045c563b2564ef3301a893d3 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -346,10 +346,26 @@ ssize_t utcp_send(struct utcp_connection *c, const void *data, size_t len) {
 
        uint32_t bufused = c->snd.nxt - c->snd.una;
 
+       /* Check our send buffer.
+        * - If it's big enough, just put the data in there.
+        * - If not, decide whether to enlarge. (TODO, now we just always enlarge)
+        * - Cap len so it doesn't overflow our buffer.
+        */
+
+       if(len > c->sndbufsize - bufused) {
+               c->sndbufsize *= 2;
+               c->sndbuf = realloc(c->sndbuf, c->sndbufsize);
+       }
+
        if(len > c->sndbufsize - bufused)
                len = c->sndbufsize - bufused;
 
-       memcpy(c->sndbuf + (c->snd.nxt - c->snd.una), data, len);
+       if(!len) {
+               errno == EWOULDBLOCK;
+               return 0;
+       }
+
+       memcpy(c->sndbuf + bufused, data, len);
 
        // Send segments
 
@@ -938,12 +954,19 @@ static void retransmit(struct utcp_connection *c) {
                        break;
 
                case ESTABLISHED:
+               case FIN_WAIT_1:
                        pkt.hdr.seq = c->snd.una;
                        pkt.hdr.ack = c->rcv.nxt;
                        pkt.hdr.ctl = ACK;
                        uint32_t len = seqdiff(c->snd.nxt, c->snd.una);
+                       if(c->state == FIN_WAIT_1)
+                               len--;
                        if(len > utcp->mtu)
                                len = utcp->mtu;
+                       else {
+                               if(c->state == FIN_WAIT_1)
+                                       pkt.hdr.ctl |= FIN;
+                       }
                        memcpy(pkt.data, c->sndbuf, len);
                        print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr + len);
                        utcp->send(utcp, &pkt, sizeof pkt.hdr + len);