-
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
Emit event for User's NAT Type i.e. Hard NAT or Easy NAT #1042
Conversation
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.
I am a little sceptical about the activated address heuristic; if we have one, then yes we are obviously behind an easy NAT.
But if we don't we might still be behind a penetrable NAT, especially with UDP.
We don't determine the NAT to be hard simply if we don't have an activated address. We determine the NAT to be hard when four different peers report four different observed addresses on outbound connections. I think this should be good enough to conclude that the NAT is bad, no ? We can augment the code to report NAT types separately for UDP & non-UDP connections if that's what you mean. |
Yeah, we should probably do that. |
p2p/protocol/identify/obsaddr.go
Outdated
oas.emitUDPTypeUnlocked(allObserved) | ||
} | ||
|
||
func (oas *ObservedAddrManager) emitTCPNATTypeUnlocked(addrs []*observedAddr) { |
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.
this and the subsequent emitUDPNATTypeUnlocked
are doing basically the same thing. can you factor out a common method that takes an additional parameter (ma.P_TCP
vs ma.P_UDP
)?
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.
This is done.
@willscott I've addressed both your comments. Have also tested this on my machine for both TCP & QUIC and it looks good. |
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.
one minor nit, and you need to get the dependencies merged and go.mod pulled up to versions before merging, but this seems ready.
p2p/protocol/identify/obsaddr.go
Outdated
// | ||
// Please see the documentation on the enumerations for `network.NATDeviceType` for more details about these NAT Device types | ||
// and how they relate to NAT traversal via Hole Punching. | ||
func (oas *ObservedAddrManager) emitNATTypeUnlocked() { |
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.
why is this method named Unlocked
? maybe this is observeAllNATTypes
and the next one is observeSpecificNATType
? the naming of the two feels not quite representative of what they do.
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.
yeah what's with the name? Is there a locked variant?
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.
Have fixed this.
cc @vyzo |
p2p/protocol/identify/obsaddr.go
Outdated
// | ||
// Please see the documentation on the enumerations for `network.NATDeviceType` for more details about these NAT Device types | ||
// and how they relate to NAT traversal via Hole Punching. | ||
func (oas *ObservedAddrManager) emitNATTypeUnlocked() { |
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.
yeah what's with the name? Is there a locked variant?
p2p/protocol/identify/obsaddr.go
Outdated
|
||
// returns true along with the new NAT device type if the NAT device type for the given protocol has changed. | ||
// returns false otherwise. | ||
func (oas *ObservedAddrManager) emitNATType(addrs []*observedAddr, protoCode int, transportProto event.NATTransportProtocol, |
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.
This could range from a little to very expensive.
How often do we call it?
Can we skip it altogether if we are not NATted?
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.
- What makes this expensive ?
- We call it every-time we have a new observed address but this function will return as soon as it sees any activated address.
The problem with skipping it altogether if we are not NATT'd is that AutoNAT dosen't take into account TCP vs UDP whereas we want to emit separate events for both.
Do you mean to say that we should emit this event for both TCP & UDP ONLY if reachability is private ?
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.
Imagine a big public peer with thousands of connections, this could become problematic.
And yes, this event is only relevant if we have private reachability and can/should be skipped altogether if we are public.
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.
5bcd646
to
df2b0be
Compare
Please can you take a look ? |
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.
One bug and a bunch of stylistic issues...
p2p/protocol/identify/obsaddr.go
Outdated
case evt, ok := <-subChan: | ||
if !ok { | ||
subChan = nil | ||
} | ||
ev := evt.(event.EvtLocalReachabilityChanged) | ||
oas.reachability = ev.Reachability |
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.
this will panic when the channel gets closed, as evt will be nil.
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.
oops :/ Fixed.
p2p/protocol/identify/obsaddr.go
Outdated
for k := range oas.addrs { | ||
allObserved = append(allObserved, oas.addrs[k]...) | ||
} |
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.
Index again when you mean to iterate.... It's more idiomatic to write this as
for _, addrs := range oas.addrs {
allObserved = append(allObserved, addrs...)
}
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.
More pertinent however, do we really need this copy?
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.
well, it's probably a micro-optimization to fix the copy. Have fixed the looping .
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.
no you haven't, it's still there.
p2p/protocol/identify/obsaddr.go
Outdated
for i := range addrs { | ||
oa := addrs[i] |
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.
and here again:
for _, oa := range addrs {
...
}
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
// An observed address on an outbound connection that has ONLY been seen by one peer | ||
if now.Sub(oa.lastSeen) <= oas.ttl && oa.numInbound == 0 && len(oa.seenBy) == 1 { | ||
cnt++ | ||
for s, _ := range oa.seenBy { |
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.
you don't need the , _
.
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.
Have made the changes.
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.
needs a go mod tidy
; also, fix dat loop!
go.mod
Outdated
github.com/google/gopacket v1.1.18 // indirect | ||
github.com/google/uuid v1.1.2 // indirect |
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.
what's that crap popping up? Do a go mod tidy
.
p2p/protocol/identify/obsaddr.go
Outdated
for k := range oas.addrs { | ||
allObserved = append(allObserved, oas.addrs[k]...) | ||
} |
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.
no you haven't, it's still there.
@vyzo This is ready. |
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.
alright, let's merge this.
For #1039.
We should emit an event informing the user of the user's NAT type for better user experience for hole punching/testing Hole punching in the wild.
TODO