[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>
This commit is contained in:
parent
88c07ddec8
commit
91cc17c0e5
|
@ -1295,6 +1295,7 @@ static int tcp_mtu_probe(struct sock *sk)
|
||||||
struct sk_buff *skb, *nskb, *next;
|
struct sk_buff *skb, *nskb, *next;
|
||||||
int len;
|
int len;
|
||||||
int probe_size;
|
int probe_size;
|
||||||
|
int size_needed;
|
||||||
unsigned int pif;
|
unsigned int pif;
|
||||||
int copy;
|
int copy;
|
||||||
int mss_now;
|
int mss_now;
|
||||||
|
@ -1313,6 +1314,7 @@ static int tcp_mtu_probe(struct sock *sk)
|
||||||
/* Very simple search strategy: just double the MSS. */
|
/* Very simple search strategy: just double the MSS. */
|
||||||
mss_now = tcp_current_mss(sk, 0);
|
mss_now = tcp_current_mss(sk, 0);
|
||||||
probe_size = 2*tp->mss_cache;
|
probe_size = 2*tp->mss_cache;
|
||||||
|
size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
|
||||||
if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
|
if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
|
||||||
/* TODO: set timer for probe_converge_event */
|
/* TODO: set timer for probe_converge_event */
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1322,18 +1324,15 @@ static int tcp_mtu_probe(struct sock *sk)
|
||||||
len = 0;
|
len = 0;
|
||||||
if ((skb = tcp_send_head(sk)) == NULL)
|
if ((skb = tcp_send_head(sk)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
while ((len += skb->len) < probe_size && !tcp_skb_is_last(sk, skb))
|
while ((len += skb->len) < size_needed && !tcp_skb_is_last(sk, skb))
|
||||||
skb = tcp_write_queue_next(sk, skb);
|
skb = tcp_write_queue_next(sk, skb);
|
||||||
if (len < probe_size)
|
if (len < size_needed)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Receive window check. */
|
if (tp->snd_wnd < size_needed)
|
||||||
if (after(TCP_SKB_CB(skb)->seq + probe_size, tp->snd_una + tp->snd_wnd)) {
|
return -1;
|
||||||
if (tp->snd_wnd < probe_size)
|
if (after(tp->snd_nxt + size_needed, tp->snd_una + tp->snd_wnd))
|
||||||
return -1;
|
return 0;
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we need to wait to drain cwnd? */
|
/* Do we need to wait to drain cwnd? */
|
||||||
pif = tcp_packets_in_flight(tp);
|
pif = tcp_packets_in_flight(tp);
|
||||||
|
|
Loading…
Reference in New Issue