For some reason, netstack keep the closed endpoint in the Endpoint map for a while after the connection is closed. At this time, if a new incoming connection reuses the same local-port, the TCP connection quadruple(srcIP, dstIP, srcPort, dstPort) matches the endpoints map. Then the Forwarder cannot receive the new incoming connection.
Clash can only accept around 7k connections and then stop to accept a new TCP connection.
Analysis:
Clash set up a
Forwarder
to accept all new TCP connection https://github.com/comzyh/clash/blob/ab7da17a75c2626fcd49d3e69080fa6536391ddb/proxy/tun/tunproxy.go#L82-L97According to gvisor netstack, netstack first check if there is an Endpoint match the incoming packet. If not, call the Forwarder I write. https://github.com/google/gvisor/blob/035f7434e978f3f246ae05e9c748e8ca7d8d7fd1/pkg/tcpip/stack/nic.go#L1301-L1311
For some reason, netstack keep the closed endpoint in the Endpoint map for a while after the connection is closed. At this time, if a new incoming connection reuses the same local-port, the TCP connection quadruple(srcIP, dstIP, srcPort, dstPort) matches the endpoints map. Then the Forwarder cannot receive the new incoming connection.