diff options
author | Paul Gofman <pgofman@codeweavers.com> | 2022-02-16 18:41:40 -0300 |
---|---|---|
committer | Cristian Ciocaltea <cristian.ciocaltea@collabora.com> | 2022-12-12 17:57:15 +0200 |
commit | ef76035f50a1147a0d39b3d9c1b80b92a2961028 (patch) | |
tree | 08c7848a52d5b73257f8a36d8b02449b8e9294de /include/net/tcp.h | |
parent | 830b3c68c1fb1e9176028d02ef86f3cf76aa2476 (diff) | |
download | linux-ef76035f50a1147a0d39b3d9c1b80b92a2961028.tar.gz |
tcp: Also use tcp_fin_timeout as TCP TIME_WAIT timeout for loopback connections
On loopback connections, reuse the configured tpc_fin_timeout to kill the socket regardless of the socket state. This is done to make sure apps that were killed can always quickly reuse their TCP port instead of waiting for one minute to do so. https://gitlab.steamos.cloud/jupiter/tasks/-/issues/429 Signed-off-by: André Almeida <andrealmeid@collabora.com> (cherry picked from commit f90f986107f1bf0b270f6ff69dd7e58530459db7) Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r-- | include/net/tcp.h | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h index 14d45661a84d..6517a6798d6f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -122,6 +122,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */ +#define TCP_TIMEWAIT_LEN_MIN (1*HZ) #define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN /* BSD style FIN_WAIT2 deadlock breaker. * It used to be 3min, new value is 60sec, @@ -1549,6 +1550,34 @@ static inline int tcp_fin_time(const struct sock *sk) return fin_timeout; } +static inline int tcp_timewait_len(const struct inet_timewait_sock *tw) +{ + bool loopback = false; + + if (tw->tw_bound_dev_if == LOOPBACK_IFINDEX) + loopback = true; +#if IS_ENABLED(CONFIG_IPV6) + else if (tw->tw_family == AF_INET6) { + if (ipv6_addr_loopback(&tw->tw_v6_daddr) || + ipv6_addr_v4mapped_loopback(&tw->tw_v6_daddr) || + ipv6_addr_loopback(&tw->tw_v6_rcv_saddr) || + ipv6_addr_v4mapped_loopback(&tw->tw_v6_rcv_saddr)) + loopback = true; + } +#endif + else + { + if (ipv4_is_loopback(tw->tw_daddr) || + ipv4_is_loopback(tw->tw_rcv_saddr)) + loopback = true; + } + + if (!loopback) + return TCP_TIMEWAIT_LEN; + + return max(TCP_TIMEWAIT_LEN_MIN, sock_net((const struct sock*)tw)->ipv4.sysctl_tcp_fin_timeout); +} + static inline bool tcp_paws_check(const struct tcp_options_received *rx_opt, int paws_win) { |