net/portmapper: reuse root device across calls

Before, we were sending 3 http requests to the same device, which was both costly and likely
caused it to be slower than necessary.

Signed-off-by: julianknodt <julianknodt@gmail.com>
This commit is contained in:
julianknodt 2021-08-03 11:35:01 -07:00
parent 2d35737a7a
commit 7b2ef0528f
3 changed files with 21 additions and 29 deletions

View File

@ -7,7 +7,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
💣 github.com/mitchellh/go-ps from tailscale.com/cmd/tailscale/cli
github.com/peterbourgon/ff/v2 from github.com/peterbourgon/ff/v2/ffcli
github.com/peterbourgon/ff/v2/ffcli from tailscale.com/cmd/tailscale/cli
github.com/tailscale/goupnp from github.com/tailscale/goupnp/dcps/internetgateway2
github.com/tailscale/goupnp from github.com/tailscale/goupnp/dcps/internetgateway2+
github.com/tailscale/goupnp/dcps/internetgateway2 from tailscale.com/net/portmapper
github.com/tailscale/goupnp/httpu from github.com/tailscale/goupnp+
github.com/tailscale/goupnp/scpd from github.com/tailscale/goupnp

View File

@ -23,7 +23,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
L 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink
W github.com/pkg/errors from github.com/tailscale/certstore
W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient
github.com/tailscale/goupnp from github.com/tailscale/goupnp/dcps/internetgateway2
github.com/tailscale/goupnp from github.com/tailscale/goupnp/dcps/internetgateway2+
github.com/tailscale/goupnp/dcps/internetgateway2 from tailscale.com/net/portmapper
github.com/tailscale/goupnp/httpu from github.com/tailscale/goupnp+
github.com/tailscale/goupnp/scpd from github.com/tailscale/goupnp

View File

@ -14,6 +14,7 @@ import (
"net/url"
"time"
"github.com/tailscale/goupnp"
"github.com/tailscale/goupnp/dcps/internetgateway2"
"inet.af/netaddr"
"tailscale.com/control/controlknobs"
@ -147,34 +148,25 @@ func getUPnPClient(ctx context.Context, gw netaddr.IP) (upnpClient, error) {
if err != nil {
return nil, err
}
clients := make(chan upnpClient, 3)
go func() {
var err error
ip1Clients, err := internetgateway2.NewWANIPConnection1ClientsByURL(ctx, u)
if err == nil && len(ip1Clients) > 0 {
clients <- ip1Clients[0]
}
}()
go func() {
ip2Clients, err := internetgateway2.NewWANIPConnection2ClientsByURL(ctx, u)
if err == nil && len(ip2Clients) > 0 {
clients <- ip2Clients[0]
}
}()
go func() {
ppp1Clients, err := internetgateway2.NewWANPPPConnection1ClientsByURL(ctx, u)
if err == nil && len(ppp1Clients) > 0 {
clients <- ppp1Clients[0]
}
}()
select {
case client := <-clients:
return client, nil
case <-ctx.Done():
return nil, ctx.Err()
rootDevice, err := goupnp.DeviceByURL(ctx, u)
if err != nil {
return nil, err
}
ip1Clients, err := internetgateway2.NewWANIPConnection1ClientsFromRootDevice(ctx, rootDevice, u)
if err == nil && len(ip1Clients) > 0 {
return ip1Clients[0], nil
}
ip2Clients, err := internetgateway2.NewWANIPConnection2ClientsFromRootDevice(ctx, rootDevice, u)
if err == nil && len(ip2Clients) > 0 {
return ip2Clients[0], nil
}
ppp1Clients, err := internetgateway2.NewWANPPPConnection1ClientsFromRootDevice(ctx, rootDevice, u)
if err == nil && len(ppp1Clients) > 0 {
return ppp1Clients[0], nil
}
return nil, fmt.Errorf("found no valid UPnP portmapping")
}
// getUPnPPortMapping attempts to create a port-mapping over the UPnP protocol. On success,