From eb0a013a9b6c957aee0aecebc7d451dfd6851661 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 5 Oct 2019 14:29:16 +0200 Subject: [PATCH] Always send an ACK back when we receive data from the peer. A previous ACK could get lost, causing the peer to resend data. If the retransmission doesn't contain any new data, we would consider this data to be outside our receive window, and then not resend our ACK. --- utcp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/utcp.c b/utcp.c index 7e28f9e..d0e56d2 100644 --- a/utcp.c +++ b/utcp.c @@ -1011,6 +1011,8 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) { ptr += 2; } + bool has_data = len; + // Try to match the packet to an existing connection struct utcp_connection *c = find_connection(utcp, hdr.dst, hdr.src); @@ -1105,8 +1107,6 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) { // It is for an existing connection. - uint32_t prevrcvnxt = c->rcv.nxt; - // 1. Drop invalid packets. // 1a. Drop packets that should not happen in our current state. @@ -1130,7 +1130,7 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) { break; } - // 1b. Drop packets with a sequence number not in our receive window. + // 1b. Discard data that is not in our receive window. if(is_reliable(c)) { bool acceptable; @@ -1282,7 +1282,6 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) { // 3. Advance snd.una advanced = seqdiff(hdr.ack, c->snd.una); - prevrcvnxt = c->rcv.nxt; if(advanced) { // RTT measurement @@ -1536,13 +1535,13 @@ skip_ack: } // Now we send something back if: - // - we advanced rcv.nxt (ie, we got some data that needs to be ACKed) + // - we received data, so we have to send back an ACK // -> sendatleastone = true // - or we got an ack, so we should maybe send a bit more data // -> sendatleastone = false if(is_reliable(c) || hdr.ctl & SYN || hdr.ctl & FIN) { - ack(c, len || prevrcvnxt != c->rcv.nxt); + ack(c, has_data); } return 0; -- 2.39.5