linux/net/ipv4
Jason Xing 5cce1c07bf tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process
[ Upstream commit 0d9e5df4a2 ]

We found that one close-wait socket was reset by the other side
due to a new connection reusing the same port which is beyond our
expectation, so we have to investigate the underlying reason.

The following experiment is conducted in the test environment. We
limit the port range from 40000 to 40010 and delay the time to close()
after receiving a fin from the active close side, which can help us
easily reproduce like what happened in production.

Here are three connections captured by tcpdump:
127.0.0.1.40002 > 127.0.0.1.9999: Flags [S], seq 2965525191
127.0.0.1.9999 > 127.0.0.1.40002: Flags [S.], seq 2769915070
127.0.0.1.40002 > 127.0.0.1.9999: Flags [.], ack 1
127.0.0.1.40002 > 127.0.0.1.9999: Flags [F.], seq 1, ack 1
// a few seconds later, within 60 seconds
127.0.0.1.40002 > 127.0.0.1.9999: Flags [S], seq 2965590730
127.0.0.1.9999 > 127.0.0.1.40002: Flags [.], ack 2
127.0.0.1.40002 > 127.0.0.1.9999: Flags [R], seq 2965525193
// later, very quickly
127.0.0.1.40002 > 127.0.0.1.9999: Flags [S], seq 2965590730
127.0.0.1.9999 > 127.0.0.1.40002: Flags [S.], seq 3120990805
127.0.0.1.40002 > 127.0.0.1.9999: Flags [.], ack 1

As we can see, the first flow is reset because:
1) client starts a new connection, I mean, the second one
2) client tries to find a suitable port which is a timewait socket
   (its state is timewait, substate is fin_wait2)
3) client occupies that timewait port to send a SYN
4) server finds a corresponding close-wait socket in ehash table,
   then replies with a challenge ack
5) client sends an RST to terminate this old close-wait socket.

I don't think the port selection algo can choose a FIN_WAIT2 socket
when we turn on tcp_tw_reuse because on the server side there
remain unread data. In some cases, if one side haven't call close() yet,
we should not consider it as expendable and treat it at will.

Even though, sometimes, the server isn't able to call close() as soon
as possible like what we expect, it can not be terminated easily,
especially due to a second unrelated connection happening.

After this patch, we can see the expected failure if we start a
connection when all the ports are occupied in fin_wait2 state:
"Ncat: Cannot assign requested address."

Reported-by: Jade Dong <jadedong@tencent.com>
Signed-off-by: Jason Xing <kernelxing@tencent.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20240823001152.31004-1-kerneljasonxing@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2024-10-10 11:57:26 +02:00
..
bpfilter net: Use umd_cleanup_helper() 2023-05-31 13:06:57 +02:00
netfilter netfilter: nf_tables: prevent nf_skb_duplicated corruption 2024-10-10 11:57:15 +02:00
af_inet.c net: relax socket state check at accept time. 2024-06-12 11:12:50 +02:00
ah4.c net: ipv4: Remove completion function scaffolding 2023-02-13 18:35:15 +08:00
arp.c arp: Prevent overflow in arp_req_get(). 2024-03-01 13:35:08 +01:00
bpf_tcp_ca.c bpf: Drop useless btf_vmlinux in bpf_tcp_ca 2023-07-18 17:31:10 -07:00
cipso_ipv4.c cipso: fix total option length computation 2024-06-27 13:49:06 +02:00
datagram.c ipv4: fix data-races around inet->inet_id 2023-08-20 11:40:49 +01:00
devinet.c ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR). 2024-10-10 11:57:26 +02:00
esp4.c net: esp: cleanup esp_output_tail_tcp() in case of unsupported ESPINTCP 2024-08-03 08:53:36 +02:00
esp4_offload.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2023-06-22 18:40:38 -07:00
fib_frontend.c ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family 2024-10-10 11:57:26 +02:00
fib_lookup.h Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-02-17 11:44:20 -08:00
fib_notifier.c net: ipv4: remove superfluous header files from fib_notifier.c 2021-09-28 17:32:56 -07:00
fib_rules.c ipv4: remove unnecessary type castings 2022-04-30 15:12:58 +01:00
fib_semantics.c net: remove NULL-pointer net parameter in ip_metrics_convert 2024-09-08 07:54:45 +02:00
fib_trie.c ipv4: Fix incorrect TOS in route get reply 2024-08-03 08:54:05 +02:00
fou_bpf.c bpf,fou: Add bpf_skb_{set,get}_fou_encap kfuncs 2023-04-12 16:40:39 -07:00
fou_core.c fou: fix initialization of grc 2024-09-18 19:24:09 +02:00
fou_nl.c net: ynl: prefix uAPI header include with uapi/ 2023-05-26 10:30:14 +01:00
fou_nl.h net: ynl: prefix uAPI header include with uapi/ 2023-05-26 10:30:14 +01:00
gre_demux.c net: Remove the member netns_ok 2021-05-17 15:29:35 -07:00
gre_offload.c net: move gso declarations and functions to their own files 2023-06-10 00:11:41 -07:00
icmp.c icmp: change the order of rate limits 2024-10-04 16:29:56 +02:00
igmp.c ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet 2023-12-08 08:52:21 +01:00
inet_connection_sock.c Fix race for duplicate reqsk on identical SYN 2024-07-05 09:33:48 +02:00
inet_diag.c inet_diag: Initialize pad field in struct inet_diag_req_v2 2024-07-11 12:49:14 +02:00
inet_fragment.c inet: inet_defrag: prevent sk release while still in use 2024-04-10 16:35:44 +02:00
inet_hashtables.c tcp: Fix refcnt handling in __inet_hash_connect(). 2024-03-26 18:20:08 -04:00
inet_timewait_sock.c tcp/dccp: do not care about families in inet_twsk_purge() 2024-08-29 17:33:46 +02:00
inetpeer.c inetpeer: Fix data-races around sysctl. 2022-07-08 12:10:33 +01:00
ip_forward.c net: ipv4, ipv6: fix IPSTATS_MIB_OUTOCTETS increment duplicated 2023-08-30 09:44:09 +01:00
ip_fragment.c inet: inet_defrag: prevent sk release while still in use 2024-04-10 16:35:44 +02:00
ip_gre.c ipv4: ip_gre: Fix drops of small packets in ipgre_xmit 2024-10-10 11:57:17 +02:00
ip_input.c ipv4: ignore dst hint for multipath routes 2023-09-01 08:11:51 +01:00
ip_options.c ipv4: drop fragmentation code from ip_options_build() 2022-01-29 17:53:07 +00:00
ip_output.c ipv4: Fix uninit-value access in __ip_make_skb() 2024-05-17 12:02:07 +02:00
ip_sockglue.c ipmr: fix kernel panic when forwarding mcast packets 2024-02-05 20:14:35 +00:00
ip_tunnel.c net: add netdev_lockdep_set_classes() to virtual drivers 2024-04-13 13:07:30 +02:00
ip_tunnel_core.c tunnels: fix out of bounds access when building IPv6 PMTU error 2024-02-16 19:10:48 +01:00
ip_vti.c ip_vti: fix potential slab-use-after-free in decode_session6 2023-07-11 11:06:08 +02:00
ipcomp.c xfrm: ipcomp: add extack to ipcomp{4,6}_init_state 2022-09-29 07:18:00 +02:00
ipconfig.c net: ipconfig: move ic_nameservers_fallback into #ifdef block 2023-05-22 11:17:55 +01:00
ipip.c ipip,ip_tunnel,sit: Add FOU support for externally controlled ipip devices 2023-04-12 16:40:39 -07:00
ipmr.c ipmr: fix incorrect parameter validation in the ip_mroute_getsockopt() function 2024-03-26 18:19:40 -04:00
ipmr_base.c ipmr: adopt rcu_read_lock() in mr_dump() 2022-06-24 11:34:38 +01:00
Kconfig tcp: configurable source port perturb table size 2022-11-16 13:02:04 +00:00
Makefile bpf,fou: Add bpf_skb_{set,get}_fou_encap kfuncs 2023-04-12 16:40:39 -07:00
metrics.c net: remove NULL-pointer net parameter in ip_metrics_convert 2024-09-08 07:54:45 +02:00
netfilter.c netfilter: Use l3mdev flow key when re-routing mangled packets 2022-05-16 13:03:29 +02:00
netlink.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
nexthop.c net: nexthop: Initialize all fields in dumped nexthops 2024-08-03 08:54:38 +02:00
ping.c bpf: Propagate modified uaddrlen from cgroup sockaddr programs 2024-01-31 16:19:04 -08:00
proc.c net: fix IPSTATS_MIB_OUTPKGS increment in OutForwDatagrams. 2024-04-03 15:28:39 +02:00
protocol.c net: Remove the member netns_ok 2021-05-17 15:29:35 -07:00
raw.c ipv4: Fix uninit-value access in __ip_make_skb() 2024-05-17 12:02:07 +02:00
raw_diag.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2023-04-06 12:01:20 -07:00
route.c ipv4: Fix incorrect source address in Record Route option 2024-08-03 08:54:37 +02:00
syncookies.c tcp: annotate data-races around tp->window_clamp 2024-08-11 12:47:19 +02:00
sysctl_net_ipv4.c networking: Update to register_net_sysctl_sz 2023-08-15 15:26:18 -07:00
tcp.c tcp: annotate data-races around tp->window_clamp 2024-08-11 12:47:19 +02:00
tcp_bbr.c bpf: Add __bpf_kfunc tag to all kfuncs 2023-02-02 00:25:14 +01:00
tcp_bic.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_bpf.c tcp_bpf: fix return value of tcp_bpf_sendmsg() 2024-09-12 11:11:28 +02:00
tcp_cdg.c Random number generator fixes for Linux 6.1-rc1. 2022-10-16 15:27:07 -07:00
tcp_cong.c net: remove NULL-pointer net parameter in ip_metrics_convert 2024-09-08 07:54:45 +02:00
tcp_cubic.c bpf: Add __bpf_kfunc tag to all kfuncs 2023-02-02 00:25:14 +01:00
tcp_dctcp.c tcp: Fix shift-out-of-bounds in dctcp_update_alpha(). 2024-06-12 11:12:48 +02:00
tcp_dctcp.h tcp: refactor DCTCP ECN ACK handling 2018-10-10 22:26:00 -07:00
tcp_diag.c tcp: Access &tcp_hashinfo via net. 2022-09-20 10:21:49 -07:00
tcp_fastopen.c inet: move inet->defer_connect to inet->inet_flags 2023-08-16 11:09:18 +01:00
tcp_highspeed.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_htcp.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_hybla.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_illinois.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_input.c tcp: process the 3rd ACK with sk_socket for TFO/MPTCP 2024-09-12 11:11:40 +02:00
tcp_ipv4.c tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process 2024-10-10 11:57:26 +02:00
tcp_lp.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_metrics.c tcp_metrics: optimize tcp_metrics_flush_all() 2024-08-19 06:04:25 +02:00
tcp_minisocks.c tcp: do not export tcp_twsk_purge() 2024-08-29 17:33:57 +02:00
tcp_nv.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_offload.c net: drop bad gso csum_start and offset in virtio_net_hdr 2024-08-14 13:58:48 +02:00
tcp_output.c tcp: annotate data-races around tp->window_clamp 2024-08-11 12:47:19 +02:00
tcp_plb.c prandom: remove prandom_u32_max() 2022-12-20 03:13:45 +01:00
tcp_rate.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-04-28 13:02:01 -07:00
tcp_recovery.c tcp: fix excessive TLP and RACK timeouts from HZ rounding 2023-10-17 17:25:42 -07:00
tcp_scalable.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_timer.c tcp: fix race in tcp_write_err() 2024-08-03 08:53:37 +02:00
tcp_ulp.c net/ulp: use consistent error code when blocking ULP 2023-01-19 09:26:16 -08:00
tcp_vegas.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_vegas.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
tcp_veno.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_westwood.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tcp_yeah.c tcp: add accessors to read/set tp->snd_cwnd 2022-04-06 12:05:41 -07:00
tunnel4.c net: Remove the member netns_ok 2021-05-17 15:29:35 -07:00
udp.c udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). 2024-07-18 13:21:14 +02:00
udp_bpf.c bpf, sockmap: Fix an infinite loop error when len is 0 in tcp_bpf_recvmsg_parser() 2023-03-03 17:25:15 +01:00
udp_diag.c udp: Access &udp_table via net. 2022-11-16 09:43:35 +00:00
udp_impl.h sock: Remove ->sendpage*() in favour of sendmsg(MSG_SPLICE_PAGES) 2023-06-24 15:50:13 -07:00
udp_offload.c udp: fix receiving fraglist GSO packets 2024-08-29 17:33:48 +02:00
udp_tunnel_core.c udp: lockless UDP_ENCAP_L2TPINUDP / UDP_GRO 2023-11-20 11:58:56 +01:00
udp_tunnel_nic.c udp_tunnel: Add checks for nla_nest_start() in __udp_tunnel_nic_dump_write() 2022-11-29 08:44:24 -08:00
udp_tunnel_stub.c udp_tunnel: add central NIC RX port offload infrastructure 2020-07-10 13:54:00 -07:00
udplite.c udplite: remove UDPLITE_BIT 2023-11-20 11:58:56 +01:00
xfrm4_input.c xfrm: Preserve vlan tags for transport mode software GRO 2024-05-17 12:02:20 +02:00
xfrm4_output.c xfrm: fix unused variable warning if CONFIG_NETFILTER=n 2020-05-11 15:12:27 +02:00
xfrm4_policy.c sysctl-6.6-rc1 2023-08-29 17:39:15 -07:00
xfrm4_protocol.c net: xfrm: unexport __init-annotated xfrm4_protocol_init() 2022-06-08 10:10:13 -07:00
xfrm4_state.c xfrm: remove output_finish indirection from xfrm_state_afinfo 2020-05-06 09:40:08 +02:00
xfrm4_tunnel.c xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state 2022-09-29 07:18:00 +02:00