diff options
author | Yonit <yhalperi@redhat.com> | 2009-07-06 11:25:49 +0300 |
---|---|---|
committer | Yonit <yhalperi@redhat.com> | 2009-07-06 11:25:49 +0300 |
commit | e3cf8ba5350388174f03aa3943e137e6e3e7e140 (patch) | |
tree | 82812c15e359554a5915bcefec59ec4769ac5908 | |
parent | aa25b55655a7acdd4a59104af1bd3527860516c8 (diff) |
A hook for a bug where tp->rcv_nxt > tp->rcv_adv. The bug corrupted the tcp window
-rw-r--r-- | tcp_input.c | 9 | ||||
-rw-r--r-- | tcp_output.c | 11 |
2 files changed, 19 insertions, 1 deletions
diff --git a/tcp_input.c b/tcp_input.c index d40eb8a..73e8d76 100644 --- a/tcp_input.c +++ b/tcp_input.c @@ -646,6 +646,15 @@ findso: win = sbspace(&so->so_rcv); if (win < 0) win = 0; + + /* a hook for the case that tp->rcv_nxt > tp->rcv_adv. It can happen + when 1) there is more space in so_rcv than in the window last advertised and + 2) we received more data than the the size of the window last advertised. + For example: it happens when we receive zero window probes of len=1 and a space + in so_rcv is available */ + if (SEQ_LT(tp->rcv_adv, tp->rcv_nxt)) { + tp->rcv_adv = tp->rcv_nxt; + } tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); } diff --git a/tcp_output.c b/tcp_output.c index 4f252c0..abe29b4 100644 --- a/tcp_output.c +++ b/tcp_output.c @@ -176,6 +176,15 @@ again: win = sbspace(&so->so_rcv); + /* a hook for the case that tp->rcv_nxt > tp->rcv_adv. It can happen + when 1) there is more space in so_rcv than in the window last advertised and + 2) we received more data than the the size of the window last advertised. + For example: it happens when we receive zero window probes of len=1 and a space + in so_rcv is available */ + if (SEQ_LT(tp->rcv_adv, tp->rcv_nxt)) { + tp->rcv_adv = tp->rcv_nxt; + } + /* * Sender silly window avoidance. If connection is idle * and can send all data, a maximum segment, @@ -214,7 +223,7 @@ again: * TCP_MAXWIN << tp->rcv_scale. */ long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - - (tp->rcv_adv - tp->rcv_nxt); + (tp->rcv_adv - tp->rcv_nxt); if (adv >= (long) (2 * tp->t_maxseg)) goto send; |