Fix zone detection for cross-zone cnames (#449)
* Fix zone detection for cross-zone cnames CNAMEs cannot co-exist with SOA records so responses with a CNAME should be skipped. The `cross-zone-example.assets.sh.` is currently hosted by me (@fd) and will continue to exist for as long as the assets.sh domain exists. (The assets.sh domain is used as a CDN and is unlikely to go away.) See #330 * Extracted CNAME checking to simplify the FindZoneByFqdn control flow.
This commit is contained in:
parent
922235d33e
commit
b929aa5aab
2 changed files with 21 additions and 3 deletions
|
@ -255,6 +255,13 @@ func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) {
|
|||
|
||||
// Check if we got a SOA RR in the answer section
|
||||
if in.Rcode == dns.RcodeSuccess {
|
||||
|
||||
// CNAME records cannot/should not exist at the root of a zone.
|
||||
// So we skip a domain when a CNAME is found.
|
||||
if dnsMsgContainsCNAME(in) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, ans := range in.Answer {
|
||||
if soa, ok := ans.(*dns.SOA); ok {
|
||||
zone := soa.Hdr.Name
|
||||
|
@ -268,6 +275,16 @@ func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) {
|
|||
return "", fmt.Errorf("Could not find the start of authority")
|
||||
}
|
||||
|
||||
// dnsMsgContainsCNAME checks for a CNAME answer in msg
|
||||
func dnsMsgContainsCNAME(msg *dns.Msg) bool {
|
||||
for _, ans := range msg.Answer {
|
||||
if _, ok := ans.(*dns.CNAME); ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ClearFqdnCache clears the cache of fqdn to zone mappings. Primarily used in testing.
|
||||
func ClearFqdnCache() {
|
||||
fqdnToZone = map[string]string{}
|
||||
|
|
|
@ -43,9 +43,10 @@ var findZoneByFqdnTests = []struct {
|
|||
fqdn string
|
||||
zone string
|
||||
}{
|
||||
{"mail.google.com.", "google.com."}, // domain is a CNAME
|
||||
{"foo.google.com.", "google.com."}, // domain is a non-existent subdomain
|
||||
{"example.com.ac.", "ac."}, // domain is a eTLD
|
||||
{"mail.google.com.", "google.com."}, // domain is a CNAME
|
||||
{"foo.google.com.", "google.com."}, // domain is a non-existent subdomain
|
||||
{"example.com.ac.", "ac."}, // domain is a eTLD
|
||||
{"cross-zone-example.assets.sh.", "assets.sh."}, // domain is a cross-zone CNAME
|
||||
}
|
||||
|
||||
var checkAuthoritativeNssTests = []struct {
|
||||
|
|
Loading…
Reference in a new issue