net/portmapper: return correct upnp port
Previously, this was incorrectly returning the internal port, and using that with the external
exposed IP when it did not use WANIPConnection2. In the case when we must provide a port, we
return it instead.
Noticed this while implementing the integration test for upnp.
import (
"context"
"fmt"
+ "math/rand"
"net/url"
"time"
@@ -86,6 +87,8 @@ type upnpClient interface {
// addAnyPortMapping abstracts over different UPnP client connections, calling the available
// AddAnyPortMapping call if available for WAN IP connection v2, otherwise defaulting to the old
// behavior of calling AddPortMapping with port = 0 to specify a wildcard port.
+// It returns the new external port (which may not be identical to the external port specified),
+// or an error.
func addAnyPortMapping(
ctx context.Context,
upnp upnpClient,
@@ -107,6 +110,9 @@ func addAnyPortMapping(
uint32(leaseDuration.Seconds()),
)
}
+ for externalPort == 0 {
+ externalPort = uint16(rand.Intn(65535))
+ }
err = upnp.AddPortMapping(
ctx,
"",
@@ -118,7 +124,7 @@ func addAnyPortMapping(
tsPortMappingDesc,
uint32(leaseDuration.Seconds()),
)
- return internalPort, err
+ return externalPort, err
}
// getUPnPClients gets a client for interfacing with UPnP, ignoring the underlying protocol for
