summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_output.c
diff options
context:
space:
mode:
authorjayanth <jayanth@FreeBSD.org>2004-07-28 02:15:14 +0000
committerjayanth <jayanth@FreeBSD.org>2004-07-28 02:15:14 +0000
commitb754d213ab76dee1e7bcd5acb4becd5658c0ca99 (patch)
tree3b799630bf83139bd6292b793a65a64582e070b7 /sys/netinet/tcp_output.c
parentac2fecdcf2ab22abbc2181ae2023eefe7389adf5 (diff)
downloadFreeBSD-src-b754d213ab76dee1e7bcd5acb4becd5658c0ca99.zip
FreeBSD-src-b754d213ab76dee1e7bcd5acb4becd5658c0ca99.tar.gz
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.
Diffstat (limited to 'sys/netinet/tcp_output.c')
-rw-r--r--sys/netinet/tcp_output.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index c69b90a..5d71887 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:
OpenPOWER on IntegriCloud