Consider only reusing TCP port when hole punching
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 1.8k
- Forks
- 320
- Avg merge
- 11d 15h
- Merged PRs (30d)
- 1
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 https://github.com/libp2p/specs/pull/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 https://github.com/libp2p/specs/pull/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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the linked sim-open, DCUtR, and Protocol Select specifications, then trace how the proposal affects coordinated and accidental TCP simultaneous opens. Done means resolving the port-discovery and NAT-mapping questions and documenting an agreed approach; the issue does not name repository files or tests.
Written by the indexing model from the issue text.
Assessment
- Domain
- networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100