diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 324b4207254a..e5130a7fe181 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,27 +1314,20 @@ 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; |
1319 | } | 1321 | } |
1320 | 1322 | ||
1321 | /* Have enough data in the send queue to probe? */ | 1323 | /* Have enough data in the send queue to probe? */ |
1322 | len = 0; | 1324 | if (tp->write_seq - tp->snd_nxt < size_needed) |
1323 | if ((skb = tcp_send_head(sk)) == NULL) | ||
1324 | return -1; | ||
1325 | while ((len += skb->len) < probe_size && !tcp_skb_is_last(sk, skb)) | ||
1326 | skb = tcp_write_queue_next(sk, skb); | ||
1327 | if (len < probe_size) | ||
1328 | return -1; | 1325 | return -1; |
1329 | 1326 | ||
1330 | /* Receive window check. */ | 1327 | if (tp->snd_wnd < size_needed) |
1331 | if (after(TCP_SKB_CB(skb)->seq + probe_size, tp->snd_una + tp->snd_wnd)) { | 1328 | return -1; |
1332 | if (tp->snd_wnd < probe_size) | 1329 | if (after(tp->snd_nxt + size_needed, tp->snd_una + tp->snd_wnd)) |
1333 | return -1; | 1330 | return 0; |
1334 | else | ||
1335 | return 0; | ||
1336 | } | ||
1337 | 1331 | ||
1338 | /* Do we need to wait to drain cwnd? */ | 1332 | /* Do we need to wait to drain cwnd? */ |
1339 | pif = tcp_packets_in_flight(tp); | 1333 | pif = tcp_packets_in_flight(tp); |
@@ -1352,7 +1346,6 @@ static int tcp_mtu_probe(struct sock *sk) | |||
1352 | 1346 | ||
1353 | skb = tcp_send_head(sk); | 1347 | skb = tcp_send_head(sk); |
1354 | tcp_insert_write_queue_before(nskb, skb, sk); | 1348 | tcp_insert_write_queue_before(nskb, skb, sk); |
1355 | tcp_advance_send_head(sk, skb); | ||
1356 | 1349 | ||
1357 | TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq; | 1350 | TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq; |
1358 | TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size; | 1351 | TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size; |