]> git.meshlink.io Git - utcp/blobdiff - utcp.c
Add fin_wanted() function that checks whether a FIN bit should be set on a packet.
[utcp] / utcp.c
diff --git a/utcp.c b/utcp.c
index 21fbea6c4eea4df28380098bdff43edb33441775..f062319fa33a1daa665faaa96f3c567eb488f245 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -103,6 +103,19 @@ static void set_state(struct utcp_connection *c, enum state state) {
        debug("%p new state: %s\n", c->utcp, strstate[state]);
 }
 
+static bool fin_wanted(struct utcp_connection *c, uint32_t seq) {
+       if(seq != c->snd.last)
+               return false;
+       switch(c->state) {
+       case FIN_WAIT_1:
+       case CLOSING:
+       case LAST_ACK:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static inline void list_connections(struct utcp *utcp) {
        debug("%p has %d connections:\n", utcp, utcp->nconnections);
        for(int i = 0; i < utcp->nconnections; i++)
@@ -366,16 +379,9 @@ static void ack(struct utcp_connection *c, bool sendatleastone) {
                c->snd.nxt += seglen;
                left -= seglen;
 
-               if(c->state != ESTABLISHED && seglen && c->snd.nxt == c->snd.last) {
-                       switch(c->state) {
-                       case FIN_WAIT_1:
-                       case CLOSING:
-                               seglen--;
-                               pkt->hdr.ctl |= FIN;
-                               break;
-                       default:
-                               break;
-                       }
+               if(seglen && fin_wanted(c, c->snd.nxt)) {
+                       seglen--;
+                       pkt->hdr.ctl |= FIN;
                }
 
                print_packet(c->utcp, "send", pkt, sizeof pkt->hdr + seglen);
@@ -501,7 +507,10 @@ static void retransmit(struct utcp_connection *c) {
 
                default:
                        // TODO: implement
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       break;
        }
 
        free(pkt);
@@ -623,7 +632,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
        case TIME_WAIT:
                break;
        default:
+#ifdef UTCP_DEBUG
                abort();
+#endif
+               break;
        }
 
        // 1b. Drop packets with a sequence number not in our receive window.
@@ -723,7 +735,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                        set_state(c, CLOSED);
                        return 0;
                default:
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       break;
                }
        }
 
@@ -822,7 +837,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                        // Ehm, no. We should never receive a second SYN.
                        goto reset;
                default:
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       return 0;
                }
 
                // SYN counts as one sequence number
@@ -852,7 +870,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                case SYN_SENT:
                case SYN_RECEIVED:
                        // This should never happen.
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       return 0;
                case ESTABLISHED:
                case FIN_WAIT_1:
                case FIN_WAIT_2:
@@ -864,7 +885,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                        // Ehm no, We should never receive more data after a FIN.
                        goto reset;
                default:
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       return 0;
                }
 
                ssize_t rxd;
@@ -893,7 +917,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                case SYN_SENT:
                case SYN_RECEIVED:
                        // This should never happen.
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       break;
                case ESTABLISHED:
                        set_state(c, CLOSE_WAIT);
                        break;
@@ -912,7 +939,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                        // Ehm, no. We should never receive a second FIN.
                        goto reset;
                default:
+#ifdef UTCP_DEBUG
                        abort();
+#endif
+                       break;
                }
 
                // FIN counts as one sequence number