net: tcp: raise zero-window probe without check wnd_end
In the origin logic, zero-window probe can not only be raised on 0 window, but also in other case, such as MTU probe fails. Therefore, we need modify tcp_probe0_needed() to make it compatible with origin logic. Signed-off-by: Menglong Dong <imagedong@tencent.com>
This commit is contained in:
parent
980a335360
commit
f0d423d51c
|
@ -1831,29 +1831,35 @@ static inline bool tcp_rtx_and_write_queues_empty(const struct sock *sk)
|
|||
return tcp_rtx_queue_empty(sk) && tcp_write_queue_empty(sk);
|
||||
}
|
||||
|
||||
static inline bool __tcp_probe0_needed(const struct sock *sk)
|
||||
{
|
||||
return !tcp_sk(sk)->packets_out && !tcp_write_queue_empty(sk);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCP_WND_SHRINK
|
||||
|
||||
static inline bool tcp_rtx_overflow(const struct sock *sk)
|
||||
{
|
||||
struct sk_buff *rtx_head = tcp_rtx_queue_head(sk);
|
||||
|
||||
return rtx_head && after(TCP_SKB_CB(rtx_head)->end_seq,
|
||||
tcp_wnd_end(tcp_sk(sk)));
|
||||
}
|
||||
|
||||
/* check if 0 window probe is need by the sk */
|
||||
static inline bool tcp_probe0_needed(const struct sock *sk)
|
||||
{
|
||||
struct sk_buff *rtx_head = tcp_rtx_queue_head(sk);
|
||||
struct sk_buff *head = tcp_send_head(sk);
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
/* for the normal case */
|
||||
if (__tcp_probe0_needed(sk))
|
||||
return true;
|
||||
|
||||
if (rtx_head) {
|
||||
if (after(TCP_SKB_CB(rtx_head)->end_seq, tcp_wnd_end(tp)))
|
||||
return true;
|
||||
} else {
|
||||
if (head && after(TCP_SKB_CB(head)->end_seq,
|
||||
tcp_wnd_end(tp)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
/* for the window shrink case */
|
||||
return tcp_rtx_overflow(sk);
|
||||
}
|
||||
#else
|
||||
static inline bool tcp_probe0_needed(const struct sock *sk)
|
||||
{
|
||||
return !tcp_sk(sk)->packets_out && !tcp_write_queue_empty(sk);
|
||||
return __tcp_probe0_needed(sk);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3316,12 +3316,24 @@ static void tcp_ack_probe(struct sock *sk)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_TCP_WND_SHRINK
|
||||
/**
|
||||
* This function is called only when there are packets in the rtx queue,
|
||||
* which means that the packets out is not 0.
|
||||
*
|
||||
* NOTE: we only handle window shrink case in this part.
|
||||
*/
|
||||
static void tcp_ack_probe_shrink(struct sock *sk)
|
||||
{
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
unsigned long when;
|
||||
|
||||
if (!tcp_probe0_needed(sk)) {
|
||||
if (tcp_rtx_overflow(sk)) {
|
||||
when = tcp_probe0_when(sk, TCP_RTO_MAX);
|
||||
|
||||
when = tcp_clamp_probe0_to_user_timeout(sk, when);
|
||||
tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0,
|
||||
when, TCP_RTO_MAX, NULL);
|
||||
} else {
|
||||
/* check if recover from window shrink */
|
||||
if (icsk->icsk_pending != ICSK_TIME_PROBE0)
|
||||
return;
|
||||
|
@ -3331,12 +3343,6 @@ static void tcp_ack_probe_shrink(struct sock *sk)
|
|||
inet_csk_clear_xmit_timer(sk, ICSK_TIME_PROBE0);
|
||||
if (!tcp_rtx_queue_empty(sk))
|
||||
tcp_retransmit_timer(sk);
|
||||
} else {
|
||||
when = tcp_probe0_when(sk, TCP_RTO_MAX);
|
||||
|
||||
when = tcp_clamp_probe0_to_user_timeout(sk, when);
|
||||
tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0,
|
||||
when, TCP_RTO_MAX, NULL);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue