]> git.meshlink.io Git - utcp/blobdiff - utcp.c
Always announce the receive window size as the size of the receive buffer.
[utcp] / utcp.c
diff --git a/utcp.c b/utcp.c
index ac162fe708a0d657abffb4cb62ecd4881a7fc79a..d2a777ce00ed9b1d9ea18a622f1ab1523dcc74b5 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -382,7 +382,6 @@ static struct utcp_connection *allocate_connection(struct utcp *utcp, uint16_t s
 #endif
        c->snd.una = c->snd.iss;
        c->snd.nxt = c->snd.iss + 1;
-       c->rcv.wnd = utcp->mtu;
        c->snd.last = c->snd.nxt;
        c->snd.cwnd = utcp->mtu;
        c->utcp = utcp;
@@ -415,13 +414,13 @@ static void update_rtt(struct utcp_connection *c, uint32_t rtt) {
        if(!utcp->srtt) {
                utcp->srtt = rtt;
                utcp->rttvar = rtt / 2;
-               utcp->rto = rtt + max(2 * rtt, CLOCK_GRANULARITY);
        } else {
                utcp->rttvar = (utcp->rttvar * 3 + absdiff(utcp->srtt, rtt)) / 4;
                utcp->srtt = (utcp->srtt * 7 + rtt) / 8;
-               utcp->rto = utcp->srtt + max(utcp->rttvar, CLOCK_GRANULARITY);
        }
 
+       utcp->rto = utcp->srtt + max(4 * utcp->rttvar, CLOCK_GRANULARITY);
+
        if(utcp->rto > MAX_RTO) {
                utcp->rto = MAX_RTO;
        }
@@ -468,7 +467,7 @@ struct utcp_connection *utcp_connect_ex(struct utcp *utcp, uint16_t dst, utcp_re
        pkt.hdr.dst = c->dst;
        pkt.hdr.seq = c->snd.iss;
        pkt.hdr.ack = 0;
-       pkt.hdr.wnd = c->rcv.wnd;
+       pkt.hdr.wnd = c->rcvbuf.maxsize;
        pkt.hdr.ctl = SYN;
        pkt.hdr.aux = 0x0101;
        pkt.init[0] = 1;
@@ -538,7 +537,7 @@ static void ack(struct utcp_connection *c, bool sendatleastone) {
        pkt->hdr.src = c->src;
        pkt->hdr.dst = c->dst;
        pkt->hdr.ack = c->rcv.nxt;
-       pkt->hdr.wnd = c->snd.wnd;
+       pkt->hdr.wnd = c->rcvbuf.maxsize;
        pkt->hdr.ctl = ACK;
        pkt->hdr.aux = 0;
 
@@ -629,6 +628,8 @@ ssize_t utcp_send(struct utcp_connection *c, const void *data, size_t len) {
 
        if(is_reliable(c) || (c->state != SYN_SENT && c->state != SYN_RECEIVED)) {
                len = buffer_put(&c->sndbuf, data, len);
+       } else {
+               return 0;
        }
 
        if(len <= 0) {
@@ -695,7 +696,7 @@ static void retransmit(struct utcp_connection *c) {
 
        pkt->hdr.src = c->src;
        pkt->hdr.dst = c->dst;
-       pkt->hdr.wnd = c->rcv.wnd;
+       pkt->hdr.wnd = c->rcvbuf.maxsize;
        pkt->hdr.aux = 0;
 
        switch(c->state) {
@@ -1055,6 +1056,7 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                                c->flags = UTCP_TCP;
                        }
 
+synack:
                        // Return SYN+ACK, go to SYN_RECEIVED state
                        c->snd.wnd = hdr.wnd;
                        c->rcv.irs = hdr.seq;
@@ -1070,7 +1072,7 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                        pkt.hdr.dst = c->dst;
                        pkt.hdr.ack = c->rcv.irs + 1;
                        pkt.hdr.seq = c->snd.iss;
-                       pkt.hdr.wnd = c->rcv.wnd;
+                       pkt.hdr.wnd = c->rcvbuf.maxsize;
                        pkt.hdr.ctl = SYN | ACK;
 
                        if(init) {
@@ -1313,8 +1315,10 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
 
                assert(data_acked >= 0);
 
+#ifndef NDEBUG
                int32_t bufused = seqdiff(c->snd.last, c->snd.una);
                assert(data_acked <= bufused);
+#endif
 
                if(data_acked) {
                        buffer_get(&c->sndbuf, NULL, data_acked);
@@ -1410,6 +1414,9 @@ skip_ack:
                        break;
 
                case SYN_RECEIVED:
+                       // This is a retransmit of a SYN, send back the SYNACK.
+                       goto synack;
+
                case ESTABLISHED:
                case FIN_WAIT_1:
                case FIN_WAIT_2: