diff options
author | jhb <jhb@FreeBSD.org> | 2012-01-05 22:29:11 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-01-05 22:29:11 +0000 |
commit | dc84417a34ae4a2b2c415dc2e403163535c8589d (patch) | |
tree | dad677180f0346b2c87c9aa4416760107b620497 /sys/netinet | |
parent | 6cd4b91f813aa3c0e4d3486fddf5dac445965cd2 (diff) | |
download | FreeBSD-src-dc84417a34ae4a2b2c415dc2e403163535c8589d.zip FreeBSD-src-dc84417a34ae4a2b2c415dc2e403163535c8589d.tar.gz |
Remove the assertion from tcp_input() that rcv_nxt is always greater
than or equal to rcv_adv and fix tcp_twstart() to handle this case by
assuming the last window was zero rather than a negative value.
The code in tcp_input() already safely handled this case. It can happen
due to delayed ACKs along with a remote sender that sends data beyond
the window we previously advertised. If we have room in our socket buffer
for the extra data beyond the advertised window, we will accept it.
However, if the ACK for that segment is delayed, then we will not
effectively fixup rcv_adv to account for that extra data until the
next segment arrives and forces out an ACK. When that next segment
arrives, rcv_nxt will be beyond rcv_adv.
Tested by: pjd
MFC after: 1 week
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/tcp_input.c | 3 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 8 |
2 files changed, 4 insertions, 7 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index e9ff355..db373cd 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1795,9 +1795,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, win = sbspace(&so->so_rcv); if (win < 0) win = 0; - KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt), - ("tcp_input negative window: tp %p rcv_nxt %u rcv_adv %u", tp, - tp->rcv_nxt, tp->rcv_adv)); tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); /* Reset receive buffer auto scaling when not in bulk receive mode. */ diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index fbcd601..31aa35c 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -242,10 +242,10 @@ tcp_twstart(struct tcpcb *tp) /* * Recover last window size sent. */ - KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt), - ("tcp_twstart negative window: tp %p rcv_nxt %u rcv_adv %u", tp, - tp->rcv_nxt, tp->rcv_adv)); - tw->last_win = (tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale; + if (SEQ_GE(tp->rcv_adv, tp->rcv_nxt)) + tw->last_win = (tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale; + else + tw->last_win = 0; /* * Set t_recent if timestamps are used on the connection. |