-
Notifications
You must be signed in to change notification settings - Fork 296
Description
Background
One can use the same port both listening for incoming connections and dialing outgoing connections. This is controlled via the SO_REUSEPORT socket option.
Port reuse is necessary for hole punching via TCP. It allows one to discover its outwards facing listening port via an outgoing TCP connection. The outgoing connection reuses the local listening port and is thus likely assigned the same outwards facing port as the outward facing listening port on the NAT.
When both endpoints of a connection send the TCP SYN simultaneously, it results not in two TCP connections but in one. On that TCP connections both endpoints assume to be the dialer (see sim-open spec for details.
Tie breaking on a simultaneous open TCP connection where both endpoints assume to be the dialer can today be done either via:
On hole punched, i.e. coordinated, TCP simultaneous open connections tie breaking via DCUtR can be used. (Tie breaking could as well be done via Multistream Select simultaneous open here, though that is less efficient as it requires more roundtrips and the tie breaking via DCUtR is available for free.)
On non-coordinated, i.e. accidental, TCP simultaneous open connections only tie breaking via Multistream Select simultaneous open can be used. This is problematic as we would like to move away from Multistream Select, replacing it with Protocol Select (see #349). Protocol Select does not support tie breaking, see "TCP Simultaneous Open" section in Protocol Select specification.
Thus far we planned to simply not-support non-coordinated, i.e. accidental, TCP simultaneous open connections. In such cases, as both endpoint assume to be the dialer and as there is no tie breaking mechanism in place, the connection upgrade would simply fail. In #349 we argue that the low probability of such non-coordinated TCP simultaneous open connection is too low for it to be special cased.
Proposal
We could do port reuse on coordinated TCP hole-punched connections only and use a new port (default TCP behaviour) for all other outgoing TCP connections. This would prevent the case of uncoordinated TCP simultaneous open and thus dissolve the need for tie breaking on uncoordinated accidentally simultaneously dialed TCP connections.
There are two problems with this proposal:
- How does one discover ones outwards-facing listening port? Previously done via non-holepunching outgoing TCP connections reusing the local listening port.
- How does one keep the port-mapping of ones listening port on the NAT alive. Previously done via non-holepunching outgoing TCP connections reusing the local listening port.
Would it be worth special casing specific outgoing connections (e.g. used for AutoNAT and identify) and have them reuse the listening TCP port, despite not being a hole-punching connection?
Would it be safe to not do port-reuse when one is public, i.e. directly reachable?
Credit for the proposal goes to @hamamo.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status