From 5d3b1b755608211cd404e22b435c0a7498db7f4f Mon Sep 17 00:00:00 2001 From: Jayanth Vijayaraghavan Date: Wed, 28 Jul 2004 02:15:14 +0000 Subject: [PATCH] Fix a bug in the sack code that was causing data to be retransmitted with the FIN bit set for all segments, if a FIN has already been sent before. The fix will allow the FIN bit to be set for only the last segment, in case it has to be retransmitted. Fix another bug that would have caused snd_nxt to be pulled by len if there was an error from ip_output. snd_nxt should not be touched during sack retransmissions. --- sys/netinet/tcp_output.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index c69b90aae8cb..5d71887a5c54 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -356,8 +356,13 @@ after_sack_rexmit: len = tp->t_maxseg; sendalot = 1; } - if (off + len < so->so_snd.sb_cc) - flags &= ~TH_FIN; + if (sack_rxmit) { + if (SEQ_LT(p->rxmit + len, tp->snd_una + so->so_snd.sb_cc)) + flags &= ~TH_FIN; + } else { + if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) + flags &= ~TH_FIN; + } recwin = sbspace(&so->so_rcv); @@ -1088,8 +1093,12 @@ timer: * No need to check for TH_FIN here because * the TF_SENTFIN flag handles that case. */ - if ((flags & TH_SYN) == 0) - tp->snd_nxt -= len; + if ((flags & TH_SYN) == 0) { + if (sack_rxmit) + p->rxmit -= len; + else + tp->snd_nxt -= len; + } } out: