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
|
// Check if we got a SOA RR in the answer section
|
||||||
if in.Rcode == dns.RcodeSuccess {
|
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 {
|
for _, ans := range in.Answer {
|
||||||
if soa, ok := ans.(*dns.SOA); ok {
|
if soa, ok := ans.(*dns.SOA); ok {
|
||||||
zone := soa.Hdr.Name
|
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")
|
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.
|
// ClearFqdnCache clears the cache of fqdn to zone mappings. Primarily used in testing.
|
||||||
func ClearFqdnCache() {
|
func ClearFqdnCache() {
|
||||||
fqdnToZone = map[string]string{}
|
fqdnToZone = map[string]string{}
|
||||||
|
|
|
@ -43,9 +43,10 @@ var findZoneByFqdnTests = []struct {
|
||||||
fqdn string
|
fqdn string
|
||||||
zone string
|
zone string
|
||||||
}{
|
}{
|
||||||
{"mail.google.com.", "google.com."}, // domain is a CNAME
|
{"mail.google.com.", "google.com."}, // domain is a CNAME
|
||||||
{"foo.google.com.", "google.com."}, // domain is a non-existent subdomain
|
{"foo.google.com.", "google.com."}, // domain is a non-existent subdomain
|
||||||
{"example.com.ac.", "ac."}, // domain is a eTLD
|
{"example.com.ac.", "ac."}, // domain is a eTLD
|
||||||
|
{"cross-zone-example.assets.sh.", "assets.sh."}, // domain is a cross-zone CNAME
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkAuthoritativeNssTests = []struct {
|
var checkAuthoritativeNssTests = []struct {
|
||||||
|
|
Loading…
Reference in a new issue