diff options
Diffstat (limited to 'net/ipv4/tcp_timer.c')
| -rw-r--r-- | net/ipv4/tcp_timer.c | 29 | 
1 files changed, 19 insertions, 10 deletions
| diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 83fe7f62f7f1..4d40615dc8fc 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -74,11 +74,7 @@ u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when)  static void tcp_write_err(struct sock *sk)  { -	WRITE_ONCE(sk->sk_err, READ_ONCE(sk->sk_err_soft) ? : ETIMEDOUT); -	sk_error_report(sk); - -	tcp_write_queue_purge(sk); -	tcp_done(sk); +	tcp_done_with_error(sk, READ_ONCE(sk->sk_err_soft) ? : ETIMEDOUT);  	__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT);  } @@ -483,11 +479,26 @@ static bool tcp_rtx_probe0_timed_out(const struct sock *sk,  				     const struct sk_buff *skb,  				     u32 rtx_delta)  { +	const struct inet_connection_sock *icsk = inet_csk(sk); +	u32 user_timeout = READ_ONCE(icsk->icsk_user_timeout);  	const struct tcp_sock *tp = tcp_sk(sk); -	const int timeout = TCP_RTO_MAX * 2; -	u32 rcv_delta; +	int timeout = TCP_RTO_MAX * 2; +	s32 rcv_delta; -	rcv_delta = inet_csk(sk)->icsk_timeout - tp->rcv_tstamp; +	if (user_timeout) { +		/* If user application specified a TCP_USER_TIMEOUT, +		 * it does not want win 0 packets to 'reset the timer' +		 * while retransmits are not making progress. +		 */ +		if (rtx_delta > user_timeout) +			return true; +		timeout = min_t(u32, timeout, msecs_to_jiffies(user_timeout)); +	} +	/* Note: timer interrupt might have been delayed by at least one jiffy, +	 * and tp->rcv_tstamp might very well have been written recently. +	 * rcv_delta can thus be negative. +	 */ +	rcv_delta = icsk->icsk_timeout - tp->rcv_tstamp;  	if (rcv_delta <= timeout)  		return false; @@ -532,8 +543,6 @@ void tcp_retransmit_timer(struct sock *sk)  	if (WARN_ON_ONCE(!skb))  		return; -	tp->tlp_high_seq = 0; -  	if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) &&  	    !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) {  		/* Receiver dastardly shrinks window. Our retransmits |