1package smtpserver
2
3import (
4 "context"
5 "net"
6
7 "github.com/mjl-/mox/dns"
8)
9
10// checks if domain can accept email.
11// i.e. if it has no null mx record, regular mx records or resolve to an address.
12func checkMXRecords(ctx context.Context, resolver dns.Resolver, d dns.Domain) (bool, error) {
13 // Note: LookupMX can return an error and still return records.
14 mx, _, err := resolver.LookupMX(ctx, d.ASCII+".")
15 if err == nil && len(mx) == 1 && mx[0].Host == "." {
16 // Null MX record, explicit signal that remote does not accept email.
17 return false, nil
18 }
19 // Treat all errors that are not "no mx record" as temporary. E.g. timeout, malformed record, remote server error.
20 if err != nil && !dns.IsNotFound(err) {
21 return false, err
22 }
23 if len(mx) == 0 {
24 mx = []*net.MX{{Host: d.ASCII + "."}}
25 }
26 var lastErr error
27 for _, x := range mx {
28 ips, _, err := resolver.LookupIPAddr(ctx, x.Host)
29 if len(ips) > 0 {
30 return true, nil
31 }
32 if err != nil && !dns.IsNotFound(err) {
33 lastErr = err
34 }
35 }
36 return false, lastErr
37}
38