diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1999-04-21 21:38:59 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1999-04-21 21:38:59 +0000 |
commit | 047a45ed0d3e3e0cb7c5b450741fbf0004317919 (patch) | |
tree | f17e5fddecd50e6159ffafa7d55c21fa0cf4ed2d | |
parent | b6a78226098fa7ced186c6ca8544c7ee20ed0e96 (diff) |
From Tom Henderson <tomh@cs.berkeley.edu>:
Fixed a sequence wraparound bug in the snd_recover variable discovered in
very large (multiple GByte) transfers (in loss free conditions, snd_recover
was not sufficiently tracking snd_una). Thanks to Mark Smith for finding
this.
Fixed a bug in tcp_newreno that was preventing retransmission of data due
to partial acks. (Discovered by Jayanth Vijayaraghavan)
-rw-r--r-- | sys/netinet/tcp_input.c | 16 | ||||
-rw-r--r-- | sys/netinet/tcp_timer.c | 9 |
2 files changed, 22 insertions, 3 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 59086ee521b..e9d4d1277de 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.33 1999/03/27 21:04:20 provos Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.34 1999/04/21 21:38:58 provos Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -875,6 +875,14 @@ findpcb: tcpstat.tcps_rcvackbyte += acked; sbdrop(&so->so_snd, acked); tp->snd_una = th->th_ack; +#if defined(TCP_SACK) || defined(TCP_NEWRENO) + /* + * We want snd_last to track snd_una so + * as to avoid sequence wraparound problems + * for very large transfers. + */ + tp->snd_last = tp->snd_una; +#endif /* TCP_SACK or TCP_NEWRENO */ #if defined(TCP_SACK) && defined(TCP_FACK) tp->snd_fack = tp->snd_una; tp->retran_data = 0; @@ -2978,7 +2986,11 @@ tcp_newreno(tp, th) tp->t_timer[TCPT_REXMT] = 0; tp->t_rtt = 0; tp->snd_nxt = th->th_ack; - tp->snd_cwnd = tp->t_maxseg; + /* + * Set snd_cwnd to one segment beyond acknowledged offset + * (tp->snd_una not yet updated when this function is called) + */ + tp->snd_cwnd = tp->t_maxseg + (th->th_ack - tp->snd_una); (void) tcp_output(tp); tp->snd_cwnd = ocwnd; if (SEQ_GT(onxt, tp->snd_nxt)) diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 217cb6464f0..c281fda1841 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_timer.c,v 1.11 1999/01/27 16:47:29 provos Exp $ */ +/* $OpenBSD: tcp_timer.c,v 1.12 1999/04/21 21:38:58 provos Exp $ */ /* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */ /* @@ -247,6 +247,13 @@ tcp_timers(tp, timer) tp->t_srtt = 0; } tp->snd_nxt = tp->snd_una; +#if defined(TCP_SACK) || defined(TCP_NEWRENO) + /* + * Note: We overload snd_last to function also as the + * snd_last variable described in RFC 2582 + */ + tp->snd_last = tp->snd_max; +#endif /* TCP_SACK or TCP_NEWRENO */ /* * If timing a segment in this window, stop the timer. */ |