net/portmapper: fall back to permanent UPnP leases if necessary

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
This commit is contained in:
Andrew Dunham
2023-09-11 12:15:02 -04:00
parent 7c1ed38ab3
commit 9ee173c256
3 changed files with 283 additions and 2 deletions

View File

@@ -16,6 +16,7 @@ import (
"tailscale.com/control/controlknobs"
"tailscale.com/net/netaddr"
"tailscale.com/syncs"
"tailscale.com/types/logger"
)
@@ -25,6 +26,7 @@ type TestIGD struct {
upnpConn net.PacketConn // for UPnP discovery
pxpConn net.PacketConn // for NAT-PMP and/or PCP
ts *httptest.Server
upnpHTTP syncs.AtomicValue[http.Handler]
logf logger.Logf
closed atomic.Bool
@@ -126,8 +128,17 @@ func (d *TestIGD) stats() igdCounters {
return d.counters
}
func (d *TestIGD) SetUPnPHandler(h http.Handler) {
d.upnpHTTP.Store(h)
}
func (d *TestIGD) serveUPnPHTTP(w http.ResponseWriter, r *http.Request) {
http.NotFound(w, r) // TODO
if handler := d.upnpHTTP.Load(); handler != nil {
handler.ServeHTTP(w, r)
return
}
http.NotFound(w, r)
}
func (d *TestIGD) serveUPnPDiscovery() {