Commit graph

1 commit

Author SHA1 Message Date
Leadaxe
d31d20ba58 system stack: self-heal the TCP forwarder accept loop (sing-box-lx SPEC 040)
Upstream acceptLoop treats any Accept error as terminal and silently
returns, leaving the stack alive but every new TCP SYN NAT-rewritten onto
a dead port (instant RST) until a full restart. When the listener fd is
closed out from under the stack (a stray close on a reused fd number from
another runtime in the same process), all new TCP dies forever while
UDP/QUIC/DNS keep working.

- System.Close() now marks a deliberate shutdown first; acceptLoop still
  exits quietly on it.
- Any other Accept error is logged (the errno names the killer path),
  the listener is recreated on the same address, the forwarder port is
  republished atomically, and the loop keeps serving.
- If the rebind fails, the loop logs an error and gives up - no worse
  than upstream.
- acceptRecoveries counter is kept as telemetry.

tcpPort/tcpPort6 become atomic (written by the heal path, read from the
tunLoop dispatch/NAT path); listener replacement is serialized against
Close() with a mutex.
2026-08-05 16:57:11 +03:00