From 6d76764f3745c529ffa62f78410de1646f3d5c68 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 7 Oct 2022 21:03:36 -0700 Subject: [PATCH] ipn/ipnlocal: fix taildrop target list UI bug The macOS and iOS apps that used the /localapi/v0/file-targets handler were getting too many candidate targets. They wouldn't actually accept the file. This is effectively just a UI glitch in the wrong hosts being listed as valid targets from the source side. Change-Id: I6907a5a1c3c66920e5ec71601c044e722e7cb888 Signed-off-by: Brad Fitzpatrick --- ipn/ipnlocal/local.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 12c4ca537..83ae81908 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -3419,10 +3419,7 @@ func (b *LocalBackend) FileTargets() ([]*apitype.FileTarget, error) { return nil, errors.New("file sharing not enabled by Tailscale admin") } for _, p := range nm.Peers { - if len(p.Addresses) == 0 { - continue - } - if p.User != nm.User && b.peerHasCapLocked(p.Addresses[0].Addr(), tailcfg.CapabilityFileSharing) { + if !b.peerIsTaildropTargetLocked(p) { continue } peerAPI := peerAPIBase(b.netMap, p) @@ -3438,6 +3435,26 @@ func (b *LocalBackend) FileTargets() ([]*apitype.FileTarget, error) { return ret, nil } +// peerIsTaildropTargetLocked reports whether p is a valid Taildrop file +// recipient from this node according to its ownership and the capabilities in +// the netmap. +// +// b.mu must be locked. +func (b *LocalBackend) peerIsTaildropTargetLocked(p *tailcfg.Node) bool { + if b.netMap == nil || p == nil { + return false + } + if b.netMap.User == p.User { + return true + } + if len(p.Addresses) > 0 && + b.peerHasCapLocked(p.Addresses[0].Addr(), tailcfg.CapabilityFileSharingTarget) { + // Explicitly noted in the netmap ACL caps as a target. + return true + } + return false +} + func (b *LocalBackend) peerHasCapLocked(addr netip.Addr, wantCap string) bool { for _, hasCap := range b.peerCapsLocked(addr) { if hasCap == wantCap {