ipn/ipnlocal: move selfNode from peerAPIServer to peerAPIHandler

The peerAPIHandler is instantiated per PeerAPI call so it is
guaranteed to have the latest selfNode.

Signed-off-by: Maisem Ali <maisem@tailscale.com>
pull/6365/head
Maisem Ali 2 years ago committed by Maisem Ali
parent 2f4fca65a1
commit b0736fe6f7

@ -2784,7 +2784,6 @@ func (b *LocalBackend) initPeerAPIListener() {
ps := &peerAPIServer{ ps := &peerAPIServer{
b: b, b: b,
rootDir: fileRoot, rootDir: fileRoot,
selfNode: selfNode,
directFileMode: b.directFileRoot != "", directFileMode: b.directFileRoot != "",
directFileDoFinalRename: b.directFileDoFinalRename, directFileDoFinalRename: b.directFileDoFinalRename,
} }

@ -60,7 +60,6 @@ var addH2C func(*http.Server)
type peerAPIServer struct { type peerAPIServer struct {
b *LocalBackend b *LocalBackend
rootDir string // empty means file receiving unavailable rootDir string // empty means file receiving unavailable
selfNode *tailcfg.Node
knownEmpty atomic.Bool knownEmpty atomic.Bool
resolver *resolver.Resolver resolver *resolver.Resolver
@ -514,10 +513,17 @@ func (pln *peerAPIListener) ServeConn(src netip.AddrPort, c net.Conn) {
c.Close() c.Close()
return return
} }
nm := pln.lb.NetMap()
if nm == nil || nm.SelfNode == nil {
logf("peerapi: no netmap")
c.Close()
return
}
h := &peerAPIHandler{ h := &peerAPIHandler{
ps: pln.ps, ps: pln.ps,
isSelf: pln.ps.selfNode.User == peerNode.User, isSelf: nm.SelfNode.User == peerNode.User,
remoteAddr: src, remoteAddr: src,
selfNode: nm.SelfNode,
peerNode: peerNode, peerNode: peerNode,
peerUser: peerUser, peerUser: peerUser,
} }
@ -535,6 +541,7 @@ type peerAPIHandler struct {
ps *peerAPIServer ps *peerAPIServer
remoteAddr netip.AddrPort remoteAddr netip.AddrPort
isSelf bool // whether peerNode is owned by same user as this node isSelf bool // whether peerNode is owned by same user as this node
selfNode *tailcfg.Node // this node; always non-nil
peerNode *tailcfg.Node // peerNode is who's making the request peerNode *tailcfg.Node // peerNode is who's making the request
peerUser tailcfg.UserProfile // profile of peerNode peerUser tailcfg.UserProfile // profile of peerNode
} }
@ -552,7 +559,7 @@ func (h *peerAPIHandler) validateHost(r *http.Request) error {
return err return err
} }
hostIPPfx := netip.PrefixFrom(ap.Addr(), ap.Addr().BitLen()) hostIPPfx := netip.PrefixFrom(ap.Addr(), ap.Addr().BitLen())
if !slices.Contains(h.ps.selfNode.Addresses, hostIPPfx) { if !slices.Contains(h.selfNode.Addresses, hostIPPfx) {
return fmt.Errorf("%v not found in self addresses", hostIPPfx) return fmt.Errorf("%v not found in self addresses", hostIPPfx)
} }
return nil return nil
@ -778,14 +785,7 @@ func (h *peerAPIHandler) canPutFile() bool {
// canDebug reports whether h can debug this node (goroutines, metrics, // canDebug reports whether h can debug this node (goroutines, metrics,
// magicsock internal state, etc). // magicsock internal state, etc).
func (h *peerAPIHandler) canDebug() bool { func (h *peerAPIHandler) canDebug() bool {
// Reread the selfNode as it may have changed since the peerAPIServer if !slices.Contains(h.selfNode.Capabilities, tailcfg.CapabilityDebug) {
// was created.
// TODO(maisem): handle this in other places too.
nm := h.ps.b.NetMap()
if nm == nil || nm.SelfNode == nil {
return false
}
if !slices.Contains(nm.SelfNode.Capabilities, tailcfg.CapabilityDebug) {
// This node does not expose debug info. // This node does not expose debug info.
return false return false
} }

@ -449,6 +449,9 @@ func TestHandlePeerAPI(t *testing.T) {
netip.MustParsePrefix("100.100.100.101/32"), netip.MustParsePrefix("100.100.100.101/32"),
}, },
} }
if tt.debugCap {
selfNode.Capabilities = append(selfNode.Capabilities, tailcfg.CapabilityDebug)
}
var e peerAPITestEnv var e peerAPITestEnv
lb := &LocalBackend{ lb := &LocalBackend{
logf: e.logBuf.Logf, logf: e.logBuf.Logf,
@ -456,18 +459,15 @@ func TestHandlePeerAPI(t *testing.T) {
netMap: &netmap.NetworkMap{SelfNode: selfNode}, netMap: &netmap.NetworkMap{SelfNode: selfNode},
} }
e.ph = &peerAPIHandler{ e.ph = &peerAPIHandler{
isSelf: tt.isSelf, isSelf: tt.isSelf,
selfNode: selfNode,
peerNode: &tailcfg.Node{ peerNode: &tailcfg.Node{
ComputedName: "some-peer-name", ComputedName: "some-peer-name",
}, },
ps: &peerAPIServer{ ps: &peerAPIServer{
b: lb, b: lb,
selfNode: selfNode,
}, },
} }
if tt.debugCap {
e.ph.ps.selfNode.Capabilities = append(e.ph.ps.selfNode.Capabilities, tailcfg.CapabilityDebug)
}
var rootDir string var rootDir string
if !tt.omitRoot { if !tt.omitRoot {
rootDir = t.TempDir() rootDir = t.TempDir()
@ -507,9 +507,6 @@ func TestFileDeleteRace(t *testing.T) {
logf: t.Logf, logf: t.Logf,
capFileSharing: true, capFileSharing: true,
}, },
selfNode: &tailcfg.Node{
Addresses: []netip.Prefix{netip.MustParsePrefix("100.100.100.101/32")},
},
rootDir: dir, rootDir: dir,
} }
ph := &peerAPIHandler{ ph := &peerAPIHandler{
@ -517,6 +514,9 @@ func TestFileDeleteRace(t *testing.T) {
peerNode: &tailcfg.Node{ peerNode: &tailcfg.Node{
ComputedName: "some-peer-name", ComputedName: "some-peer-name",
}, },
selfNode: &tailcfg.Node{
Addresses: []netip.Prefix{netip.MustParsePrefix("100.100.100.101/32")},
},
ps: ps, ps: ps,
} }
buf := make([]byte, 2<<20) buf := make([]byte, 2<<20)

Loading…
Cancel
Save