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: add HasNAT method for checking NAT environments #2346

Closed
wants to merge 3 commits into from

Conversation

sukunrt
Copy link
Member

@sukunrt sukunrt commented Jun 9, 2023

This PR fixes 1 major and 2 minor issues with address inference in NATed environments.

  1. Introduces a check to determine if we have a nat device. This is reasonable. We can never be sure that we will support all NAT devices. In case the user has selected the NATPortMap option and we are unable to do a NAT mapping, we should do address inference using addresses obtained from observed address manager. This is the same behaviour as 0.27
  2. In case we have a NAT device but we failed to do the mapping, we should use the addresses obtained from the observed address manager.
  3. Fixes an edge case for inferring observed addresses for QUIC addresses correctly in case the NAT doesn't give use a publicly routable address. QUIC addresses have local address as 0.0.0.0 and so only checking resolved listen addresses isn't enough, we need to check the unresolved listen address as well.

@sukunrt sukunrt mentioned this pull request Jun 9, 2023
Copy link
Collaborator

@MarcoPolo MarcoPolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test for this?

@sukunrt
Copy link
Member Author

sukunrt commented Jun 9, 2023

Turns out I could add tests. A mocknet would have been nicer though.
TestAllAddrsNAT fails on master and works here.

@sukunrt sukunrt requested a review from MarcoPolo June 9, 2023 18:53
@marten-seemann
Copy link
Contributor

I’ll review this tomorrow.

@marten-seemann
Copy link
Contributor

I have to admit I don't understand this PR. None of the three issues listed.

If these are bugs, we should have issues for them (this applies to all but the most trivial fixes). If these are separate bugs, it would be helpful to have separate PRs for them.

@MarcoPolo
Copy link
Collaborator

Is this fixing a regression from v0.27? @sukunrt Can you add more context, and create an issue that would highlight the problem such that someone could find it if they run into this issue, and thus find this fix?

@@ -21,6 +21,7 @@ import (
// and tries to obtain port mappings for those.
type NATManager interface {
GetMapping(ma.Multiaddr) ma.Multiaddr
HasNAT() bool
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should call this HasNAT because this checks if we can communicate with a NAT device. If we have a NAT, but are unable to communicate with it (e.g. via upnp) then, this would return false.

Maybe call it HasDiscoveredNAT instead?

@sukunrt
Copy link
Member Author

sukunrt commented Jun 12, 2023

this explains the first issue, #2357
We can discuss why we need the HasNAT check there.

@sukunrt
Copy link
Member Author

sukunrt commented Jun 12, 2023

@MarcoPolo, yes this is a regression from v0.27

@MarcoPolo
Copy link
Collaborator

Let's just merge the fix for the regression for now.


for _, addr := range resolved {
addrs = append(addrs, listen)
for _, addr := range addrs {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little suspicious about this code in general. Why do we trust the NAT device to give us the correct external port, but not the IP address? Or, in other words, how likely is it that the NAT device gives us the correct port mapping but the incorrect public IP address?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not about the NAT giving the IP address, this is about this line returning the correct addresses for the listen address.
#2346

@@ -904,6 +904,19 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr {
}
}
}
// Add observed addresses for umapped addresses
for _, listen := range unmapped {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This didn't exist before. What did this fix for you? This codepath gets hit in the case we discover a NAT device, but fail to register a mapping, is that correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. If you are unable to do a nat mapping after discovering a NAT device this code path fixes it.

@sukunrt
Copy link
Member Author

sukunrt commented Jun 12, 2023

Let's just take this commit: bed6dca for now.

@p-shahi
Copy link
Member

p-shahi commented Jun 12, 2023

Let's just take this commit: bed6dca for now.

Do you want to create a separate PR?

@sukunrt
Copy link
Member Author

sukunrt commented Jun 13, 2023

closing in favour of #2358

@sukunrt sukunrt closed this Jun 13, 2023
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

Successfully merging this pull request may close these issues.

4 participants