Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Direct Connection Upgrade through Relay #651

Closed
3 tasks
vyzo opened this issue May 30, 2019 · 5 comments
Closed
3 tasks

Support Direct Connection Upgrade through Relay #651

vyzo opened this issue May 30, 2019 · 5 comments
Assignees

Comments

@vyzo
Copy link
Contributor

vyzo commented May 30, 2019

The draft in libp2p/specs#173 specifies a mechanism for upgrading relay connections to direct connections using hole punching.

This issue is here to track implementation changes necessary to support it

  • The swarm needs to support direct dial with user-specified addresses (bypassing the peerstore), even when there is an existing relay connection
  • The swarm needs to be able to prioritize direct connections over relay connections once they exist.
    The current logic picks the connection with the most streams.
  • The most difficult part: multistream is an interactive protocol with a designated initiator (the outbound peer).
    This breaks with simultaneous open, which may result in both peers being the initiators.
    To make things even more complicated, we might end up with a peer accepting and a peer connecting.
    We may have to delay deployment until multistream/2.0 is ready.
@raulk
Copy link
Member

raulk commented Jun 3, 2019

Here's one possible adaptation to multistream 1.0 to cope with TCP simultaneous open, while keeping backwards compatibility. Let's call it ms1.1, although only theoretically; we can't use this ID on the wire because, go-multistream expects an exact match and does not entertain multiple versions in the header.

(Context: We've discussed poison bits (1 for initiator, 0 for responder) to short-circuit the connection in case the AND is true, but that's a backwards-incompatible change. I believe all solutions proposed until now are backwards-incompatible.)

After the initial /multistream/1.0.0 announcement, the node believing it is the initiator signals this belief by sending what seems like an ordinary protocol selection:

/p2p/initiator/1.0.0/<my peer ID>

Various things can happen:

  1. Both parties believe they're the initiator (TCP simultaneous open), and:

    1. they both support ms1.1, in which case each party sees the signal and they resolve the conflict by either: (a) assigning the initiator role to the highest peer ID in-band, (b) closing the connection and having the highest peer restart it.
    2. only one party supports ms1.1, the legacy party will error, but the upgraded party can detect this situation and restart the connection (hoping the router will keep this mapping alive in TIME_WAIT).
  2. Only one party believes they're the initiator (no TCP simultaneous open), and:

    1. they both support ms1.1, the responder confirms by responding with /p2p/responder/1.0.0.
    2. only the initiator supports ms1.1, they'll send /p2p/initiator/1.0.0/<my peer ID>, but they'll simply get a na back. Nothing breaks.
    3. only the responder supports ms1.1, nothing special happens.

@vyzo
Copy link
Contributor Author

vyzo commented Jun 3, 2019

I would like to avoid having to restart the conneciton, it's very complicated to implement and not certain it will work.
But given that we will roll out the connection upgrade protocol together with the multistream upgrade, we should be ok.
So in 1i we should assign as the initiator the highest peer ID in band and not restart the connection (a).

@raulk
Copy link
Member

raulk commented Jun 3, 2019

@vyzo yeah, that option has higher chances of success, however it implies changes in libp2p that may break the abstractions quite a bit.

@Stebalien
Copy link
Member

See libp2p/go-tcp-transport#21 for a list of solutions.

@marten-seemann
Copy link
Contributor

v0.16.0 shipped DCUtR support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants