diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index bc3693dab..0811ecc9f 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -2794,9 +2794,11 @@ const ( const ( // NodeAttrPrefixServices is the prefix for per-service [NodeCapMap] - // entries describing Services visible (accessible) to this node. The full - // key for a service named "svc:foo" is NodeAttrPrefixServices+"foo". + // entries describing Services visible (accessible) to this node. // Each value under such a key is of type [ServiceDetails]. + // The suffix after the prefix is an opaque server-chosen identifier; + // consumers must use [ServiceDetails.Name] as the canonical service name + // rather than parsing it from the map key. NodeAttrPrefixServices NodeCapabilityPrefix = "services/" ) diff --git a/types/netmap/netmap.go b/types/netmap/netmap.go index ef76c05da..b768caf4c 100644 --- a/types/netmap/netmap.go +++ b/types/netmap/netmap.go @@ -147,8 +147,10 @@ func (nm *NetworkMap) GetIPVIPServiceMap() IPServiceMappings { } // Services returns the Services visible (accessible) to this node, -// decoded from [tailcfg.NodeAttrPrefixServices]+serviceName entries in the -// self node's CapMap. Returns nil if nm is nil or SelfNode is invalid. +// decoded from [tailcfg.NodeAttrPrefixServices] entries in the self node's +// CapMap. The returned map is keyed by [tailcfg.ServiceDetails.Name], which is +// the canonical service name; the NodeCapMap key suffix is opaque and must not +// be parsed or relied upon. It returns nil if nm is nil or SelfNode is invalid. // // TODO(adrianosela): cache the result of decoding the capmap so // we don't have to decode it multiple times after each netmap update.