diff options
Diffstat (limited to 'discover.go')
-rw-r--r-- | discover.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/discover.go b/discover.go new file mode 100644 index 0000000..08d4aa1 --- /dev/null +++ b/discover.go @@ -0,0 +1,66 @@ +package koushin + +import ( + "fmt" + "net" + "net/url" + "strings" +) + +func discoverTCP(service, name string) (string, error) { + _, addrs, err := net.LookupSRV(service, "tcp", name) + if dnsErr, ok := err.(*net.DNSError); ok { + if dnsErr.IsTemporary { + return "", err + } + } else if err != nil { + return "", err + } + + if len(addrs) == 0 { + return "", nil + } + addr := addrs[0] + + target := strings.TrimSuffix(addr.Target, ".") + if target == "" { + return "", nil + } + + return fmt.Sprintf("%v:%v", target, addr.Port), nil +} + +// discoverIMAP performs a DNS-based IMAP service discovery, as defined in +// RFC 6186 section 3.2. +func discoverIMAP(domain string) (*url.URL, error) { + imapsHost, err := discoverTCP("imaps", domain) + if err != nil { + return nil, err + } + if imapsHost != "" { + return &url.URL{Scheme: "imaps", Host: imapsHost}, nil + } + + imapHost, err := discoverTCP("imap", domain) + if err != nil { + return nil, err + } + if imapHost != "" { + return &url.URL{Scheme: "imap", Host: imapHost}, nil + } + + return nil, fmt.Errorf("IMAP service discovery not configured for domain %q", domain) +} + +// discoverSMTP performs a DNS-based SMTP submission service discovery, as +// defined in RFC 6186 section 3.1. +func discoverSMTP(domain string) (*url.URL, error) { + host, err := discoverTCP("submission", domain) + if err != nil { + return nil, err + } + if host == "" { + return nil, fmt.Errorf("SMTP service discovery not configured for domain %q", domain) + } + return &url.URL{Scheme: "smtp", Host: host}, nil +} |