aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-11-23 06:08:16 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2007-11-23 06:08:16 -0500
commit91cc17c0e5e5ada156a8d5787a2509d263ea6bbf (patch)
tree776cd7cf3438913d6a10b4071c528307eb4db50c
parent88c07ddec8c5e06aa331470076af27a397fc0993 (diff)
[TCP]: MTUprobe: receiver window & data available checks fixed
It seems that the checked range for receiver window check should begin from the first rather than from the last skb that is going to be included to the probe. And that can be achieved without reference to skbs at all, snd_nxt and write_seq provides the correct seqno already. Plus, it SHOULD account packets that are necessary to trigger fast retransmit [RFC4821]. Location of snd_wnd < probe_size/size_needed check is bogus because it will cause the other if() match as well (due to snd_nxt >= snd_una invariant). Removed dead obvious comment. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--net/ipv4/tcp_output.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index e48e28e7d539..4f8a8a17891a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1295,6 +1295,7 @@ static int tcp_mtu_probe(struct sock *sk)
1295 struct sk_buff *skb, *nskb, *next; 1295 struct sk_buff *skb, *nskb, *next;
1296 int len; 1296 int len;
1297 int probe_size; 1297 int probe_size;
1298 int size_needed;
1298 unsigned int pif; 1299 unsigned int pif;
1299 int copy; 1300 int copy;
1300 int mss_now; 1301 int mss_now;
@@ -1313,6 +1314,7 @@ static int tcp_mtu_probe(struct sock *sk)
1313 /* Very simple search strategy: just double the MSS. */ 1314 /* Very simple search strategy: just double the MSS. */
1314 mss_now = tcp_current_mss(sk, 0); 1315 mss_now = tcp_current_mss(sk, 0);
1315 probe_size = 2*tp->mss_cache; 1316 probe_size = 2*tp->mss_cache;
1317 size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
1316 if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) { 1318 if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
1317 /* TODO: set timer for probe_converge_event */ 1319 /* TODO: set timer for probe_converge_event */
1318 return -1; 1320 return -1;
@@ -1322,18 +1324,15 @@ static int tcp_mtu_probe(struct sock *sk)
1322 len = 0; 1324 len = 0;
1323 if ((skb = tcp_send_head(sk)) == NULL) 1325 if ((skb = tcp_send_head(sk)) == NULL)
1324 return -1; 1326 return -1;
1325 while ((len += skb->len) < probe_size && !tcp_skb_is_last(sk, skb)) 1327 while ((len += skb->len) < size_needed && !tcp_skb_is_last(sk, skb))
1326 skb = tcp_write_queue_next(sk, skb); 1328 skb = tcp_write_queue_next(sk, skb);
1327 if (len < probe_size) 1329 if (len < size_needed)
1328 return -1; 1330 return -1;
1329 1331
1330 /* Receive window check. */ 1332 if (tp->snd_wnd < size_needed)
1331 if (after(TCP_SKB_CB(skb)->seq + probe_size, tp->snd_una + tp->snd_wnd)) { 1333 return -1;
1332 if (tp->snd_wnd < probe_size) 1334 if (after(tp->snd_nxt + size_needed, tp->snd_una + tp->snd_wnd))
1333 return -1; 1335 return 0;
1334 else
1335 return 0;
1336 }
1337 1336
1338 /* Do we need to wait to drain cwnd? */ 1337 /* Do we need to wait to drain cwnd? */
1339 pif = tcp_packets_in_flight(tp); 1338 pif = tcp_packets_in_flight(tp);