|
|
|
|
@ -347,14 +347,36 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// resolveReverse returns the unique domain name that maps to the given address.
|
|
|
|
|
func (r *Resolver) resolveLocalReverse(ip netaddr.IP) (dnsname.FQDN, dns.RCode) { |
|
|
|
|
func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCode) { |
|
|
|
|
var ip netaddr.IP |
|
|
|
|
var ok bool |
|
|
|
|
switch { |
|
|
|
|
case strings.HasSuffix(name.WithTrailingDot(), rdnsv4Suffix): |
|
|
|
|
ip, ok = rdnsNameToIPv4(name) |
|
|
|
|
case strings.HasSuffix(name.WithTrailingDot(), rdnsv6Suffix): |
|
|
|
|
ip, ok = rdnsNameToIPv6(name) |
|
|
|
|
} |
|
|
|
|
if !ok { |
|
|
|
|
// This isn't a well-formed in-addr.arpa or ip6.arpa name, but
|
|
|
|
|
// who knows what upstreams might do, try kicking it up to
|
|
|
|
|
// them. We definitely won't handle it.
|
|
|
|
|
return "", dns.RCodeRefused |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
r.mu.Lock() |
|
|
|
|
defer r.mu.Unlock() |
|
|
|
|
name, ok := r.ipToHost[ip] |
|
|
|
|
ret, ok := r.ipToHost[ip] |
|
|
|
|
if !ok { |
|
|
|
|
return "", dns.RCodeNameError |
|
|
|
|
for _, suffix := range r.localDomains { |
|
|
|
|
if suffix.Contains(name) { |
|
|
|
|
// We are authoritative for this chunk of IP space.
|
|
|
|
|
return "", dns.RCodeNameError |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Not authoritative, signal that forwarding is advisable.
|
|
|
|
|
return "", dns.RCodeRefused |
|
|
|
|
} |
|
|
|
|
return name, dns.RCodeSuccess |
|
|
|
|
return ret, dns.RCodeSuccess |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *Resolver) handleQuery(pkt packet) { |
|
|
|
|
@ -650,26 +672,8 @@ func (r *Resolver) respondReverse(query []byte, name dnsname.FQDN, resp *respons |
|
|
|
|
return nil, errNotOurName |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ip netaddr.IP |
|
|
|
|
var ok bool |
|
|
|
|
switch { |
|
|
|
|
case strings.HasSuffix(name.WithTrailingDot(), rdnsv4Suffix): |
|
|
|
|
ip, ok = rdnsNameToIPv4(name) |
|
|
|
|
case strings.HasSuffix(name.WithTrailingDot(), rdnsv6Suffix): |
|
|
|
|
ip, ok = rdnsNameToIPv6(name) |
|
|
|
|
default: |
|
|
|
|
return nil, errNotOurName |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// It is more likely that we failed in parsing the name than that it is actually malformed.
|
|
|
|
|
// To avoid frustrating users, just log and delegate.
|
|
|
|
|
if !ok { |
|
|
|
|
r.logf("parsing rdns: malformed name: %s", name) |
|
|
|
|
return nil, errNotOurName |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
resp.Name, resp.Header.RCode = r.resolveLocalReverse(ip) |
|
|
|
|
if resp.Header.RCode == dns.RCodeNameError { |
|
|
|
|
resp.Name, resp.Header.RCode = r.resolveLocalReverse(name) |
|
|
|
|
if resp.Header.RCode == dns.RCodeRefused { |
|
|
|
|
return nil, errNotOurName |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|