|
@@ -1992,6 +1992,33 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static int tcp_can_forward_retransmit(struct sock *sk)
|
|
|
+{
|
|
|
+ const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
+ struct tcp_sock *tp = tcp_sk(sk);
|
|
|
+
|
|
|
+ /* Forward retransmissions are possible only during Recovery. */
|
|
|
+ if (icsk->icsk_ca_state != TCP_CA_Recovery)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* No forward retransmissions in Reno are possible. */
|
|
|
+ if (tcp_is_reno(tp))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* Yeah, we have to make difficult choice between forward transmission
|
|
|
+ * and retransmission... Both ways have their merits...
|
|
|
+ *
|
|
|
+ * For now we do not retransmit anything, while we have some new
|
|
|
+ * segments to send. In the other cases, follow rule 3 for
|
|
|
+ * NextSeg() specified in RFC3517.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (tcp_may_send_now(sk))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
/* This gets called after a retransmit timeout, and the initially
|
|
|
* retransmitted data is acknowledged. It tries to continue
|
|
|
* resending the rest of the retransmit queue, until either
|
|
@@ -2057,24 +2084,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
|
|
|
}
|
|
|
|
|
|
/* OK, demanded retransmission is finished. */
|
|
|
-
|
|
|
- /* Forward retransmissions are possible only during Recovery. */
|
|
|
- if (icsk->icsk_ca_state != TCP_CA_Recovery)
|
|
|
- return;
|
|
|
-
|
|
|
- /* No forward retransmissions in Reno are possible. */
|
|
|
- if (tcp_is_reno(tp))
|
|
|
- return;
|
|
|
-
|
|
|
- /* Yeah, we have to make difficult choice between forward transmission
|
|
|
- * and retransmission... Both ways have their merits...
|
|
|
- *
|
|
|
- * For now we do not retransmit anything, while we have some new
|
|
|
- * segments to send. In the other cases, follow rule 3 for
|
|
|
- * NextSeg() specified in RFC3517.
|
|
|
- */
|
|
|
-
|
|
|
- if (tcp_may_send_now(sk))
|
|
|
+ if (!tcp_can_forward_retransmit(sk))
|
|
|
return;
|
|
|
|
|
|
/* If nothing is SACKed, highest_sack in the loop won't be valid */
|