mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-26 11:11:01 +00:00
net/dns/resolver: support magic resolution of via-<siteid>.<ip4> domains
Updates #3616 Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
parent
910ae68e0b
commit
78fededaa5
@ -17,6 +17,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -633,6 +634,10 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
|
|||||||
return tsaddr.TailscaleServiceIPv6(), dns.RCodeSuccess
|
return tsaddr.TailscaleServiceIPv6(), dns.RCodeSuccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Special-case: 'via-<siteid>.<ipv4>' queries.
|
||||||
|
if ip, ok := r.parseViaDomain(domain, typ); ok {
|
||||||
|
return ip, dns.RCodeSuccess
|
||||||
|
}
|
||||||
|
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
hosts := r.hostToIP
|
hosts := r.hostToIP
|
||||||
@ -708,6 +713,46 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseViaDomain synthesizes an IP address for quad-A DNS requests of
|
||||||
|
// the form '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'.
|
||||||
|
func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP, bool) {
|
||||||
|
fqdn := string(domain.WithoutTrailingDot())
|
||||||
|
if typ != dns.TypeAAAA {
|
||||||
|
return netaddr.IP{}, false
|
||||||
|
}
|
||||||
|
if len(fqdn) < len("via-X.0.0.0.0") {
|
||||||
|
return netaddr.IP{}, false // too short to be valid
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(fqdn, "via-") {
|
||||||
|
return netaddr.IP{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
firstDot := strings.Index(fqdn, ".")
|
||||||
|
if firstDot < 0 {
|
||||||
|
return netaddr.IP{}, false // missing dot delimiters
|
||||||
|
}
|
||||||
|
|
||||||
|
siteID := fqdn[len("via-"):firstDot]
|
||||||
|
ip4Str := fqdn[firstDot+1:]
|
||||||
|
|
||||||
|
ip4, err := netaddr.ParseIP(ip4Str)
|
||||||
|
if err != nil {
|
||||||
|
return netaddr.IP{}, false // badly formed, dont respond
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix, err := strconv.ParseUint(siteID, 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return netaddr.IP{}, false // badly formed, dont respond
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapVia will never error when given an ipv4 netaddr.IPPrefix.
|
||||||
|
out, _ := tsaddr.MapVia(uint32(prefix), netaddr.IPPrefixFrom(ip4, ip4.BitLen()))
|
||||||
|
return out.IP(), true
|
||||||
|
}
|
||||||
|
|
||||||
// resolveReverse returns the unique domain name that maps to the given address.
|
// resolveReverse returns the unique domain name that maps to the given address.
|
||||||
func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
|
func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
|
||||||
var ip netaddr.IP
|
var ip netaddr.IP
|
||||||
|
@ -348,6 +348,9 @@ func TestResolveLocal(t *testing.T) {
|
|||||||
{"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netaddr.IP{}, dns.RCodeNameError},
|
{"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netaddr.IP{}, dns.RCodeNameError},
|
||||||
{"onion-domain", "footest.onion.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError},
|
{"onion-domain", "footest.onion.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError},
|
||||||
{"magicdns", dnsSymbolicFQDN, dns.TypeA, netaddr.MustParseIP("100.100.100.100"), dns.RCodeSuccess},
|
{"magicdns", dnsSymbolicFQDN, dns.TypeA, netaddr.MustParseIP("100.100.100.100"), dns.RCodeSuccess},
|
||||||
|
{"via_hex", dnsname.FQDN("via-0xff.1.2.3.4."), dns.TypeAAAA, netaddr.MustParseIP("fd7a:115c:a1e0:b1a:0:ff:102:304"), dns.RCodeSuccess},
|
||||||
|
{"via_dec", dnsname.FQDN("via-1.10.0.0.1."), dns.TypeAAAA, netaddr.MustParseIP("fd7a:115c:a1e0:b1a:0:1:a00:1"), dns.RCodeSuccess},
|
||||||
|
{"via_invalid", dnsname.FQDN("via-."), dns.TypeA, netaddr.IP{}, dns.RCodeRefused},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user