net/portmapper: send UPnP protocol in upper-case

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
This commit is contained in:
Andrew Dunham 2023-03-04 14:40:59 -05:00
parent d379a25ae4
commit 51eb0b2cb7

View File

@ -44,11 +44,21 @@ type upnpMapping struct {
client upnpClient
}
// upnpProtocolUDP represents the protocol name for UDP, to be used in the UPnP
// <AddPortMapping> message in the <NewProtocol> field.
//
// NOTE: this must be an upper-case string, or certain routers will reject the
// mapping request. Other implementations like miniupnp send an upper-case
// protocol as well. See:
//
// https://github.com/tailscale/tailscale/issues/7377
const upnpProtocolUDP = "UDP"
func (u *upnpMapping) GoodUntil() time.Time { return u.goodUntil }
func (u *upnpMapping) RenewAfter() time.Time { return u.renewAfter }
func (u *upnpMapping) External() netip.AddrPort { return u.external }
func (u *upnpMapping) Release(ctx context.Context) {
u.client.DeletePortMapping(ctx, "", u.external.Port(), "udp")
u.client.DeletePortMapping(ctx, "", u.external.Port(), upnpProtocolUDP)
}
// upnpClient is an interface over the multiple different clients exported by goupnp,
@ -69,7 +79,7 @@ type upnpClient interface {
// `AddAnyPortMapping` is not supported.
externalPort uint16,
// protocol is whether this is over TCP or UDP. Either "tcp" or "udp".
// protocol is whether this is over TCP or UDP. Either "TCP" or "UDP".
protocol string,
// internalPort is the port that the gateway device forwards the traffic to.
@ -116,7 +126,7 @@ func addAnyPortMapping(
ctx,
"",
externalPort,
"udp",
upnpProtocolUDP,
internalPort,
internalClient,
true,
@ -138,7 +148,7 @@ func addAnyPortMapping(
ctx,
"",
externalPort,
"udp",
upnpProtocolUDP,
internalPort,
internalClient,
true,