diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-01-27 22:12:50 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-01-27 22:12:50 +0100 |
commit | 8152e9d075e507d36b6edb48ac1e15082fabeed5 (patch) | |
tree | a5b92a4952182a3d21e14bf37d749c8056409cb5 | |
parent | 63a0d519bcdb02b226023b1c07343bc52791a677 (diff) |
devip: tcp: Don't respond to FIN-less ACKs during TIME-WAIT (thanks Barret Rhoden)
Under the normal close sequence, when we receive a FIN|ACK, we enter
TIME-WAIT and respond to that LAST-ACK with an ACK. Our TCP stack would
send an ACK in response to *any* ACK, which included FIN|ACK but also
included regular ACKs. (Or PSH|ACKs, which is what we were actually
getting/sending).
That was more ACKs than is necessary and results in an endless ACK storm
if we were under the simultaneous close sequence. In that scenario,
both sides of a connection are in TIME-WAIT. Both sides receive
FIN|ACK, and both respond with an ACK. Then both sides receive *those*
ACKs, and respond again. This continues until the TIME-WAIT wait period
elapses and each side's TCP timers (in the Plan 9 / Akaros case) shut
down.
The fix for this is to only respond to a FIN|ACK when we are in TIME-WAIT.
-rw-r--r-- | sys/src/9/ip/tcp.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/src/9/ip/tcp.c b/sys/src/9/ip/tcp.c index 3989ce437..775d1b1ce 100644 --- a/sys/src/9/ip/tcp.c +++ b/sys/src/9/ip/tcp.c @@ -2399,7 +2399,8 @@ reset: goto raise; } case Time_wait: - tcb->flags |= FORCE; + if(seg.flags & FIN) + tcb->flags |= FORCE; if(tcb->timer.state != TcptimerON) tcpgo(tpriv, &tcb->timer); } |