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

NAT traversal: TCP hole punching via simultaneous open #1021

Closed
aarshkshah1992 opened this issue Nov 5, 2020 · 5 comments
Closed

NAT traversal: TCP hole punching via simultaneous open #1021

aarshkshah1992 opened this issue Nov 5, 2020 · 5 comments
Assignees

Comments

@aarshkshah1992
Copy link
Contributor

aarshkshah1992 commented Nov 5, 2020

  • Implement TCP hole punching via simultaneous open.
  • The approach is very similar to what we plan to do with QUIC hole punching.
  • One important difference here is to add some retry logic if initial hole punching attempts fail as some nasty NATs can send RSTs or ICMP errors in response to unsolicited SYN packets instead of silently dropping the SYNs.
  • This usually has a lower success rate than UDP because a lot of NATs don’t support consistent endpoint translation for TCP i.e. even if we use the same port for different outgoing connections, we'll get different NAT port mappings.

Reference: https://pdos.csail.mit.edu/papers/p2pnat.pdf

@willscott
Copy link
Contributor

This tends to have quite low success rates because it's trivial from the nat's perspective to identify that the two sides are sending different flows. It's also rare to have nat's where the outbound TCP port will be stable so you can predict the 5 tuple for even attempting the simultaneous open. (citation needed of course, but that's my impression)

@aarshkshah1992
Copy link
Contributor Author

aarshkshah1992 commented Nov 5, 2020

@willscott

  • We can use the same local port for all sockets by using the SO_REUSEPORT and SO_REUSEADDR options when creating them. That should help with getting the same NAT port mappings for all of them.
  • However, you are right. NATs are a bit nasty with doing "consistent endpoint translation" for TCP i.e. even if we use the same local port for all outbound connections, NATs might still assign them different port mappings.

You can find some good info for this in the TCP testing section of https://pdos.csail.mit.edu/papers/p2pnat.pdf.

@willscott
Copy link
Contributor

Right. Most TCP nat mapping will be on the 5 tuple. Initially, many nat devices would use predictable mappings (e.g. the external port would increase by 1 with each subsequent connection). That has stopped happening. Only nat devices that use a stable mapping based on only the internal host:port (the 3 tuple) will be usable, but still, better than not doing it 👍

@aarshkshah1992
Copy link
Contributor Author

@willscott Based on that paper, we're hoping to get ~60% success rates for TCP hole punching (much lower than ~85 for QUIC), exactly because of this problem.

But yes, it really does help getting this in as we still rely on TCP over QUIC for a lot of use cases.

@aarshkshah1992
Copy link
Contributor Author

This is now being done as part of #1039.

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

No branches or pull requests

2 participants