From 3b22615aec46eb7e4664c93f6ae77c1f5a6ed8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 4 Aug 2026 22:29:14 +0800 Subject: [PATCH] tailscale: Match bare hostnames in preferred_by when search domains exist MagicDNS resolves single-label names via tailnet search domains, so route preferred_by should treat them as tailscale domains, matching official client behavior. --- protocol/tailscale/endpoint.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/protocol/tailscale/endpoint.go b/protocol/tailscale/endpoint.go index 32c00d47..27bbef50 100644 --- a/protocol/tailscale/endpoint.go +++ b/protocol/tailscale/endpoint.go @@ -98,6 +98,7 @@ type Endpoint struct { routerCfg *router.Config dnsCfg *tsDNS.Config routeDomains common.TypedValue[map[string]bool] + searchDomains atomic.Bool routePrefixes atomic.Pointer[netipx.IPSet] acceptRoutes bool @@ -785,7 +786,11 @@ func (t *Endpoint) PreferredDomain(domain string) bool { if routeDomains == nil { return false } - return routeDomains[strings.ToLower(domain)] + domain = strings.ToLower(domain) + if routeDomains[domain] { + return true + } + return !strings.Contains(domain, ".") && t.searchDomains.Load() } func (t *Endpoint) PreferredAddress(address netip.Addr) bool { @@ -830,6 +835,7 @@ func (t *Endpoint) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCf routeDomains[fqdn.WithoutTrailingDot()] = true } t.routeDomains.Store(routeDomains) + t.searchDomains.Store(len(dnsCfg.SearchDomains) > 0) var builder netipx.IPSetBuilder for _, peer := range cfg.Peers {