From f01091babe85c5fd2e8205a3823f382ed634edbc Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 30 Mar 2021 09:54:52 -0700 Subject: [PATCH] ipn/ipnlocal: make peerapi work in netstack mode Signed-off-by: Brad Fitzpatrick --- ipn/ipnlocal/local.go | 30 +++++++++++++++++++++--------- ipn/ipnlocal/peerapi.go | 20 +++++++++++++++++++- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 505d15bb3..aee143ee6 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -1490,7 +1490,7 @@ func (b *LocalBackend) initPeerAPIListener() { defer b.mu.Unlock() for _, pln := range b.peerAPIListeners { - pln.ln.Close() + pln.Close() } b.peerAPIListeners = nil @@ -1527,20 +1527,32 @@ func (b *LocalBackend) initPeerAPIListener() { selfNode: selfNode, } - for _, a := range b.netMap.Addresses { - ln, err := ps.listen(a.IP, b.prevIfState) - if err != nil { - b.logf("[unexpected] peerAPI listen(%q) error: %v", a.IP, err) - continue + isNetstack := wgengine.IsNetstack(b.e) + for i, a := range b.netMap.Addresses { + var ln net.Listener + var err error + skipListen := i > 0 && isNetstack + if !skipListen { + ln, err = ps.listen(a.IP, b.prevIfState) + if err != nil { + b.logf("[unexpected] peerapi listen(%q) error: %v", a.IP, err) + continue + } } pln := &peerAPIListener{ ps: ps, ip: a.IP, - ln: ln, + ln: ln, // nil for 2nd+ on netstack lb: b, } - pln.urlStr = "http://" + net.JoinHostPort(a.IP.String(), strconv.Itoa(pln.Port())) - + var port int + if skipListen { + port = b.peerAPIListeners[0].Port() + } else { + port = pln.Port() + } + pln.urlStr = "http://" + net.JoinHostPort(a.IP.String(), strconv.Itoa(port)) + b.logf("peerapi: serving on %s", pln.urlStr) go pln.serve() b.peerAPIListeners = append(b.peerAPIListeners, pln) } diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go index 857639610..0c8033cc2 100644 --- a/ipn/ipnlocal/peerapi.go +++ b/ipn/ipnlocal/peerapi.go @@ -24,6 +24,7 @@ import ( "inet.af/netaddr" "tailscale.com/net/interfaces" "tailscale.com/tailcfg" + "tailscale.com/wgengine" ) var initListenConfig func(*net.ListenConfig, netaddr.IP, *interfaces.State, string) error @@ -51,6 +52,10 @@ func (s *peerAPIServer) listen(ip netaddr.IP, ifState *interfaces.State) (ln net } } + if wgengine.IsNetstack(s.b.e) { + ipStr = "" + } + tcp4or6 := "tcp4" if ip.Is6() { tcp4or6 = "tcp6" @@ -81,12 +86,22 @@ func (s *peerAPIServer) listen(ip netaddr.IP, ifState *interfaces.State) (ln net type peerAPIListener struct { ps *peerAPIServer ip netaddr.IP - ln net.Listener + ln net.Listener // or nil for 2nd+ address family in netstack mdoe lb *LocalBackend urlStr string } +func (pln *peerAPIListener) Close() error { + if pln.ln != nil { + return pln.ln.Close() + } + return nil +} + func (pln *peerAPIListener) Port() int { + if pln.ln == nil { + return 0 + } ta, ok := pln.ln.Addr().(*net.TCPAddr) if !ok { return 0 @@ -95,6 +110,9 @@ func (pln *peerAPIListener) Port() int { } func (pln *peerAPIListener) serve() { + if pln.ln == nil { + return + } defer pln.ln.Close() logf := pln.lb.logf for {