mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-22 04:48:39 +00:00
tailcfg, net/portmapper, wgengine/magicsock: add NetInfo.HavePortMap
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
79d8288f0a
commit
ef7bac2895
@ -63,6 +63,13 @@ type Client struct {
|
|||||||
pmpMapping *pmpMapping // non-nil if we have a PMP mapping
|
pmpMapping *pmpMapping // non-nil if we have a PMP mapping
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HaveMapping reports whether we have a current valid mapping.
|
||||||
|
func (c *Client) HaveMapping() bool {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
return c.pmpMapping != nil && c.pmpMapping.useUntil.After(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
// pmpMapping is an already-created PMP mapping.
|
// pmpMapping is an already-created PMP mapping.
|
||||||
//
|
//
|
||||||
// All fields are immutable once created.
|
// All fields are immutable once created.
|
||||||
|
@ -431,6 +431,10 @@ type NetInfo struct {
|
|||||||
// WorkingUDP is whether UDP works.
|
// WorkingUDP is whether UDP works.
|
||||||
WorkingUDP opt.Bool
|
WorkingUDP opt.Bool
|
||||||
|
|
||||||
|
// HavePortMap is whether we have an existing portmap open
|
||||||
|
// (UPnP, PMP, or PCP).
|
||||||
|
HavePortMap bool `json:",omitempty"`
|
||||||
|
|
||||||
// UPnP is whether UPnP appears present on the LAN.
|
// UPnP is whether UPnP appears present on the LAN.
|
||||||
// Empty means not checked.
|
// Empty means not checked.
|
||||||
UPnP opt.Bool
|
UPnP opt.Bool
|
||||||
@ -479,10 +483,14 @@ func (ni *NetInfo) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ni *NetInfo) portMapSummary() string {
|
func (ni *NetInfo) portMapSummary() string {
|
||||||
if ni.UPnP == "" && ni.PMP == "" && ni.PCP == "" {
|
if !ni.HavePortMap && ni.UPnP == "" && ni.PMP == "" && ni.PCP == "" {
|
||||||
return "?"
|
return "?"
|
||||||
}
|
}
|
||||||
return conciseOptBool(ni.UPnP, "U") + conciseOptBool(ni.PMP, "M") + conciseOptBool(ni.PCP, "C")
|
var prefix string
|
||||||
|
if ni.HavePortMap {
|
||||||
|
prefix = "active-"
|
||||||
|
}
|
||||||
|
return prefix + conciseOptBool(ni.UPnP, "U") + conciseOptBool(ni.PMP, "M") + conciseOptBool(ni.PCP, "C")
|
||||||
}
|
}
|
||||||
|
|
||||||
func conciseOptBool(b opt.Bool, trueVal string) string {
|
func conciseOptBool(b opt.Bool, trueVal string) string {
|
||||||
@ -512,6 +520,7 @@ func (ni *NetInfo) BasicallyEqual(ni2 *NetInfo) bool {
|
|||||||
ni.HairPinning == ni2.HairPinning &&
|
ni.HairPinning == ni2.HairPinning &&
|
||||||
ni.WorkingIPv6 == ni2.WorkingIPv6 &&
|
ni.WorkingIPv6 == ni2.WorkingIPv6 &&
|
||||||
ni.WorkingUDP == ni2.WorkingUDP &&
|
ni.WorkingUDP == ni2.WorkingUDP &&
|
||||||
|
ni.HavePortMap == ni2.HavePortMap &&
|
||||||
ni.UPnP == ni2.UPnP &&
|
ni.UPnP == ni2.UPnP &&
|
||||||
ni.PMP == ni2.PMP &&
|
ni.PMP == ni2.PMP &&
|
||||||
ni.PCP == ni2.PCP &&
|
ni.PCP == ni2.PCP &&
|
||||||
|
@ -143,6 +143,7 @@ var _NetInfoNeedsRegeneration = NetInfo(struct {
|
|||||||
HairPinning opt.Bool
|
HairPinning opt.Bool
|
||||||
WorkingIPv6 opt.Bool
|
WorkingIPv6 opt.Bool
|
||||||
WorkingUDP opt.Bool
|
WorkingUDP opt.Bool
|
||||||
|
HavePortMap bool
|
||||||
UPnP opt.Bool
|
UPnP opt.Bool
|
||||||
PMP opt.Bool
|
PMP opt.Bool
|
||||||
PCP opt.Bool
|
PCP opt.Bool
|
||||||
|
@ -375,6 +375,7 @@ func TestNetInfoFields(t *testing.T) {
|
|||||||
"HairPinning",
|
"HairPinning",
|
||||||
"WorkingIPv6",
|
"WorkingIPv6",
|
||||||
"WorkingUDP",
|
"WorkingUDP",
|
||||||
|
"HavePortMap",
|
||||||
"UPnP",
|
"UPnP",
|
||||||
"PMP",
|
"PMP",
|
||||||
"PCP",
|
"PCP",
|
||||||
|
@ -628,6 +628,23 @@ func (c *Conn) setEndpoints(endpoints []string, reasons map[string]string) (chan
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setNetInfoHavePortMap updates NetInfo.HavePortMap to true.
|
||||||
|
func (c *Conn) setNetInfoHavePortMap() {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
if c.netInfoLast == nil {
|
||||||
|
// No NetInfo yet. Nothing to update.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.netInfoLast.HavePortMap {
|
||||||
|
// No change.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ni := c.netInfoLast.Clone()
|
||||||
|
ni.HavePortMap = true
|
||||||
|
c.callNetInfoCallbackLocked(ni)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Conn) updateNetInfo(ctx context.Context) (*netcheck.Report, error) {
|
func (c *Conn) updateNetInfo(ctx context.Context) (*netcheck.Report, error) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
dm := c.derpMap
|
dm := c.derpMap
|
||||||
@ -658,6 +675,7 @@ func (c *Conn) updateNetInfo(ctx context.Context) (*netcheck.Report, error) {
|
|||||||
UPnP: report.UPnP,
|
UPnP: report.UPnP,
|
||||||
PMP: report.PMP,
|
PMP: report.PMP,
|
||||||
PCP: report.PCP,
|
PCP: report.PCP,
|
||||||
|
HavePortMap: c.portMapper.HaveMapping(),
|
||||||
}
|
}
|
||||||
for rid, d := range report.RegionV4Latency {
|
for rid, d := range report.RegionV4Latency {
|
||||||
ni.DERPLatency[fmt.Sprintf("%d-v4", rid)] = d.Seconds()
|
ni.DERPLatency[fmt.Sprintf("%d-v4", rid)] = d.Seconds()
|
||||||
@ -752,6 +770,10 @@ func (c *Conn) callNetInfoCallback(ni *tailcfg.NetInfo) {
|
|||||||
if ni.BasicallyEqual(c.netInfoLast) {
|
if ni.BasicallyEqual(c.netInfoLast) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.callNetInfoCallbackLocked(ni)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) callNetInfoCallbackLocked(ni *tailcfg.NetInfo) {
|
||||||
c.netInfoLast = ni
|
c.netInfoLast = ni
|
||||||
if c.netInfoFunc != nil {
|
if c.netInfoFunc != nil {
|
||||||
c.logf("[v1] magicsock: netInfo update: %+v", ni)
|
c.logf("[v1] magicsock: netInfo update: %+v", ni)
|
||||||
@ -1016,6 +1038,7 @@ func (c *Conn) determineEndpoints(ctx context.Context) (ipPorts []string, reason
|
|||||||
|
|
||||||
if ext, err := c.portMapper.CreateOrGetMapping(ctx); err == nil {
|
if ext, err := c.portMapper.CreateOrGetMapping(ctx); err == nil {
|
||||||
addAddr(ext.String(), "portmap")
|
addAddr(ext.String(), "portmap")
|
||||||
|
c.setNetInfoHavePortMap()
|
||||||
} else if !portmapper.IsNoMappingError(err) {
|
} else if !portmapper.IsNoMappingError(err) {
|
||||||
c.logf("portmapper: %v", err)
|
c.logf("portmapper: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user