-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Don't hole punch if either peer is behind a Symmetric NAT #1046
Don't hole punch if either peer is behind a Symmetric NAT #1046
Conversation
Based on an offline discussion with @willscott The fact that we dial a peer if it has any public addresses at all before giving up on Hole Punching due to NAT types will take care of Full Cone NATs. It will break for address restricted Cones. So, we need to look at how our current code performs in the wild (with some stats around failures rates) to decide if we need to remove the restriction this PR introduces. |
but after my experiment, some operators can make reverse connections through the opened ports. |
@godcong Yeah, that's a FULL Cone NAT. This PR will dial public addresses before giving up because of the NAT type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple of nits, but overall looks good.
p2p/protocol/identify/id.go
Outdated
UDPNATDeviceTypeKey = "UdpNATDeviceType" | ||
// TCPNATDeviceTypeKey is the key with which we will persist a peer's TCP NAT Device Type to the peerstore. | ||
TCPNATDeviceTypeKey = "TcpNATDeviceType" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
funky capitalization in the strings; it's UDP
not Udp
and same for TCP
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
UNKNOWN = 100; | ||
CONE = 200; | ||
SYMMETRIC = 300; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0,1,2...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
optional NATDeviceType tcpNATDeviceType = 10; | ||
optional NATDeviceType udpNATDeviceType = 11; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
few more comments.
|
||
for { | ||
select { | ||
case _, ok := <-sub.Out(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we look at the actual event? why are we ignoring it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, where do we set the support meta-variables into the peerstore?
Shouldn't we be doing it here? Or is it handled elsewhere?
I think we need a comment if this is correct as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Our local vars are set in the peerstore in
basic_host.go
during initialisation of the Host & updated in the obs addr manager. -
Remote vars are set in the peerstore by Identify.
Both changes are included in this PR. I've added a comment.
p2p/protocol/identify/id.go
Outdated
|
||
return mes | ||
} | ||
|
||
func toPbNATDeviceTyp(typ network.NATDeviceType) pb.Identify_NATDeviceType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo in method name; shouldn't this be Type?
Also, typ is a very funky variable name, better call it just t
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing the handler is a BUG.
if hs.peerSupportsHolePunching(hs.host.ID(), hs.host.Addrs()) { | ||
hs.host.SetStreamHandler(protocol, hs.handleNewStream) | ||
} else { | ||
hs.host.RemoveStreamHandler(protocol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, this is a BUG -- we lose the ability to dial back connect to a public node that has dialed us.
oh wait, nvm we just direct dial back when we see the relayed connection without coordination. Sorry about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased and addressed review.
|
||
for { | ||
select { | ||
case _, ok := <-sub.Out(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Our local vars are set in the peerstore in
basic_host.go
during initialisation of the Host & updated in the obs addr manager. -
Remote vars are set in the peerstore by Identify.
Both changes are included in this PR. I've added a comment.
p2p/protocol/identify/id.go
Outdated
|
||
return mes | ||
} | ||
|
||
func toPbNATDeviceTyp(typ network.NATDeviceType) pb.Identify_NATDeviceType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
p2p/protocol/identify/obsaddr.go
Outdated
@@ -200,6 +207,21 @@ func (oas *ObservedAddrManager) filter(observedAddrs []*observedAddr) []ma.Multi | |||
} | |||
} | |||
|
|||
// For certain use cases such as hole punching, it's better to advertise even unactivated observed addresses rather than none at all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vyzo This needs your attention. I discussed this with @Stebalien and he was okay with it.
…update-deps update deps due to license
@marten-seemann @vyzo @aarshkshah1992 : I'm putting this back to draft for now. Feel free to close if that's the better option. |
I actually think we ahould close it, i personally find it dangerous. |
@aarshkshah1992 @BigLep @vyzo @marten-seemann |
For #1039.
If either peer is behind a Symmetric NAT, there's no point in wasting a hole punch and bandwidth on Relay servers.
TODO