|
@@ -52,7 +52,7 @@ static void tcp_write_err(struct sock *sk)
|
|
|
* limit.
|
|
|
* 2. If we have strong memory pressure.
|
|
|
*/
|
|
|
-static int tcp_out_of_resources(struct sock *sk, int do_reset)
|
|
|
+static int tcp_out_of_resources(struct sock *sk, bool do_reset)
|
|
|
{
|
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
|
int shift = 0;
|
|
@@ -72,7 +72,7 @@ static int tcp_out_of_resources(struct sock *sk, int do_reset)
|
|
|
if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
|
|
|
/* 2. Window is closed. */
|
|
|
(!tp->snd_wnd && !tp->packets_out))
|
|
|
- do_reset = 1;
|
|
|
+ do_reset = true;
|
|
|
if (do_reset)
|
|
|
tcp_send_active_reset(sk, GFP_ATOMIC);
|
|
|
tcp_done(sk);
|
|
@@ -270,40 +270,41 @@ static void tcp_probe_timer(struct sock *sk)
|
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
|
int max_probes;
|
|
|
+ u32 start_ts;
|
|
|
|
|
|
if (tp->packets_out || !tcp_send_head(sk)) {
|
|
|
icsk->icsk_probes_out = 0;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* *WARNING* RFC 1122 forbids this
|
|
|
- *
|
|
|
- * It doesn't AFAIK, because we kill the retransmit timer -AK
|
|
|
- *
|
|
|
- * FIXME: We ought not to do it, Solaris 2.5 actually has fixing
|
|
|
- * this behaviour in Solaris down as a bug fix. [AC]
|
|
|
- *
|
|
|
- * Let me to explain. icsk_probes_out is zeroed by incoming ACKs
|
|
|
- * even if they advertise zero window. Hence, connection is killed only
|
|
|
- * if we received no ACKs for normal connection timeout. It is not killed
|
|
|
- * only because window stays zero for some time, window may be zero
|
|
|
- * until armageddon and even later. We are in full accordance
|
|
|
- * with RFCs, only probe timer combines both retransmission timeout
|
|
|
- * and probe timeout in one bottle. --ANK
|
|
|
+ /* RFC 1122 4.2.2.17 requires the sender to stay open indefinitely as
|
|
|
+ * long as the receiver continues to respond probes. We support this by
|
|
|
+ * default and reset icsk_probes_out with incoming ACKs. But if the
|
|
|
+ * socket is orphaned or the user specifies TCP_USER_TIMEOUT, we
|
|
|
+ * kill the socket when the retry count and the time exceeds the
|
|
|
+ * corresponding system limit. We also implement similar policy when
|
|
|
+ * we use RTO to probe window in tcp_retransmit_timer().
|
|
|
*/
|
|
|
- max_probes = sysctl_tcp_retries2;
|
|
|
+ start_ts = tcp_skb_timestamp(tcp_send_head(sk));
|
|
|
+ if (!start_ts)
|
|
|
+ skb_mstamp_get(&tcp_send_head(sk)->skb_mstamp);
|
|
|
+ else if (icsk->icsk_user_timeout &&
|
|
|
+ (s32)(tcp_time_stamp - start_ts) > icsk->icsk_user_timeout)
|
|
|
+ goto abort;
|
|
|
|
|
|
+ max_probes = sysctl_tcp_retries2;
|
|
|
if (sock_flag(sk, SOCK_DEAD)) {
|
|
|
const int alive = inet_csk_rto_backoff(icsk, TCP_RTO_MAX) < TCP_RTO_MAX;
|
|
|
|
|
|
max_probes = tcp_orphan_retries(sk, alive);
|
|
|
-
|
|
|
- if (tcp_out_of_resources(sk, alive || icsk->icsk_probes_out <= max_probes))
|
|
|
+ if (!alive && icsk->icsk_backoff >= max_probes)
|
|
|
+ goto abort;
|
|
|
+ if (tcp_out_of_resources(sk, true))
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (icsk->icsk_probes_out > max_probes) {
|
|
|
- tcp_write_err(sk);
|
|
|
+abort: tcp_write_err(sk);
|
|
|
} else {
|
|
|
/* Only send another probe if we didn't close things up. */
|
|
|
tcp_send_probe0(sk);
|