net/dns,ipn/ipnlocal: add nodecap to resolve subdomains (#18258)
This adds a new node capability 'dns-subdomain-resolve' that signals that all of hosts' subdomains should resolve to the same IP address. It allows wildcard matching on any node marked with this capability. This change also includes an util/dnsname utility function that lets us access the parent of a full qualified domain name. MagicDNS takes this function and recursively searchs for a matching real node name. One important thing to observe is that, in this context, a subdomain can have multiple sub labels. This means that for a given node named machine, both my.machine and be.my.machine will be a positive match. Updates #1196 Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
This commit is contained in:
committed by
GitHub
parent
214b70cc1a
commit
f48cd46662
@@ -94,6 +94,18 @@ func (f FQDN) Contains(other FQDN) bool {
|
||||
return strings.HasSuffix(other.WithTrailingDot(), cmp)
|
||||
}
|
||||
|
||||
// Parent returns the parent domain by stripping the first label.
|
||||
// For "foo.bar.baz.", it returns "bar.baz."
|
||||
// It returns an empty FQDN for root or single-label domains.
|
||||
func (f FQDN) Parent() FQDN {
|
||||
s := f.WithTrailingDot()
|
||||
_, rest, ok := strings.Cut(s, ".")
|
||||
if !ok || rest == "" {
|
||||
return ""
|
||||
}
|
||||
return FQDN(rest)
|
||||
}
|
||||
|
||||
// ValidLabel reports whether label is a valid DNS label. All errors are
|
||||
// [vizerror.Error].
|
||||
func ValidLabel(label string) error {
|
||||
|
||||
@@ -123,6 +123,34 @@ func TestFQDNContains(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFQDNParent(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
want FQDN
|
||||
}{
|
||||
{"", ""},
|
||||
{".", ""},
|
||||
{"com.", ""},
|
||||
{"foo.com.", "com."},
|
||||
{"www.foo.com.", "foo.com."},
|
||||
{"a.b.c.d.", "b.c.d."},
|
||||
{"sub.node.tailnet.ts.net.", "node.tailnet.ts.net."},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.in, func(t *testing.T) {
|
||||
in, err := ToFQDN(test.in)
|
||||
if err != nil {
|
||||
t.Fatalf("ToFQDN(%q): %v", test.in, err)
|
||||
}
|
||||
got := in.Parent()
|
||||
if got != test.want {
|
||||
t.Errorf("ToFQDN(%q).Parent() = %q, want %q", test.in, got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeLabel(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user