aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_input.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e990d562f5e3..cc935c8a6aae 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1296,7 +1296,7 @@ void tcp_enter_frto(struct sock *sk)
1296 * which indicates that we should follow the traditional RTO recovery, 1296 * which indicates that we should follow the traditional RTO recovery,
1297 * i.e. mark everything lost and do go-back-N retransmission. 1297 * i.e. mark everything lost and do go-back-N retransmission.
1298 */ 1298 */
1299static void tcp_enter_frto_loss(struct sock *sk) 1299static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments)
1300{ 1300{
1301 struct tcp_sock *tp = tcp_sk(sk); 1301 struct tcp_sock *tp = tcp_sk(sk);
1302 struct sk_buff *skb; 1302 struct sk_buff *skb;
@@ -1326,7 +1326,7 @@ static void tcp_enter_frto_loss(struct sock *sk)
1326 } 1326 }
1327 tcp_sync_left_out(tp); 1327 tcp_sync_left_out(tp);
1328 1328
1329 tp->snd_cwnd = tp->frto_counter + tcp_packets_in_flight(tp)+1; 1329 tp->snd_cwnd = tcp_packets_in_flight(tp) + allowed_segments;
1330 tp->snd_cwnd_cnt = 0; 1330 tp->snd_cwnd_cnt = 0;
1331 tp->snd_cwnd_stamp = tcp_time_stamp; 1331 tp->snd_cwnd_stamp = tcp_time_stamp;
1332 tp->undo_marker = 0; 1332 tp->undo_marker = 0;
@@ -2527,6 +2527,11 @@ static void tcp_process_frto(struct sock *sk, u32 prior_snd_una, int flag)
2527 if (flag&FLAG_DATA_ACKED) 2527 if (flag&FLAG_DATA_ACKED)
2528 inet_csk(sk)->icsk_retransmits = 0; 2528 inet_csk(sk)->icsk_retransmits = 0;
2529 2529
2530 if (!before(tp->snd_una, tp->frto_highmark)) {
2531 tcp_enter_frto_loss(sk, tp->frto_counter + 1);
2532 return;
2533 }
2534
2530 /* RFC4138 shortcoming in step 2; should also have case c): ACK isn't 2535 /* RFC4138 shortcoming in step 2; should also have case c): ACK isn't
2531 * duplicate nor advances window, e.g., opposite dir data, winupdate 2536 * duplicate nor advances window, e.g., opposite dir data, winupdate
2532 */ 2537 */
@@ -2534,9 +2539,8 @@ static void tcp_process_frto(struct sock *sk, u32 prior_snd_una, int flag)
2534 !(flag&FLAG_FORWARD_PROGRESS)) 2539 !(flag&FLAG_FORWARD_PROGRESS))
2535 return; 2540 return;
2536 2541
2537 if (tp->snd_una == prior_snd_una || 2542 if (!(flag&FLAG_DATA_ACKED)) {
2538 !before(tp->snd_una, tp->frto_highmark)) { 2543 tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 0 : 3));
2539 tcp_enter_frto_loss(sk);
2540 return; 2544 return;
2541 } 2545 }
2542 2546