如何区分空的MX记录列表和Go中的DNS错误?

t3psigkw  于 2023-04-27  发布在  Go
关注(0)|答案(1)|浏览(110)

我正在发送邮件。每当我想发送电子邮件到“example@gmail.com”时,我都会进行DNS查找以获取“gmail.com”的MX记录列表

mxs, err := net.LookupMX(domain)

对于具有MX记录的域,这是足够简单的,但是RFC5321第5.1节说
如果返回的MX列表为空,则该地址将被视为与隐式MX RR相关联,首选项为0,指向该主机。
因此,如果一个域没有MX记录(如chat.google.com),我需要直接向“chat.google.com”发送邮件。为了做到这一点,我需要检测net.LookupMX()何时得到空响应。问题是net.LookupMX()认为空响应是错误的。我做了一个小测试来演示这一点:

var resolver net.Resolver
for _, preferGo := range []bool{true, false} {
    for _, strictErrors := range []bool{true, false} {
        resolver.PreferGo = preferGo
        resolver.StrictErrors = strictErrors
        fmt.Printf("PreferGo: %v\tStrictErrors: %v\t", preferGo, strictErrors)
        result, err := resolver.LookupMX(context.Background(), "chat.google.com")
        fmt.Printf("Result: %v\tError: %v\n", result, err)
    }
}
PreferGo: true  StrictErrors: true      Result: []      Error: lookup chat.google.com on 10.64.15.252:53: no such host
PreferGo: true  StrictErrors: false     Result: []      Error: lookup chat.google.com on 10.64.15.252:53: no such host
PreferGo: false StrictErrors: true      Result: []      Error: lookup chat.google.com: dnsquery: No records found for given DNS query.
PreferGo: false StrictErrors: false     Result: []      Error: lookup chat.google.com: dnsquery: No records found for given DNS query.

我希望net.LookupMX()将返回[], nil的空结果。但是,错误值似乎与平台相关。我可以测试在每个平台上获得的err.String()值(Windows,Mac,Linux,FreeBSD等)并做一些正则表达式比较。有没有更好的方法?

64jmpszr

64jmpszr1#

来自net.LookupMX()的错误通常(总是?)是net.DNSError。如果将其转换为net.DNSError,则可以访问错误的IsTimeoutIsTemporaryIsNotFound属性,这些属性可以给予您轻松测试有关错误的信息。

var resolver net.Resolver
for _, preferGo := range []bool{true, false} {
    for _, strictErrors := range []bool{true, false} {
        resolver.PreferGo = preferGo
        resolver.StrictErrors = strictErrors
        fmt.Printf("PreferGo: %v\tStrictErrors: %v\t", preferGo, strictErrors)

        result, err := resolver.LookupMX(context.Background(), "chat.google.com")
        fmt.Printf("Result: %v\tError: %v\n", result, err)

        dnsErr, isDNSErr := err.(*net.DNSError)
        fmt.Printf("IsDNSError: %v", isDNSErr)
        if isDNSErr {
            fmt.Printf(
                "\tIsTimeout: %v\tIsTemporary: %v\tIsNotFound: %v",
                dnsErr.IsTimeout,
                dnsErr.IsTemporary,
                dnsErr.IsNotFound,
            )
        }

        fmt.Println()
        fmt.Println()
    }
}
PreferGo: true  StrictErrors: true  Result: []  Error: lookup chat.google.com on 10.64.15.252:53: no such host
IsDNSError: true    IsTimeout: false    IsTemporary: false  IsNotFound: true

PreferGo: true  StrictErrors: false Result: []  Error: lookup chat.google.com on 10.64.15.252:53: no such host
IsDNSError: true    IsTimeout: false    IsTemporary: false  IsNotFound: true

PreferGo: false StrictErrors: true  Result: []  Error: lookup chat.google.com: dnsquery: No records found for given DNS query.
IsDNSError: true    IsTimeout: false    IsTemporary: false  IsNotFound: false

PreferGo: false StrictErrors: false Result: []  Error: lookup chat.google.com: dnsquery: No records found for given DNS query.
IsDNSError: true    IsTimeout: false    IsTemporary: false  IsNotFound: false

就我个人而言,我打算使用内置的Go解析器(resolver.PreferGo = true)来实现跨平台的一致性,并进行测试

  • err.(*net.DNSError).IsTimeout == false
  • err.(*net.DNSError).IsTemporary == false
  • err.(*net.DNSError).IsNotFound == true

希望这将缩小可能的错误列表,并在识别表示空结果的错误方面做得很好。

相关问题