Skip to content

Commit

Permalink
Faster recovery from retransmission
Browse files Browse the repository at this point in the history
Limit the number of dup-ACKs to 3, and send fast-ACKs after each
retransmitted segment.
  • Loading branch information
jwt27 committed Jan 20, 2024
1 parent 208a98b commit 4b26f08
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
30 changes: 27 additions & 3 deletions src/tcp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,18 @@ static int tcp_estab_state (_tcp_Socket **sp, const in_Header *ip,
len = tcp_process_data (s, tcp, len, &flags);
if (len < 0)
{
TCP_SEND (s); /* An out-of-order or missing segment; do fast ACK */
/* An out-of-order or missing segment; do fast ACK.
* Three should be enough. If those get dropped,
* retransmitter will send more eventually.
*/
if (s->dup_acks < 3)
{
TCP_SEND (s);
++s->dup_acks;
}
return (1);
}
s->dup_acks = 0;

if (s->state != tcp_StateCLOSWT &&
(flags & tcp_FlagFIN) &&
Expand Down Expand Up @@ -403,6 +412,14 @@ static int tcp_estab_state (_tcp_Socket **sp, const in_Header *ip,
}
}

/* Send fast-ACK after retransmission.
*/
if (len > 0 && s->missed_seq[0] != s->missed_seq[1])
{
TCP_SEND (s);
return (0);
}

/* Peer ACKed some of our data, continue sending more.
*/
if (ldiff > 0 && s->tx_datalen > (unsigned long)s->send_una)
Expand Down Expand Up @@ -847,7 +864,7 @@ copy_in_order (_tcp_Socket *s, const BYTE *data, unsigned len)
* Handle any new data that increments the 'recv_next' index.
* 'ldiff >= 0'.
*/
static void
static int
data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
{
/* Skip data before recv_next. We must be left with some data or
Expand Down Expand Up @@ -892,6 +909,11 @@ data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
*/
copy_in_order (s, data + ms_end, len - ms_end);
}

/* Send fast-ACK to notify peer that we caught up.
*/
s->dup_acks = 0;
len = -1;
}

TRACE_FILE ("data_in_order (%u): edges %lu/%lu, recv.next %lu\n",
Expand All @@ -900,6 +922,8 @@ data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)

TRACE_FILE ("data_in_order (%u): new data now ends at %u\n",
__LINE__, s->rx_datalen);

return (len);
}

/*
Expand Down Expand Up @@ -1091,7 +1115,7 @@ static int tcp_process_data (_tcp_Socket *s, const tcp_Header *tcp,

if (ldiff >= 0)
{
data_in_order (s, data, len, ldiff);
len = data_in_order (s, data, len, ldiff);
s->unhappy = (s->tx_datalen > 0);
return (len);
}
Expand Down
4 changes: 3 additions & 1 deletion src/wattcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,9 @@ typedef struct tcp_Socket {
UINT rto; /**< retransmission timeout */
BYTE karn_count; /**< count of packets */
BYTE tos; /**< TOS from IP-header */
WORD fill_5;

BYTE dup_acks; /**< number of dup-ACKs we sent recently */
BYTE fill_5;

DWORD rtt_time; /**< Round Trip Time value */
DWORD rtt_lasttran; /**< RTT at last transmission */
Expand Down

0 comments on commit 4b26f08

Please sign in to comment.