tailcfg,ipn/ipnlocal,wgengine: add values to PeerCapabilities

Define PeerCapabilty and PeerCapMap as the new way of sending down
inter-peer capability information.

Previously, this was unstructured and you could only send down strings
which got too limiting for certain usecases. Instead add the ability
to send down raw JSON messages that are opaque to Tailscale but provide
the applications to define them however they wish.

Also update accessors to use the new values.

Updates #4217

Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
Maisem Ali
2023-07-24 21:07:00 -07:00
committed by Maisem Ali
parent 306deea03a
commit 1ecc16da5f
13 changed files with 139 additions and 68 deletions

View File

@@ -814,13 +814,13 @@ func (b *LocalBackend) WhoIs(ipp netip.AddrPort) (n *tailcfg.Node, u tailcfg.Use
// PeerCaps returns the capabilities that remote src IP has to
// ths current node.
func (b *LocalBackend) PeerCaps(src netip.Addr) []string {
func (b *LocalBackend) PeerCaps(src netip.Addr) tailcfg.PeerCapMap {
b.mu.Lock()
defer b.mu.Unlock()
return b.peerCapsLocked(src)
}
func (b *LocalBackend) peerCapsLocked(src netip.Addr) []string {
func (b *LocalBackend) peerCapsLocked(src netip.Addr) tailcfg.PeerCapMap {
if b.netMap == nil {
return nil
}
@@ -834,7 +834,7 @@ func (b *LocalBackend) peerCapsLocked(src netip.Addr) []string {
}
dst := a.Addr()
if dst.BitLen() == src.BitLen() { // match on family
return filt.AppendCaps(nil, src, dst)
return filt.CapsWithValues(src, dst)
}
}
return nil
@@ -4328,20 +4328,15 @@ func (b *LocalBackend) peerIsTaildropTargetLocked(p *tailcfg.Node) bool {
return true
}
if len(p.Addresses) > 0 &&
b.peerHasCapLocked(p.Addresses[0].Addr(), tailcfg.CapabilityFileSharingTarget) {
b.peerHasCapLocked(p.Addresses[0].Addr(), tailcfg.PeerCapabilityFileSharingTarget) {
// 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 {
return true
}
}
return false
func (b *LocalBackend) peerHasCapLocked(addr netip.Addr, wantCap tailcfg.PeerCapability) bool {
return b.peerCapsLocked(addr).HasCapability(wantCap)
}
// SetDNS adds a DNS record for the given domain name & TXT record

View File

@@ -1028,7 +1028,7 @@ func (h *peerAPIHandler) canPutFile() bool {
// Unsigned peers can't send files.
return false
}
return h.isSelf || h.peerHasCap(tailcfg.CapabilityFileSharingSend)
return h.isSelf || h.peerHasCap(tailcfg.PeerCapabilityFileSharingSend)
}
// canDebug reports whether h can debug this node (goroutines, metrics,
@@ -1042,7 +1042,7 @@ func (h *peerAPIHandler) canDebug() bool {
// Unsigned peers can't debug.
return false
}
return h.isSelf || h.peerHasCap(tailcfg.CapabilityDebugPeer)
return h.isSelf || h.peerHasCap(tailcfg.PeerCapabilityDebugPeer)
}
// canWakeOnLAN reports whether h can send a Wake-on-LAN packet from this node.
@@ -1050,23 +1050,18 @@ func (h *peerAPIHandler) canWakeOnLAN() bool {
if h.peerNode.UnsignedPeerAPIOnly {
return false
}
return h.isSelf || h.peerHasCap(tailcfg.CapabilityWakeOnLAN)
return h.isSelf || h.peerHasCap(tailcfg.PeerCapabilityWakeOnLAN)
}
var allowSelfIngress = envknob.RegisterBool("TS_ALLOW_SELF_INGRESS")
// canIngress reports whether h can send ingress requests to this node.
func (h *peerAPIHandler) canIngress() bool {
return h.peerHasCap(tailcfg.CapabilityIngress) || (allowSelfIngress() && h.isSelf)
return h.peerHasCap(tailcfg.PeerCapabilityIngress) || (allowSelfIngress() && h.isSelf)
}
func (h *peerAPIHandler) peerHasCap(wantCap string) bool {
for _, hasCap := range h.ps.b.PeerCaps(h.remoteAddr.Addr()) {
if hasCap == wantCap {
return true
}
}
return false
func (h *peerAPIHandler) peerHasCap(wantCap tailcfg.PeerCapability) bool {
return h.ps.b.PeerCaps(h.remoteAddr.Addr()).HasCapability(wantCap)
}
func (h *peerAPIHandler) handlePeerPut(w http.ResponseWriter, r *http.Request) {