]> git.meshlink.io Git - utcp/blobdiff - utcp.c
Log when we start retransmission.
[utcp] / utcp.c
diff --git a/utcp.c b/utcp.c
index 4f3510e8c0da3f8ee130e5089d23aa244f22cb0c..c21d6ab664b0146030c44d60e6feb730e924f0d8 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -358,6 +358,21 @@ static void update_rtt(struct utcp_connection *c, uint32_t rtt) {
        debug("rtt %u srtt %u rttvar %u rto %u\n", rtt, utcp->srtt, utcp->rttvar, utcp->rto);
 }
 
+static void start_retransmit_timer(struct utcp_connection *c) {
+       gettimeofday(&c->rtrx_timeout, NULL);
+       c->rtrx_timeout.tv_usec += c->utcp->rto;
+       while(c->rtrx_timeout.tv_usec >= 1000000) {
+               c->rtrx_timeout.tv_usec -= 1000000;
+               c->rtrx_timeout.tv_sec++;
+       }
+       debug("timeout set to %lu.%06lu (%u)\n", c->rtrx_timeout.tv_sec, c->rtrx_timeout.tv_usec, c->utcp->rto);
+}
+
+static void stop_retransmit_timer(struct utcp_connection *c) {
+       timerclear(&c->rtrx_timeout);
+       debug("timeout cleared\n");
+}
+
 struct utcp_connection *utcp_connect(struct utcp *utcp, uint16_t dst, utcp_recv_t recv, void *priv) {
        struct utcp_connection *c = allocate_connection(utcp, 0, dst);
        if(!c)
@@ -505,6 +520,8 @@ ssize_t utcp_send(struct utcp_connection *c, const void *data, size_t len) {
 
        c->snd.last += len;
        ack(c, false);
+       if(!timerisset(&c->rtrx_timeout))
+               start_retransmit_timer(c);
        return len;
 }
 
@@ -583,14 +600,17 @@ static void retransmit(struct utcp_connection *c) {
 #ifdef UTCP_DEBUG
                        abort();
 #endif
-                       timerclear(&c->rtrx_timeout);
-                       break;
+                       stop_retransmit_timer(c);
+                       goto cleanup;
        }
 
+       start_retransmit_timer(c);
        utcp->rto *= 2;
        if(utcp->rto > MAX_RTO)
                utcp->rto = MAX_RTO;
        c->rtt_start.tv_sec = 0; // invalidate RTT timer
+
+cleanup:
        free(pkt);
 }
 
@@ -859,10 +879,7 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
        // ackno should not roll back, and it should also not be bigger than what we ever could have sent
        // (= snd.una + c->sndbuf.used).
 
-       if(hdr.ctl & ACK &&
-                       ((seqdiff(hdr.ack, c->snd.una + c->sndbuf.used) > 0 &&
-                         seqdiff(hdr.ack, c->snd.nxt) > 0) // TODO: simplify this if
-                        || seqdiff(hdr.ack, c->snd.una) < 0)) {
+       if(hdr.ctl & ACK && (seqdiff(hdr.ack, c->snd.last) > 0 || seqdiff(hdr.ack, c->snd.una) < 0)) {
                debug("Packet ack seqno out of range, %u <= %u < %u\n", c->snd.una, hdr.ack, c->snd.una + c->sndbuf.used);
                // Ignore unacceptable RST packets.
                if(hdr.ctl & RST)
@@ -1008,8 +1025,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
 
        if(advanced) {
                timerclear(&c->conn_timeout); // It will be set anew in utcp_timeout() if c->snd.una != c->snd.nxt.
-               if(c->snd.una == c->snd.nxt)
-                       timerclear(&c->rtrx_timeout);
+               if(c->snd.una == c->snd.last)
+                       stop_retransmit_timer(c);
+               else
+                       start_retransmit_timer(c);
        }
 
        // 5. Process SYN stuff
@@ -1145,7 +1164,6 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
        // - or we got an ack, so we should maybe send a bit more data
        //   -> sendatleastone = false
 
-ack:
        ack(c, prevrcvnxt != c->rcv.nxt);
        return 0;
 
@@ -1303,6 +1321,7 @@ struct timeval utcp_timeout(struct utcp *utcp) {
                if(!c)
                        continue;
 
+               // delete connections that have been utcp_close()d.
                if(c->state == CLOSED) {
                        if(c->reapable) {
                                debug("Reaping %p\n", c);
@@ -1321,6 +1340,7 @@ struct timeval utcp_timeout(struct utcp *utcp) {
                }
 
                if(timerisset(&c->rtrx_timeout) && timercmp(&c->rtrx_timeout, &now, <)) {
+                       debug("retransmit()\n");
                        retransmit(c);
                }
 
@@ -1330,13 +1350,6 @@ struct timeval utcp_timeout(struct utcp *utcp) {
                if(timerisset(&c->conn_timeout) && timercmp(&c->conn_timeout, &next, <))
                        next = c->conn_timeout;
 
-               if(c->snd.nxt != c->snd.una) {
-                       c->rtrx_timeout = now;
-                       c->rtrx_timeout.tv_sec++;
-               } else {
-                       timerclear(&c->rtrx_timeout);
-               }
-
                if(timerisset(&c->rtrx_timeout) && timercmp(&c->rtrx_timeout, &next, <))
                        next = c->rtrx_timeout;
        }