opnsense-src/sys/netinet
Gleb Smirnoff 1bda3fae78 tcp: don't ever return ECONNRESET on close(2)
The SUS doesn't mention this error code as a possible one [1]. The FreeBSD
manual page specifies a possible ECONNRESET for close(2):

[ECONNRESET]	The underlying object was a stream socket that was
		shut down by the peer before all pending data was
		delivered.

In the past it had been EINVAL (see 21367f630d), and this EINVAL was
added as a safety measure in 623dce13c6.  After conversion to
ECONNRESET it had been documented in the manual page in 78e3a7fdd5, but
I bet wasn't ever tested to actually be ever returned, cause the
tcp-testsuite[2] didn't exist back then.  So documentation is incorrect
since 2006, if my bet wins.  Anyway, in the modern FreeBSD the condition
described above doesn't end up with ECONNRESET error code from close(2).
The error condition is reported via SO_ERROR socket option, though.  This
can be checked using the tcp-testsuite, temporarily disabling the
getsockopt(SO_ERROR) lines using sed command [3].  Most of these
getsockopt(2)s are followed by '+0.00 close(3) = 0', which will confirm
that close(2) doesn't return ECONNRESET even on a socket that has the
error stored, neither it is returned in the case described in the manual
page.  The latter case is covered by multiple tests residing in tcp-
testsuite/state-event-engine/rcv-rst-*.

However, the deleted block of code could be entered in a race condition
between close(2) and processing of incoming packet, when connection had
already been half-closed with shutdown(SHUT_WR) and sits in TCPS_LAST_ACK.
This was reported in the bug 146845.  With the block deleted, we will
continue into tcp_disconnect() which has proper handling of INP_DROPPED.

The race explanation follows.  The connection is in TCPS_LAST_ACK.  The
network input thread acquires the tcpcb lock first, sets INP_DROPPED,
acquires the socket lock in soisdisconnected() and clears SS_ISCONNECTED.
Meanwhile, the syscall thread goes through sodisconnect() which checks for
SS_ISCONNECTED locklessly(!).  The check passes and the thread blocks on
the tcpcb lock in tcp_usr_disconnect().  Once input thread releases the
lock, the syscall thread observes INP_DROPPED and returns ECONNRESET.

- Thread 1: tcp_do_segment()->tcp_close()->in_pcbdrop(),soisdisconnected()
- Thread 2: sys_close()...->soclose()->sodisconnect()->tcp_usr_disconnect()

Note that the lockless operation in sodisconnect() isn't correct, but
enforcing the socket lock there will not fix the problem.

[1] https://pubs.opengroup.org/onlinepubs/9799919799/
[2] https://github.com/freebsd-net/tcp-testsuite
[3] sed -i "" -Ee '/\+0\.00 getsockopt\(3, SOL_SOCKET, SO_ERROR, \[ECONNRESET\]/d' $(grep -lr ECONNRESET tcp-testsuite)

PR:			146845
Reviewed by:		tuexen, rrs, imp
Differential Revision:	https://reviews.freebsd.org/D48148

(cherry picked from commit 053a988497342a6fd0a717cc097d09c23f83e103)
2025-03-31 10:31:21 -07:00
..
cc tcp cc: Remove a stray semicolon 2024-10-31 12:40:18 +08:00
khelp sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
libalias libalias: fix subtle racy problem in outside-inside forwarding 2024-08-25 13:31:24 +07:00
netdump netdump: Check the return value of ifunit_ref() 2023-10-08 20:41:42 -04:00
tcp_stacks TCP BBR: remove dead code 2025-02-05 11:04:01 +01:00
accf_data.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
accf_dns.c sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
accf_http.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
dccp.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
icmp6.h icmp6: move ICMPv6 related tunables to the files where they are used 2024-06-26 12:48:44 +08:00
icmp_var.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
if_ether.c netinet: enter epoch in garp_rexmit() 2025-01-27 10:04:34 +01:00
if_ether.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
igmp.c netinet: Remove stale references to Giant from comments 2024-02-03 14:10:36 -05:00
igmp.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
igmp_var.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
in.c netinet: Make in_canforward() return bool 2025-03-07 12:02:41 +08:00
in.h netinet: Make in_canforward() return bool 2025-03-07 12:02:41 +08:00
in_cksum.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_debug.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_fib.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_fib.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
in_fib_algo.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_fib_dxr.c fib_dxr: code hygiene, prune old code, no functional changes 2024-05-22 19:34:40 +02:00
in_gif.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_jail.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_kdtrace.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_kdtrace.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
in_mcast.c mcast: fix leaked igmp packets on multicast cleanup 2024-08-26 09:46:21 -06:00
in_pcb.c inpcb: Add FIB-aware inpcb lookup 2025-02-21 01:04:50 +00:00
in_pcb.h inpcb: Move the definition of struct inpcblbgroup to in_pcb_var.h 2025-02-21 01:04:50 +00:00
in_pcb_var.h inpcb: Move the definition of struct inpcblbgroup to in_pcb_var.h 2025-02-21 01:04:50 +00:00
in_prot.c Fix 'security.bsd.see_jail_proc' by using cr_bsd_visible() 2023-10-17 16:42:58 -03:00
in_proto.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_rmx.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
in_rss.c sys: Remove $FreeBSD$: two-line .c pattern 2023-08-16 11:54:30 -06:00
in_rss.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
in_systm.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
in_var.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
ip.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
ip6.h netinet: Define IPv6 ECN mask 2024-01-11 09:18:12 -05:00
ip_carp.c carp: Use static initializers 2025-03-13 18:13:50 +08:00
ip_carp.h sys: Remove $FreeBSD$: one-line .c comment pattern 2023-08-16 11:54:24 -06:00
ip_carp_nl.h carp: allow commands to use interface name rather than index 2023-03-31 11:29:58 +02:00
ip_divert.c pf: use an enum for packet direction in divert tag 2023-11-09 10:56:20 +01:00
ip_divert.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
ip_dummynet.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
ip_ecn.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
ip_ecn.h sys: Remove $FreeBSD$: one-line .c comment pattern 2023-08-16 11:54:24 -06:00
ip_encap.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
ip_encap.h sys: Remove $FreeBSD$: one-line .c comment pattern 2023-08-16 11:54:24 -06:00
ip_fastfwd.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
ip_fw.h ipfw: Fix a typo in a source code comment 2024-05-16 07:59:09 +02:00
ip_gre.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
ip_icmp.c netinet: Do not forward or ICMP response to INADDR_ANY 2025-03-07 12:02:41 +08:00
ip_icmp.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
ip_id.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
ip_input.c netinet: Make in_canforward() return bool 2025-03-07 12:02:41 +08:00
ip_mroute.c ip_mroute: Use NET_EPOCH_WAIT() macro 2024-07-05 23:11:51 +08:00
ip_mroute.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
ip_options.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
ip_options.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
ip_output.c ip_output(): style 2025-03-17 02:48:33 +02:00
ip_reass.c vnet: (read) lock the vnet list while iterating it 2023-12-14 12:20:25 +01:00
ip_var.h ip_var.h: align comment style 2023-11-09 10:56:26 +01:00
pim.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
pim_var.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
raw_ip.c rawip: Add a bind_all_fibs sysctl 2025-02-21 01:04:50 +00:00
sctp.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_asconf.c sctp: improve debug output 2024-10-31 12:41:06 +01:00
sctp_asconf.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_auth.c sctp: cleanup locking for notifications 2023-09-15 19:41:16 +02:00
sctp_auth.h sctp: cleanup SCTP AUTH related notification 2023-09-15 19:35:57 +02:00
sctp_bsd_addr.c sctp: improve handling of address changes 2024-11-06 10:12:28 +01:00
sctp_bsd_addr.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_cc_functions.c sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_constants.h sctp: make sure all SCTP RESET notifications use sctp_ulp_notify() 2023-09-15 19:38:29 +02:00
sctp_crc32.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
sctp_crc32.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_header.h sctp: store heartbeat creation time as time_t 2024-08-04 00:27:00 +02:00
sctp_indata.c sctp: improve input validation for data chunks 2024-08-06 23:32:06 +02:00
sctp_indata.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_input.c sctp: store cookie secret change time as time_t 2024-08-04 00:25:22 +02:00
sctp_input.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_kdtrace.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
sctp_kdtrace.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_lock_bsd.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_module.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
sctp_os.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_os_bsd.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_output.c sctp: improve debug output 2024-10-31 12:41:06 +01:00
sctp_output.h sctp: improve sending of packets containing an INIT ACK chunk 2024-04-17 15:47:17 +02:00
sctp_pcb.c sctp: fix debug message 2024-11-06 10:13:14 +01:00
sctp_pcb.h sctp: improve handling of address changes 2024-11-06 10:12:28 +01:00
sctp_peeloff.c sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_peeloff.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_ss_functions.c sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_structs.h sctp: cleanup handling of graceful shutdown of the peer 2023-08-19 12:35:49 +02:00
sctp_syscalls.c sctp: propagate cap rights on sctp_peeloff 2024-10-17 12:29:21 -04:00
sctp_sysctl.c sctp: fix format of sysctl variables 2024-08-30 08:31:35 +02:00
sctp_sysctl.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_timer.c sctp: cleanup 2023-09-15 19:30:51 +02:00
sctp_timer.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_uio.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctp_usrreq.c sctp: further improve shutting down the read side of a socket 2023-09-15 19:48:02 +02:00
sctp_var.h sctp: cleanup cdefs.h include 2023-08-18 15:25:34 +02:00
sctputil.c sctp: improve heartbeat timer computation 2024-08-04 00:27:53 +02:00
sctputil.h sctp: make sure all SCTP RESET notifications use sctp_ulp_notify() 2023-09-15 19:38:29 +02:00
siftr.c siftr: remove the shutdown_pre_sync event handler on unload 2024-08-02 09:30:38 +02:00
tcp.h tcp: Add a new kernel-only TCP_USE_DDP socket option 2024-04-12 12:25:11 -07:00
tcp_accounting.h Move access to tcp's t_logstate into inline functions and provide new tracepoint and bbpoint capabilities. 2023-03-16 11:43:16 -04:00
tcp_ecn.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
tcp_ecn.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
tcp_fastopen.c tcp_fastopen: Fix a typo in a source code comment 2024-01-25 07:44:39 +01:00
tcp_fastopen.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
tcp_fsm.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
tcp_hostcache.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
tcp_hpts.c Optimize HPTS so that little work is done until we have a hpts thread that is over the connection threshold 2024-04-24 22:37:40 +02:00
tcp_hpts.h HTPS has actually three states not two so the macro needs to account for that. 2024-04-24 22:36:32 +02:00
tcp_input.c tcp: fix reverting of spurious timeouts (RTO) 2025-03-24 06:35:43 +01:00
tcp_log_buf.c tcp bblog: use correct length 2024-04-17 15:51:00 +02:00
tcp_log_buf.h tcp: whitespace cleanup of enum tcp_log_events 2024-08-04 00:53:41 +02:00
tcp_lro.c tcp: make tcp_lro_flush() static 2024-10-31 12:20:35 +01:00
tcp_lro.h tcp: make tcp_lro_flush() static 2024-10-31 12:20:35 +01:00
tcp_lro_hpts.c tcp: define tcp_lro_log() only when TCP_BLACKBOX is defined 2025-02-05 08:17:23 +01:00
tcp_offload.c tcp_fill_info(): Change lock assertion on INPCB to locked only 2023-08-22 20:33:49 +02:00
tcp_offload.h tcp_fill_info(): Change lock assertion on INPCB to locked only 2023-08-22 20:33:49 +02:00
tcp_output.c tcp_output: Clear FIN if tcp_m_copym truncates output length 2024-11-30 21:46:04 -05:00
tcp_pcap.c sys: Style fix for M_EXT | M_EXTPG 2024-01-18 14:35:14 -08:00
tcp_pcap.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00
tcp_ratelimit.c tcp_ratelimit: Use static initializers 2025-03-13 18:13:51 +08:00
tcp_ratelimit.h tcp: Silence a -Wunused-function warning in tcp_ratelimit.h 2024-02-18 15:26:28 +01:00
tcp_reass.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
tcp_sack.c tcp: fix duplicate retransmissions when RTO happens during SACK loss recovery 2024-10-18 09:51:38 +02:00
tcp_seq.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
tcp_stats.c sys: Remove $FreeBSD$: one-line .c pattern 2023-08-16 11:54:36 -06:00
tcp_subr.c tcp: initialize V_ts_offset_secret for all vnets 2024-08-12 07:34:35 +02:00
tcp_syncache.c tcp: small cleanup 2024-10-31 12:37:05 +01:00
tcp_syncache.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
tcp_timer.c tcp: fix the initial CWND when a SYN retransmission happened 2025-02-05 08:14:14 +01:00
tcp_timer.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
tcp_timewait.c tcp: improve consistency 2024-04-17 16:00:09 +02:00
tcp_usrreq.c tcp: don't ever return ECONNRESET on close(2) 2025-03-31 10:31:21 -07:00
tcp_var.h tcp: Add a sysctl to modify listening socket FIB inheritance 2025-02-21 01:04:50 +00:00
tcpip.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
toecore.c tcp_fill_info(): Change lock assertion on INPCB to locked only 2023-08-22 20:33:49 +02:00
toecore.h tcp_fill_info(): Change lock assertion on INPCB to locked only 2023-08-22 20:33:49 +02:00
udp.h sys: Remove $FreeBSD$: one-line .h pattern 2023-08-16 11:54:18 -06:00
udp_usrreq.c udp: Do not recursively enter net epoch 2025-03-13 18:13:50 +08:00
udp_var.h udp: Add a sysctl to modify listening socket FIB inheritance 2025-02-21 01:04:50 +00:00
udplite.h sys: Remove $FreeBSD$: two-line .h pattern 2023-08-16 11:54:11 -06:00