diff --git a/net/dns/resolver/tsdns.go b/net/dns/resolver/tsdns.go index 8a0ce2f48..517606e23 100644 --- a/net/dns/resolver/tsdns.go +++ b/net/dns/resolver/tsdns.go @@ -763,23 +763,16 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netip.Addr, } // resolveViaDomain synthesizes an IP address for quad-A DNS requests of the form -// `-via-[.*]`. Two prior formats that -// didn't pan out (due to a Chrome issue and DNS search ndots issues) were -// `.via-` and the older `via-.`, -// where X is a decimal, or hex-encoded number with a '0x' prefix. +// `-via-[.*]`. +// For example: "192-168-1-2-via-7" or "192-168-1-2-via-7.foo.ts.net." // // This exists as a convenient mapping into Tailscales 'Via Range'. // // It returns a zero netip.Addr and true to indicate a successful response with // an empty answers section if the specified domain is a valid Tailscale 4via6 // domain, but the request type is neither quad-A nor ALL. -// -// TODO(maisem/bradfitz/tom): `.via-` was introduced -// (2022-06-02) to work around an issue in Chrome where it would treat -// "http://via-1.1.2.3.4" as a search string instead of a URL. We should rip out -// the old format in early 2023. -func (r *Resolver) resolveViaDomain(domain dnsname.FQDN, typ dns.Type) (netip.Addr, bool) { - fqdn := string(domain.WithoutTrailingDot()) +func (r *Resolver) resolveViaDomain(dnsName dnsname.FQDN, typ dns.Type) (netip.Addr, bool) { + fqdn := string(dnsName.WithoutTrailingDot()) switch typ { case dns.TypeA, dns.TypeAAAA, dns.TypeALL: // For Type A requests, we should return a successful response @@ -793,45 +786,23 @@ func (r *Resolver) resolveViaDomain(domain dnsname.FQDN, typ dns.Type) (netip.Ad default: return netip.Addr{}, false } - if len(fqdn) < len("via-X.0.0.0.0") { + if len(fqdn) < len("0-0-0-0-via-0") { return netip.Addr{}, false // too short to be valid } - var siteID string - var ip4Str string - 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:] - default: - lastDot := strings.LastIndex(fqdn, ".") - if lastDot < 0 { - return netip.Addr{}, false // missing dot delimiters - } - suffix := fqdn[lastDot+1:] - if !strings.HasPrefix(suffix, "via-") { - return netip.Addr{}, false - } - siteID = suffix[len("via-"):] - ip4Str = fqdn[:lastDot] + if !strings.Contains(fqdn, "-via-") { + return netip.Addr{}, false // not a 4via6 domain } + 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, "-", ".") ip4, err := netip.ParseAddr(ip4Str) if err != nil { diff --git a/net/dns/resolver/tsdns_test.go b/net/dns/resolver/tsdns_test.go index 381ceedb4..a8c568d3d 100644 --- a/net/dns/resolver/tsdns_test.go +++ b/net/dns/resolver/tsdns_test.go @@ -390,12 +390,8 @@ func TestResolveLocal(t *testing.T) { {"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netip.Addr{}, dns.RCodeNameError}, {"onion-domain", "footest.onion.", dns.TypeA, netip.Addr{}, dns.RCodeNameError}, {"magicdns", dnsSymbolicFQDN, dns.TypeA, netip.MustParseAddr("100.100.100.100"), dns.RCodeSuccess}, - {"via_hex", dnsname.FQDN("via-0xff.1.2.3.4."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:ff:1.2.3.4"), dns.RCodeSuccess}, - {"via_dec", dnsname.FQDN("via-1.10.0.0.1."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:10.0.0.1"), dns.RCodeSuccess}, - {"x_via_hex", dnsname.FQDN("4.3.2.1.via-0xff."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:ff:4.3.2.1"), dns.RCodeSuccess}, - {"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}, + {"via_invalid_2", dnsname.FQDN("2-3-4-5-via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused}, // Hyphenated 4via6 format. // Without any suffix domain: