···4949 parts := strings.Split(addr.Address, "@")
5050 domain := parts[1]
51515252- mx, err := net.LookupMX(domain)
5353- if err != nil || len(mx) == 0 {
5454- return false
5252+ canonical := coalesceToCanonicalName(domain)
5353+ mx, err := net.LookupMX(canonical)
5454+5555+ // Don't check err here; mx will only contain valid mx records, and we should
5656+ // only fallback to an implicit mx if there are no mx records defined (whether
5757+ // they are valid or not).
5858+ if len(mx) != 0 {
5959+ return true
6060+ }
6161+6262+ if err != nil {
6363+ // If the domain resolves to an address, assume it's an implicit mx.
6464+ address, _ := net.LookupIP(canonical)
6565+ if len(address) != 0 {
6666+ return true
6767+ }
5568 }
56695757- return true
7070+ return false
7171+}
7272+7373+func coalesceToCanonicalName(domain string) string {
7474+ canonical, err := net.LookupCNAME(domain)
7575+ if err != nil {
7676+ // net.LookupCNAME() returns an error if there is no cname record *and* no
7777+ // a/aaaa records, but there may still be mx records.
7878+ return domain
7979+ }
8080+ return canonical
5881}