summaryrefslogtreecommitdiffhomepage
path: root/net/portmapper
AgeCommit message (Collapse)AuthorFilesLines
2026-01-23all: remove AUTHORS file and references to itWill Norris13-13/+13
This file was never truly necessary and has never actually been used in the history of Tailscale's open source releases. A Brief History of AUTHORS files --- The AUTHORS file was a pattern developed at Google, originally for Chromium, then adopted by Go and a bunch of other projects. The problem was that Chromium originally had a copyright line only recognizing Google as the copyright holder. Because Google (and most open source projects) do not require copyright assignemnt for contributions, each contributor maintains their copyright. Some large corporate contributors then tried to add their own name to the copyright line in the LICENSE file or in file headers. This quickly becomes unwieldy, and puts a tremendous burden on anyone building on top of Chromium, since the license requires that they keep all copyright lines intact. The compromise was to create an AUTHORS file that would list all of the copyright holders. The LICENSE file and source file headers would then include that list by reference, listing the copyright holder as "The Chromium Authors". This also become cumbersome to simply keep the file up to date with a high rate of new contributors. Plus it's not always obvious who the copyright holder is. Sometimes it is the individual making the contribution, but many times it may be their employer. There is no way for the proejct maintainer to know. Eventually, Google changed their policy to no longer recommend trying to keep the AUTHORS file up to date proactively, and instead to only add to it when requested: https://opensource.google/docs/releasing/authors. They are also clear that: > Adding contributors to the AUTHORS file is entirely within the > project's discretion and has no implications for copyright ownership. It was primarily added to appease a small number of large contributors that insisted that they be recognized as copyright holders (which was entirely their right to do). But it's not truly necessary, and not even the most accurate way of identifying contributors and/or copyright holders. In practice, we've never added anyone to our AUTHORS file. It only lists Tailscale, so it's not really serving any purpose. It also causes confusion because Tailscalars put the "Tailscale Inc & AUTHORS" header in other open source repos which don't actually have an AUTHORS file, so it's ambiguous what that means. Instead, we just acknowledge that the contributors to Tailscale (whoever they are) are copyright holders for their individual contributions. We also have the benefit of using the DCO (developercertificate.org) which provides some additional certification of their right to make the contribution. The source file changes were purely mechanical with: git ls-files | xargs sed -i -e 's/\(Tailscale Inc &\) AUTHORS/\1 contributors/g' Updates #cleanup Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d Signed-off-by: Will Norris <will@tailscale.com>
2026-01-19net/portmapper: Stop replacing the internal port with the upnp external port ↵Eduardo Sorribas1-1/+1
(#18349) net/portmapper: Stop replacing the internal port with the upnp external port This causes the UPnP mapping to break in the next recreation of the mapping. Fixes #18348 Signed-off-by: Eduardo Sorribas <eduardo@sorribas.org>
2026-01-08net/portmapper, go.mod: unfork our goupnp dependencyAndrew Dunham3-51/+85
Updates #7436 Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2025-11-17go.mod: bump golang.org/x/crypto (#17907)Andrew Lytvynov1-2/+3
Pick up a fix for https://pkg.go.dev/vuln/GO-2025-4116 (even though we're not affected). Updates #cleanup Change-Id: I9f2571b17c1f14db58ece8a5a34785805217d9dd Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-11-16syncs: add Mutex/RWMutex alias/wrappers for future mutex debuggingBrad Fitzpatrick1-2/+1
Updates #17852 Change-Id: I477340fb8e40686870e981ade11cd61597c34a20 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-10-02feature/featuretags: add features for c2n, peerapi, advertise/use ↵Brad Fitzpatrick1-4/+8
routes/exit nodes Saves 262 KB so far. I'm sure I missed some places, but shotizam says these were the low hanging fruit. Updates #12614 Change-Id: Ia31c01b454f627e6d0470229aae4e19d615e45e3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-16feature/portmapper: make the portmapper & its debugging tools modularBrad Fitzpatrick6-57/+141
Starting at a minimal binary and adding one feature back... tailscaled tailscale combined (linux/amd64) 30073135 17451704 31543692 omitting everything + 480302 + 10258 + 493896 .. add debugportmapper + 475317 + 151943 + 467660 .. add portmapper + 500086 + 162873 + 510511 .. add portmapper+debugportmapper Fixes #17148 Change-Id: I90bd0e9d1bd8cbe64fa2e885e9afef8fb5ee74b1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-08-18ipn/localapi: plumb an event bus through the localapi.Handler (#16892)M. J. Fromberger1-5/+2
Some of the operations of the local API need an event bus to correctly instantiate other components (notably including the portmapper). This commit adds that, and as the parameter list is starting to get a bit long and hard to read, I took the opportunity to move the arguments to a config type. Only a few call sites needed to be updated and this API is not intended for general use, so I did not bother to stage the change. Updates #15160 Updates #16842 Change-Id: I7b057d71161bd859f5acb96e2f878a34c85be0ef Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-07-29ipn,net,tsnet,wgengine: make an eventbus mandatory where it is used (#16594)M. J. Fromberger2-22/+27
In the components where an event bus is already plumbed through, remove the exceptions that allow it to be omitted, and update all the tests that relied on those workarounds execute properly. This change applies only to the places where we're already using the bus; it does not enforce the existence of a bus in other components (yet), Updates #15160 Change-Id: Iebb92243caba82b5eb420c49fc3e089a77454f65 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-07-28net/portmapper: avert a panic when a mapping is not available (#16686)M. J. Fromberger1-0/+7
Ideally when we attempt to create a new port mapping, we should not return without error when no mapping is available. We already log these cases as unexpected, so this change is just to avoiding panicking dispatch on the invalid result in those cases. We still separately need to fix the underlying control flow. Updates #16662 Change-Id: I51e8a116b922b49eda45e31cd27f6b89dd51abc8 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-06-25util/eventbus: add test helpers to simplify testing events (#16294)Claus Lensbøl2-13/+6
Instead of every module having to come up with a set of test methods for the event bus, this handful of test helpers hides a lot of the needed setup for the testing of the event bus. The tests in portmapper is also ported over to the new helpers. Updates #15160 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
2025-04-25net/portmapper: fix test flakes from logging after test doneBrad Fitzpatrick4-12/+15
Fixes #15794 Change-Id: Ic22aa99acb10fdb6dc5f0b6482e722e48237703c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-04-23net/portmapper: fix nil pointer dereference in Client.createMappingNick Khyl1-5/+7
The EventBus in net/portmapper.Config is still optional and Client.updates can be nil. Updates #15772 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-16net/portmapper: fire an event when a port mapping is updated (#15371)M. J. Fromberger5-49/+114
When an event bus is configured publish an event each time a new port mapping is updated. Publication is unconditional and occurs prior to calling any callback that is registered. For now, the callback is still fired in a separate goroutine as before -- later, those callbacks should become subscriptions to the published event. For now, the event type is defined as a new type here in the package. We will want to move it to a more central package when there are subscribers. The event wrapper is effectively a subset of the data exported by the internal mapping interface, but on a concrete struct so the bus plumbing can inspect it. Updates #15160 Change-Id: I951f212429ac791223af8d75b6eb39a0d2a0053a Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16{wgengine,util/portmapper}: add and plumb an event bus (#15359)M. J. Fromberger1-0/+10
Updates #15160 Change-Id: I2510fb4a8905fb0abe8a8e0c5b81adb15d50a6f8 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16portmapper: update NewClient to use a Config argumentM. J. Fromberger3-27/+45
In preparation for adding more parameters (and later, moving some away), rework the portmapper constructor to accept its arguments on a Config struct rather than positionally. This is a breaking change to the function signature, but one that is very easy to update, and a search of GitHub reveals only six instances of usage outside clones and forks of Tailscale itself, that are not direct copies of the code fixed up here. While we could stub in another constructor, I think it is safe to let those folks do the update in-place, since their usage is already affected by other changes we can't test for anyway. Updates #15160 Change-Id: I9f8a5e12b38885074c98894b7376039261b43f43 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-03-07net/portmapper: retry UPnP when we get an "Invalid Args"Andrew Dunham2-2/+110
We previously retried getting a UPnP mapping when the device returned error code 725, "OnlyPermanentLeasesSupported". However, we've seen devices in the wild also return 402, "Invalid Args", when given a lease duration. Fall back to the no-duration mapping method in these cases. Updates #15223 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I6a25007c9eeac0dac83750dd3ae9bfcc287c8fcf
2024-10-01net/portmapper: don't treat 0.0.0.0 as a valid IPBrad Fitzpatrick1-0/+4
Updates tailscale/corp#23538 Change-Id: I58b8c30abe43f1d1829f01eb9fb2c1e6e8db9476 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-10-01net/portmapper: don't return unspecified/local external IPsAndrew Dunham2-21/+92
We were previously not checking that the external IP that we got back from a UPnP portmap was a valid endpoint; add minimal validation that this endpoint is something that is routeable by another host. Updates tailscale/corp#23538 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Id9649e7683394aced326d5348f4caa24d0efd532
2024-06-05all: use math/rand/v2 moreMaisem Ali1-2/+2
Updates #11058 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2024-05-06net/portmapper: add envknob to disable portmapper in localhost integration testsBrad Fitzpatrick1-0/+6
Updates #11962 Change-Id: I8212cd814985b455d96986de0d4c45f119516cb3 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-28net/{interfaces,netmon}, all: merge net/interfaces package into net/netmonBrad Fitzpatrick1-2/+1
In prep for most of the package funcs in net/interfaces to become methods in a long-lived netmon.Monitor that can cache things. (Many of the funcs are very heavy to call regularly, whereas the long-lived netmon.Monitor can subscribe to things from the OS and remember answers to questions it's asked regularly later) Updates tailscale/corp#10910 Updates tailscale/corp#18960 Updates #7967 Updates #3299 Change-Id: Ie4e8dedb70136af2d611b990b865a822cd1797e5 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-27net/netns, net/dns/resolver, etc: make netmon required in most placesBrad Fitzpatrick2-4/+8
The goal is to move more network state accessors to netmon.Monitor where they can be cheaper/cached. But first (this change and others) we need to make sure the one netmon.Monitor is plumbed everywhere. Some notable bits: * tsdial.NewDialer is added, taking a now-required netmon * because a tsdial.Dialer always has a netmon, anything taking both a Dialer and a NetMon is now redundant; take only the Dialer and get the NetMon from that if/when needed. * netmon.NewStatic is added, primarily for tests Updates tailscale/corp#10910 Updates tailscale/corp#18960 Updates #7967 Updates #3299 Change-Id: I877f9cb87618c4eb037cee098241d18da9c01691 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-04-16all: use Go 1.22 range-over-intBrad Fitzpatrick2-3/+3
Updates #11058 Change-Id: I35e7ef9b90e83cac04ca93fd964ad00ed5b48430 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-03-25tailcfg, ipn/ipnlocal, wgengine/magicsock: add only-tcp-443 node attrBrad Fitzpatrick1-0/+18
Updates tailscale/corp#17879 Change-Id: I0dc305d147b76c409cf729b599a94fa723aef0e0 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-01-23net/portmapper: support legacy "urn:dslforum-org" portmapping servicesAndrew Dunham4-2/+488
These are functionally the same as the "urn:schemas-upnp-org" services with a few minor changes, and are still used by older devices. Support them to improve our ability to obtain an external IP on such networks. Updates #10911 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I05501fad9d6f0a3b8cf19fc95eee80e7d16cc2cf
2024-01-22net/portmapper: handle cases where we have no supported clientsAndrew Dunham2-1/+232
This no longer results in a nil pointer exception when we get a valid UPnP response with no supported clients. Updates #10911 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I6e3715a49a193ff5261013871ad7fff197a4d77e
2024-01-03net/portmapper: check returned epoch from PMP and PCP protocolsAndrew Dunham2-3/+65
If the epoch that we see during a Probe is less than the existing epoch, it means that the gateway has either restarted or reset its configuration, and an existing mapping is no longer valid. Reset any saved mapping(s) if we detect this case so that a future createOrGetMapping will not attempt to re-use it. Updates #10597 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Ie3cddaf625cb94a29885f7a1eeea25dbf6b97b47
2023-12-20all: cleanup unused code, part 1 (#10661)Andrew Lytvynov1-2/+0
Run `staticcheck` with `U1000` to find unused code. This cleans up about a half of it. I'll do the other half separately to keep PRs manageable. Updates #cleanup Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2023-12-20net/portmapper: add logs about obtained mapping(s)Andrew Dunham4-1/+69
This logs additional information about what mapping(s) are obtained during the creation process, including whether we return an existing cached mapping. Updates #10597 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I9ff25071f064c91691db9ab0b9365ccc5f948d6e
2023-12-18net/portmapper: handle multiple UPnP discovery responsesAndrew Dunham4-84/+395
Instead of taking the first UPnP response we receive and using that to create port mappings, store all received UPnP responses, sort and deduplicate them, and then try all of them to obtain an external address. Updates #10602 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I783ccb1834834ee2a9ecbae2b16d801f2354302f
2023-12-13net/portmapper: be smarter about selecting a UPnP deviceAndrew Dunham4-109/+697
Previously, we would select the first WANIPConnection2 (and related) client from the root device, without any additional checks. However, some routers expose multiple UPnP devices in various states, and simply picking the first available one can result in attempting to perform a portmap with a device that isn't functional. Instead, mimic what the miniupnpc code does, and prefer devices that are (a) reporting as Connected, and (b) have a valid external IP address. For our use-case, we additionally prefer devices that have an external IP address that's a public address, to increase the likelihood that we can obtain a direct connection from peers. Finally, we split out fetching the root device (getUPnPRootDevice) from selecting the best service within that root device (selectBestService), and add some extensive tests for various UPnP server behaviours. RELNOTE=Improve UPnP portmapping when multiple UPnP services exist Updates #8364 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I71795cd80be6214dfcef0fe83115a5e3fe4b8753
2023-12-05net/portmap: add test of Mikrotik Root Desc XML.Denton Gentry1-29/+170
Unfortunately in the test we can't reproduce the failure seen in the real system ("SOAP fault: UPnPError") Updates https://github.com/tailscale/tailscale/issues/8364 Signed-off-by: Denton Gentry <dgentry@tailscale.com>
2023-10-26net/portmapper: avoid alloc in getUPnPErrorsMetricAndrew Dunham1-10/+12
Updates #cleanup Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Iea558024c038face24cc46584421998d10f13a66
2023-10-25net/portmapper: convert UPnP metrics to new syncs.Map.LoadOrInit methodVal1-12/+3
Simplify UPnP error metrics by using the new syncs.Map.LoadOrInit method. Updates #cleanup Signed-off-by: Val <valerie@tailscale.com>
2023-09-27net/portmapper: fix invalid UPnP metric nameAndrew Dunham2-1/+21
Fixes #9551 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I06f3a15a668be621675be6cbc7e5bdcc006e8570
2023-09-18net/portmapper: add clientmetric for UPnP error codesAndrew Dunham2-10/+34
This should allow us to gather a bit more information about errors that we encounter when creating UPnP mappings. Since we don't have a "LabelMap" construction for clientmetrics, do what sockstats does and lazily register a new metric when we see a new code. Updates #9343 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Ibb5aadd6138beb58721f98123debcc7273b611ba
2023-09-12net/portmapper: fall back to permanent UPnP leases if necessaryAndrew Dunham3-2/+283
Some routers don't support lease times for UPnP portmapping; let's fall back to adding a permanent lease in these cases. Additionally, add a proper end-to-end test case for the UPnP portmapping behaviour. Updates #9343 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I17dec600b0595a5bfc9b4d530aff6ee3109a8b12
2023-09-11control/controlknobs, all: add plumbed Knobs type, not global variablesBrad Fitzpatrick4-11/+24
Previously two tsnet nodes in the same process couldn't have disjoint sets of controlknob settings from control as both would overwrite each other's global variables. This plumbs a new controlknobs.Knobs type around everywhere and hangs the knobs sent by control on that instead. Updates #9351 Change-Id: I75338646d36813ed971b4ffad6f9a8b41ec91560 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-08-28cmd/tailscale, net/portmapper: add --log-http option to "debug portmap"Andrew Dunham2-0/+67
This option allows logging the raw HTTP requests and responses that the portmapper Client makes when using UPnP. This can be extremely helpful when debugging strange UPnP issues with users' devices, and might allow us to avoid having to instruct users to perform a packet capture. Updates #8992 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I2c3cf6930b09717028deaff31738484cc9b008e4
2023-08-21net/portmapper: never select port 0 in UPnPAndrew Dunham1-14/+34
Port 0 is interpreted, per the spec (but inconsistently among router software) as requesting to map every single available port on the UPnP gateway to the internal IP address. We'd previously avoided picking ports below 1024 for one of the two UPnP methods (in #7457), and this change moves that logic so that we avoid it in all cases. Updates #8992 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I20d652c0cd47a24aef27f75c81f78ae53cc3c71e
2023-04-20all: avoid repeated default interface lookupsMihai Parparita4-7/+13
On some platforms (notably macOS and iOS) we look up the default interface to bind outgoing connections to. This is both duplicated work and results in logspam when the default interface is not available (i.e. when a phone has no connectivity, we log an error and thus cause more things that we will try to upload and fail). Fixed by passing around a netmon.Monitor to more places, so that we can use its cached interface state. Fixes #7850 Updates #7621 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-04-17various: add golangci-lint, fix issues (#7905)Andrew Dunham1-1/+1
This adds an initial and intentionally minimal configuration for golang-ci, fixes the issues reported, and adds a GitHub Action to check new pull requests against this linter configuration. Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I8f38fbc315836a19a094d0d3e986758b9313f163
2023-04-15wgengine/magicsock, types/nettype, etc: finish ReadFromUDPAddrPort netip ↵Brad Fitzpatrick1-10/+5
migration So we're staying within the netip.Addr/AddrPort consistently and avoiding allocs/conversions to the legacy net addr types. Updates #5162 Change-Id: I59feba60d3de39f773e68292d759766bac98c917 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2023-04-12net/sockstats: pass in logger to sockstats.WithSockStatsMihai Parparita1-1/+1
Using log.Printf may end up being printed out to the console, which is not desirable. I noticed this when I was investigating some client logs with `sockstats: trace "NetcheckClient" was overwritten by another`. That turns to be harmless/expected (the netcheck client will fall back to the DERP client in some cases, which does its own sockstats trace). However, the log output could be visible to users if running the `tailscale netcheck` CLI command, which would be needlessly confusing. Updates tailscale/corp#9230 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-03-06sockstats: switch label to enumMihai Parparita1-1/+1
Makes it cheaper/simpler to persist values, and encourages reuse of labels as opposed to generating an arbitrary number. Updates tailscale/corp#9230 Updates #3363 Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2023-03-04net/portmapper: relax source port check for UPnP responsesAndrew Dunham1-22/+41
Per a packet capture provided, some gateways will reply to a UPnP discovery packet with a UDP packet with a source port that does not come from the UPnP port. Accept these packets with a log message. Updates #7377 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I5d4d5b2a0275009ed60f15c20b484fe2025d094b
2023-03-04net/portmapper: send UPnP protocol in upper-caseAndrew Dunham1-4/+14
We were previously sending a lower-case "udp" protocol, whereas other implementations like miniupnp send an upper-case "UDP" protocol. For compatibility, use an upper-case protocol instead. Updates #7377 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I4aed204f94e4d51b7a256d29917af1536cb1b70f
2023-03-04net/portmapper: don't pick external ports below 1024Andrew Dunham1-2/+9
Some devices don't let you UPnP portmap a port below 1024, so let's just avoid that range of ports entirely. Updates #7377 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Ib7603b1c9a019162cdc4fa21744a2cae48bb1d86
2023-03-03cmd/tailscale, cmd/tailscaled: move portmapper debugging into tailscale CLIAndrew Dunham5-26/+37
The debug flag on tailscaled isn't available in the macOS App Store build, since we don't have a tailscaled binary; move it to the 'tailscale debug' CLI that is available on all platforms instead, accessed over LocalAPI. Updates #7377 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: I47bffe4461e036fab577c2e51e173f4003592ff7