net/dns/resolver: add yet another 4via6 DNS form that's hopefully more robust
$ dig +short @100.100.100.100 aaaa 10-2-5-3-via-7.foo-bar.ts.net fd7a:115c:a1e0:b1a:0:7:a02:503 $ dig +short @100.100.100.100 aaaa 10-2-5-3-via-7 fd7a:115c:a1e0:b1a:0:7:a02:503 $ ping 10-2-5-3-via-7 PING 10-2-5-3-via-7(fd7a:115c:a1e0:b1a:0:7:a02:503 (fd7a:115c:a1e0:b1a:0:7:a02:503)) 56 data bytes ... Change-Id: Ice8f954518a6a2fca8b2c04da7f31f61d78cdec4 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
e0cd9e9dec
commit
66b4a363bd
|
@ -550,7 +550,7 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netip.Addr,
|
|||
return tsaddr.TailscaleServiceIPv6(), dns.RCodeSuccess
|
||||
}
|
||||
}
|
||||
// Special-case: 'via-<siteid>.<ipv4>' queries.
|
||||
// Special-case: 4via6 DNS names.
|
||||
if ip, ok := r.parseViaDomain(domain, typ); ok {
|
||||
return ip, dns.RCodeSuccess
|
||||
}
|
||||
|
@ -630,7 +630,9 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netip.Addr,
|
|||
}
|
||||
|
||||
// parseViaDomain synthesizes an IP address for quad-A DNS requests of the form
|
||||
// `<IPv4-address>.via-<X>` and the deprecated form `via-<X>.<IPv4-address>`,
|
||||
// `<IPv4-address-with-hypens-instead-of-dots>-via-<siteid>[.*]`. Two prior formats that
|
||||
// didn't pan out (due to a Chrome issue and DNS search ndots issues) were
|
||||
// `<IPv4-address>.via-<X>` and the older `via-<X>.<IPv4-address>`,
|
||||
// where X is a decimal, or hex-encoded number with a '0x' prefix.
|
||||
//
|
||||
// This exists as a convenient mapping into Tailscales 'Via Range'.
|
||||
|
@ -650,14 +652,28 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netip.Addr
|
|||
|
||||
var siteID string
|
||||
var ip4Str string
|
||||
if strings.HasPrefix(fqdn, "via-") {
|
||||
switch {
|
||||
case strings.Contains(fqdn, "-via-"):
|
||||
// Format number 3: "192-168-1-2-via-7" or "192-168-1-2-via-7.foo.ts.net."
|
||||
// Third time's a charm. The earlier two formats follow after this block.
|
||||
firstLabel, domain, _ := strings.Cut(fqdn, ".") // "192-168-1-2-via-7"
|
||||
if !(domain == "" || dnsname.HasSuffix(domain, "ts.net") || dnsname.HasSuffix(domain, "tailscale.net")) {
|
||||
return netip.Addr{}, false
|
||||
}
|
||||
v4hyphens, suffix, ok := strings.Cut(firstLabel, "-via-")
|
||||
if !ok {
|
||||
return netip.Addr{}, false
|
||||
}
|
||||
siteID = suffix
|
||||
ip4Str = strings.ReplaceAll(v4hyphens, "-", ".")
|
||||
case strings.HasPrefix(fqdn, "via-"):
|
||||
firstDot := strings.Index(fqdn, ".")
|
||||
if firstDot < 0 {
|
||||
return netip.Addr{}, false // missing dot delimiters
|
||||
}
|
||||
siteID = fqdn[len("via-"):firstDot]
|
||||
ip4Str = fqdn[firstDot+1:]
|
||||
} else {
|
||||
default:
|
||||
lastDot := strings.LastIndex(fqdn, ".")
|
||||
if lastDot < 0 {
|
||||
return netip.Addr{}, false // missing dot delimiters
|
||||
|
@ -672,12 +688,12 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netip.Addr
|
|||
|
||||
ip4, err := netip.ParseAddr(ip4Str)
|
||||
if err != nil {
|
||||
return netip.Addr{}, false // badly formed, dont respond
|
||||
return netip.Addr{}, false // badly formed, don't respond
|
||||
}
|
||||
|
||||
prefix, err := strconv.ParseUint(siteID, 0, 32)
|
||||
if err != nil {
|
||||
return netip.Addr{}, false // badly formed, dont respond
|
||||
return netip.Addr{}, false // badly formed, don't respond
|
||||
}
|
||||
|
||||
// MapVia will never error when given an ipv4 netip.Prefix.
|
||||
|
|
|
@ -350,6 +350,18 @@ func TestResolveLocal(t *testing.T) {
|
|||
{"x_via_dec", dnsname.FQDN("1.0.0.10.via-1."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:1.0.0.10"), dns.RCodeSuccess},
|
||||
{"via_invalid", dnsname.FQDN("via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
|
||||
{"via_invalid_2", dnsname.FQDN("2.3.4.5.via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
|
||||
|
||||
// Hyphenated 4via6 format.
|
||||
// Without any suffix domain:
|
||||
{"via_form3_hex_bare", dnsname.FQDN("1-2-3-4-via-0xff."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:ff:1.2.3.4"), dns.RCodeSuccess},
|
||||
{"via_form3_dec_bare", dnsname.FQDN("1-2-3-4-via-1."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:1.2.3.4"), dns.RCodeSuccess},
|
||||
// With a Tailscale domain:
|
||||
{"via_form3_dec_ts.net", dnsname.FQDN("1-2-3-4-via-1.foo.ts.net."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:1.2.3.4"), dns.RCodeSuccess},
|
||||
{"via_form3_dec_tailscale.net", dnsname.FQDN("1-2-3-4-via-1.foo.tailscale.net."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:1.2.3.4"), dns.RCodeSuccess},
|
||||
// Non-Tailscale domain suffixes aren't allowed for now: (the allowed
|
||||
// suffixes are currently hard-coded and not plumbed via the netmap)
|
||||
{"via_form3_dec_example.com", dnsname.FQDN("1-2-3-4-via-1.example.com."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
|
||||
{"via_form3_dec_examplets.net", dnsname.FQDN("1-2-3-4-via-1.examplets.net."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
Loading…
Reference in New Issue