ipn/ipnlocal: pass along localNodeContext lock state in context

Fixes #15824

Change-Id: I0a85fda892ee34513a5d1b45ac47202e717f45c1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2025-04-29 11:49:51 -07:00
parent cc6f367520
commit 1a2b02849c
3 changed files with 17 additions and 9 deletions

View File

@ -4,6 +4,7 @@
package ipnlocal package ipnlocal
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"slices" "slices"
@ -338,7 +339,7 @@ func (b *LocalBackend) driveRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Rem
// Check that the peer is allowed to share with us. // Check that the peer is allowed to share with us.
addresses := peer.Addresses() addresses := peer.Addresses()
for _, p := range addresses.All() { for _, p := range addresses.All() {
if cn.PeerHasCap(p.Addr(), tailcfg.PeerCapabilityTaildriveSharer) { if cn.PeerHasCap(context.Background(), p.Addr(), tailcfg.PeerCapabilityTaildriveSharer) {
return true return true
} }
} }

View File

@ -96,6 +96,7 @@ import (
"tailscale.com/types/ptr" "tailscale.com/types/ptr"
"tailscale.com/types/views" "tailscale.com/types/views"
"tailscale.com/util/clientmetric" "tailscale.com/util/clientmetric"
"tailscale.com/util/ctxkey"
"tailscale.com/util/deephash" "tailscale.com/util/deephash"
"tailscale.com/util/dnsname" "tailscale.com/util/dnsname"
"tailscale.com/util/goroutines" "tailscale.com/util/goroutines"
@ -1463,7 +1464,11 @@ func (b *LocalBackend) PeerCaps(src netip.Addr) tailcfg.PeerCapMap {
return b.currentNode().PeerCaps(src) return b.currentNode().PeerCaps(src)
} }
func (b *localNodeContext) AppendMatchingPeers(base []tailcfg.NodeView, pred func(tailcfg.NodeView) bool) []tailcfg.NodeView { var nodeCtxLockedKey = ctxkey.New("localNodeContext-locked", false)
var ctxNodeContextLocked = nodeCtxLockedKey.WithValue(context.Background(), true)
func (b *localNodeContext) AppendMatchingPeers(base []tailcfg.NodeView, pred func(context.Context, tailcfg.NodeView) bool) []tailcfg.NodeView {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() defer b.mu.Unlock()
ret := base ret := base
@ -1471,7 +1476,7 @@ func (b *localNodeContext) AppendMatchingPeers(base []tailcfg.NodeView, pred fun
return ret return ret
} }
for _, peer := range b.netMap.Peers { for _, peer := range b.netMap.Peers {
if pred(peer) { if pred(ctxNodeContextLocked, peer) {
ret = append(ret, peer) ret = append(ret, peer)
} }
} }
@ -6652,9 +6657,11 @@ func (b *LocalBackend) TestOnlyPublicKeys() (machineKey key.MachinePublic, nodeK
// PeerHasCap reports whether the peer with the given Tailscale IP addresses // PeerHasCap reports whether the peer with the given Tailscale IP addresses
// contains the given capability string, with any value(s). // contains the given capability string, with any value(s).
func (b *localNodeContext) PeerHasCap(addr netip.Addr, wantCap tailcfg.PeerCapability) bool { func (b *localNodeContext) PeerHasCap(ctx context.Context, addr netip.Addr, wantCap tailcfg.PeerCapability) bool {
b.mu.Lock() if !nodeCtxLockedKey.Value(ctx) {
defer b.mu.Unlock() b.mu.Lock()
defer b.mu.Unlock()
}
return b.peerHasCapLocked(addr, wantCap) return b.peerHasCapLocked(addr, wantCap)
} }

View File

@ -190,14 +190,14 @@ func (b *LocalBackend) FileTargets() ([]*apitype.FileTarget, error) {
if !b.capFileSharing { if !b.capFileSharing {
return nil, errors.New("file sharing not enabled by Tailscale admin") return nil, errors.New("file sharing not enabled by Tailscale admin")
} }
peers := cn.AppendMatchingPeers(nil, func(p tailcfg.NodeView) bool { peers := cn.AppendMatchingPeers(nil, func(ctx context.Context, p tailcfg.NodeView) bool {
if !p.Valid() || p.Hostinfo().OS() == "tvOS" { if !p.Valid() || p.Hostinfo().OS() == "tvOS" {
return false return false
} }
if self != p.User() { if self != p.User() {
return false return false
} }
if p.Addresses().Len() != 0 && cn.PeerHasCap(p.Addresses().At(0).Addr(), tailcfg.PeerCapabilityFileSharingTarget) { if p.Addresses().Len() != 0 && cn.PeerHasCap(ctx, p.Addresses().At(0).Addr(), tailcfg.PeerCapabilityFileSharingTarget) {
// Explicitly noted in the netmap ACL caps as a target. // Explicitly noted in the netmap ACL caps as a target.
return true return true
} }
@ -241,7 +241,7 @@ func (b *LocalBackend) taildropTargetStatus(p tailcfg.NodeView) ipnstate.Taildro
} }
if nm.User() != p.User() { if nm.User() != p.User() {
// Different user must have the explicit file sharing target capability // Different user must have the explicit file sharing target capability
if p.Addresses().Len() == 0 || !cn.PeerHasCap(p.Addresses().At(0).Addr(), tailcfg.PeerCapabilityFileSharingTarget) { if p.Addresses().Len() == 0 || !cn.PeerHasCap(context.Background(), p.Addresses().At(0).Addr(), tailcfg.PeerCapabilityFileSharingTarget) {
// Explicitly noted in the netmap ACL caps as a target. // Explicitly noted in the netmap ACL caps as a target.
return ipnstate.TaildropTargetOwnedByOtherUser return ipnstate.TaildropTargetOwnedByOtherUser
} }