diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2000-09-05 21:57:42 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2000-09-05 21:57:42 +0000 |
commit | bd283c54e9b0fb364bc2573d357bf401b661b747 (patch) | |
tree | 74d5cff36092378594e3baf96ad1da74f036a829 /sys/netinet/tcp_input.c | |
parent | 20def5508e57c7205c4776a54a03e0df6aa4f3cd (diff) |
various fixes to SACK and FACK from adesai@cisco.com, tomh@tomh.org and
osuga@mml.yrp.nttdocomo.co.jp
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index e84f649e326..33a38b7dee4 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.68 2000/07/27 04:05:26 itojun Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.69 2000/09/05 21:57:41 provos Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -1563,9 +1563,7 @@ trimthenstep6: * False fast retx after * timeout. Do not cut window. */ - tp->snd_cwnd += tp->t_maxseg; tp->t_dupacks = 0; - (void) tcp_output(tp); goto drop; } #endif @@ -1581,13 +1579,13 @@ trimthenstep6: tp->t_rtt = 0; tcpstat.tcps_sndrexmitfast++; #if defined(TCP_SACK) && defined(TCP_FACK) + tp->t_dupacks = tcprexmtthresh; (void) tcp_output(tp); /* * During FR, snd_cwnd is held * constant for FACK. */ tp->snd_cwnd = tp->snd_ssthresh; - tp->t_dupacks = tcprexmtthresh; #else /* * tcp_output() will send @@ -1663,7 +1661,7 @@ trimthenstep6: th->th_ack) < tp->snd_ssthresh) tp->snd_cwnd = tcp_seq_subtract(tp->snd_max, - th->th_ack) + tp->t_maxseg; + th->th_ack); tp->t_dupacks = 0; #if defined(TCP_SACK) && defined(TCP_FACK) if (SEQ_GT(th->th_ack, tp->snd_fack)) @@ -1680,7 +1678,7 @@ trimthenstep6: tp->snd_ssthresh) tp->snd_cwnd = tcp_seq_subtract(tp->snd_max, - th->th_ack) + tp->t_maxseg; + th->th_ack); tp->t_dupacks = 0; } } @@ -1739,7 +1737,7 @@ trimthenstep6: if (cw > tp->snd_ssthresh) incr = incr * incr / cw; #if defined (TCP_SACK) - if (SEQ_GEQ(th->th_ack, tp->snd_last)) + if (tp->t_dupacks < tcprexmtthresh) #endif tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale); } @@ -1759,8 +1757,14 @@ trimthenstep6: if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; #if defined (TCP_SACK) && defined (TCP_FACK) - if (SEQ_GT(tp->snd_una, tp->snd_fack)) + if (SEQ_GT(tp->snd_una, tp->snd_fack)) { tp->snd_fack = tp->snd_una; + /* Update snd_awnd for partial ACK + * without any SACK blocks. + */ + tp->snd_awnd = tcp_seq_subtract(tp->snd_nxt, + tp->snd_fack) + tp->retran_data; + } #endif switch (tp->t_state) { @@ -2546,6 +2550,8 @@ tcp_del_sackholes(tp, th) tp->snd_numholes--; } else if (SEQ_LT(cur->start, lastack)) { cur->start = lastack; + if (SEQ_LT(cur->rxmit, cur->start)) + cur->rxmit = cur->start; break; } else break; @@ -2588,7 +2594,11 @@ tcp_sack_partialack(tp, th) * fact that tp->snd_una has not been updated yet. In FACK * hold snd_cwnd constant during fast recovery. */ - tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg); + if (tp->snd_cwnd > (th->th_ack - tp->snd_una)) { + tp->snd_cwnd -= th->th_ack - tp->snd_una; + tp->snd_cwnd += tp->t_maxseg; + } else + tp->snd_cwnd = tp->t_maxseg; #endif return 1; } |