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

chore: move go-nat to internal package #3154

Open
wants to merge 73 commits into
base: master
Choose a base branch
from

Conversation

MarcoPolo
Copy link
Collaborator

@MarcoPolo MarcoPolo commented Jan 24, 2025

I believe we are the main users of this library, and we don't have enough bandwidth to maintain this for other use cases besides our own.

This PR brings in the commit history from the go-nat repo, and does some refactoring to clean up the code and surface errors to help debug issues.

After merging this, I'll archive the old repo.

Before merge:

  • Squash refactor commits
  • merge this as a merge commit

fd and others added 30 commits August 28, 2014 20:49
This change also removes the restriction on what IP ranges can be
used with NAT-PMP/PCP.

Fixes: #1, #2
Bumps [github.com/jackpal/gateway](https://github.com/jackpal/gateway) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/jackpal/gateway/releases)
- [Commits](jackpal/gateway@v1.0.4...v1.0.5)

Signed-off-by: dependabot[bot] <[email protected]>
…l/gateway-1.0.5

Bump github.com/jackpal/gateway from 1.0.4 to 1.0.5
add gomod support // tag v0.0.1.
Added method to generically discover IG Devices
This change makes it possible to configure all discovered NATs, not just the
first one found.
web-flow and others added 9 commits June 28, 2023 08:54
* chore: add or force update .github/workflows/go-test.yml

* chore: add or force update .github/workflows/go-check.yml

* chore: add or force update .github/workflows/releaser.yml

* chore: add or force update .github/workflows/release-check.yml

* chore: add or force update .github/workflows/tagpush.yml
* chore: bump go.mod to Go 1.21 and run go fix

* chore: run go mod tidy
* chore: add or force update .github/workflows/go-test.yml

* chore: add or force update .github/workflows/go-check.yml

* chore: add or force update .github/workflows/releaser.yml

* chore: add or force update .github/workflows/release-check.yml

* chore: add or force update .github/workflows/tagpush.yml

* chore: add or force update .github/workflows/go-test.yml

* chore: add or force update .github/workflows/go-check.yml

* chore: add or force update .github/workflows/releaser.yml

* chore: add or force update .github/workflows/release-check.yml

* chore: add or force update .github/workflows/tagpush.yml

* chore: add or force update .github/workflows/go-test.yml

* chore: add or force update .github/workflows/go-check.yml

* chore: add or force update .github/workflows/releaser.yml

* chore: add or force update .github/workflows/release-check.yml

* chore: add or force update .github/workflows/tagpush.yml
…a99234c9fc5f175c'

git-subtree-dir: p2p/net/nat/internal/nat
git-subtree-mainline: 49c9549
git-subtree-split: 2fac909
@MarcoPolo MarcoPolo requested a review from sukunrt January 24, 2025 03:17
@MarcoPolo
Copy link
Collaborator Author

For reviewing, only the last commit is likely useful.

var gw ssdp.Service
for _, Service := range DeviceList {
if strings.Contains(Service.Type, "InternetGatewayDevice") {
gw = Service
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Shouldn't we do this on all services that match this string?

@marten-seemann
Copy link
Contributor

I believe we are the main users of this library, and we don't have enough bandwidth to maintain this for other use cases besides our own.

Please don't do this. It's totally ok to refuse PRs to reduce the maintenance burden (as you've been doing with zeroconf), and you can call this out in the README. But code should only be moved if the code logically belongs somewhere else. This clearly is not the case for go-nat.

@MarcoPolo
Copy link
Collaborator Author

Are you using this library?

@MarcoPolo
Copy link
Collaborator Author

go-nat is a thin layer over what the underlying libraries provide (primarily github.com/huin/goupnp and github.com/jackpal/go-nat-pmp). Granted, it provides a higher level API that abstracts out the differences between 3 different ways to reserve a port. But this isn't particularly difficult, if not finicky. For our use case, only the p2p/net/nat package uses go-nat. Therefore, it's entirely reasonable to move go-nat into an internal package for p2p/net/nat. This lets us iterate quicker on these related packages.

A fair complaint would be that this makes it much harder for other folks to use go-nat and our future changes to that library. This is true. but from my brief cursory code search, I didn't find any recent usages of this library, but I could have missed something. If you're using it that would be a useful data point.

As an alternative, folks looking for a higher level NAT package could make use of go-libp2p's nat package directly github.com/libp2p/go-libp2p/p2p/net/nat. It provides a higher level API than go-nat, is easier to use, and something we will support.

Given that we have a supported high level API with github.com/libp2p/go-libp2p/p2p/net/nat and users could still access the lower level libraries of github.com/huin/goupnp and github.com/jackpal/go-nat-pmp, I'm not sure I see the value in supporting go-nat as a separate package.

@MarcoPolo MarcoPolo force-pushed the marco/bring-go-nat-home branch from 26be225 to f8bd11c Compare January 28, 2025 18:17
@MarcoPolo MarcoPolo requested review from aschmahmann and removed request for sukunrt January 28, 2025 18:48
@MarcoPolo MarcoPolo mentioned this pull request Jan 29, 2025
20 tasks
Copy link
Collaborator

@aschmahmann aschmahmann left a comment

Choose a reason for hiding this comment

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

@MarcoPolo I reviewed f8bd11c. Is there anything else you wanted me to look at (e.g. the git merging things)?

p2p/net/nat/internal/nat/natpmp.go Show resolved Hide resolved
p2p/net/nat/internal/nat/upnp.go Show resolved Hide resolved
p2p/net/nat/internal/nat/nat.go Show resolved Hide resolved
p2p/net/nat/internal/nat/nat.go Outdated Show resolved Hide resolved
return
}

func serviceVisitor(ctx context.Context, rootDevice *goupnp.RootDevice, outNats *[]NAT, outErrs *[]error) func(srv *goupnp.Service) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need a comment somewhere (e.g. on this function or the top level caller of all the upnp discovery mechanisms) describing why we'll handle whatever service type gets sent to us even if we searched for a totally different one (e.g. searching for IG1 and getting IP2 which comes from IG2). This will help us later if there's a problem.

Note: do we want / need this behavior anymore now that we're doing the sequential lookups to deal with badly implemented routers (e.g. fritzbox)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This will now collect an error if it sees a v2 service on a v1 device.

@MarcoPolo
Copy link
Collaborator Author

@MarcoPolo I reviewed f8bd11c. Is there anything else you wanted me to look at (e.g. the git merging things)?

That should be it. I'll merge this a merge commit so the history should be preserved.

@aschmahmann
Copy link
Collaborator

Regarding whether we should bring this functionality into the monorepo I'm +1 with @MarcoPolo's assessment.

  • The library is small
  • The library is only used by us (and it's had a whole bunch of years of independence if it was going to get independent users)
  • It's much easier to work with and debug the library within the monorepo.... which is part of what inspired the move to the monorepo to begin with

FWIW if the above were not true (particularly, if the library was going to be used by others independent of go-libp2p and the Go module pruning was insufficient) I'd understand wanting to keep the repo separate. Additionally, this is not an uncommon thing to do. Other projects like Syncthing (https://github.com/syncthing/syncthing/tree/124673f7a89b73e7389dc664ce46441b41b7012b/lib/upnp) and Tailscale (https://github.com/tailscale/tailscale/tree/08dd4994d09cf4b960663321136b4fde3f5ccb18/net/portmapper) seem to take the same approach with bundling their portmapping code into their codebases (albeit they're less library focused than go-libp2p is).

If in the future say a group like Syncthing wanted to collaborate on / share a portmapping module and it made sense to do so in a separate repo that'd seem very reasonable to me.

@MarcoPolo MarcoPolo requested a review from aschmahmann January 30, 2025 22:20
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.

Occasional failure to discover NAT which prevents NAT port from getting mapped