return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
}
+// ensureEndDot adds '.' at the end of name unless it is already there.
+func ensureEndDot(name string) string {
+ if name == "" {
+ return "."
+ }
+ if name[len(name)-1] == '.' {
+ return name
+ }
+ return name + "."
+}
+
func lookupCNAME(name string) (string, error) {
acquireThread()
defer releaseThread()
// windows returns DNS_INFO_NO_RECORDS if there are no CNAME-s
if errno, ok := e.(syscall.Errno); ok && errno == syscall.DNS_INFO_NO_RECORDS {
// if there are no aliases, the canonical name is the input name
- if name == "" || name[len(name)-1] != '.' {
- return name + ".", nil
- }
- return name, nil
+ return ensureEndDot(name), nil
}
if e != nil {
return "", &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
defer syscall.DnsRecordListFree(r, 1)
resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), r)
- cname := syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(resolved))[:]) + "."
- return cname, nil
+ cname := syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(resolved))[:])
+ return ensureEndDot(cname), nil
}
func lookupSRV(service, proto, name string) (string, []*SRV, error) {
srvs := make([]*SRV, 0, 10)
for _, p := range validRecs(r, syscall.DNS_TYPE_SRV, target) {
v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
- srvs = append(srvs, &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight})
+ srvs = append(srvs, &SRV{ensureEndDot(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:])), v.Port, v.Priority, v.Weight})
}
byPriorityWeight(srvs).sort()
- return name, srvs, nil
+ return ensureEndDot(target), srvs, nil
}
func lookupMX(name string) ([]*MX, error) {
mxs := make([]*MX, 0, 10)
for _, p := range validRecs(r, syscall.DNS_TYPE_MX, name) {
v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
- mxs = append(mxs, &MX{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]) + ".", v.Preference})
+ mxs = append(mxs, &MX{ensureEndDot(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:])), v.Preference})
}
byPref(mxs).sort()
return mxs, nil
nss := make([]*NS, 0, 10)
for _, p := range validRecs(r, syscall.DNS_TYPE_NS, name) {
v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
- nss = append(nss, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."})
+ nss = append(nss, &NS{ensureEndDot(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))})
}
return nss, nil
}
ptrs := make([]string, 0, 10)
for _, p := range validRecs(r, syscall.DNS_TYPE_PTR, arpa) {
v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
- ptrs = append(ptrs, syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))
+ ptrs = append(ptrs, ensureEndDot(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:])))
}
return ptrs, nil
}
func (s byHost) Less(i, j int) bool { return s[i].Host < s[j].Host }
func (s byHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-func fqdn(s string) string {
- if len(s) == 0 || s[len(s)-1] != '.' {
- return s + "."
- }
- return s
-}
-
func nslookup(qtype, name string) (string, error) {
var out bytes.Buffer
var err bytes.Buffer
rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+mail exchanger\s*=\s*([0-9]+)\s*([a-z0-9.\-]+)$`)
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
pref, _, _ := dtoi(ans[2], 0)
- mx = append(mx, &MX{fqdn(ans[3]), uint16(pref)})
+ mx = append(mx, &MX{ensureEndDot(ans[3]), uint16(pref)})
}
// windows nslookup syntax
// gmail.com MX preference = 30, mail exchanger = alt3.gmail-smtp-in.l.google.com
rx = regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+MX preference\s*=\s*([0-9]+)\s*,\s*mail exchanger\s*=\s*([a-z0-9.\-]+)$`)
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
pref, _, _ := dtoi(ans[2], 0)
- mx = append(mx, &MX{fqdn(ans[3]), uint16(pref)})
+ mx = append(mx, &MX{ensureEndDot(ans[3]), uint16(pref)})
}
return
}
// golang.org nameserver = ns1.google.com.
rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+nameserver\s*=\s*([a-z0-9.\-]+)$`)
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
- ns = append(ns, &NS{fqdn(ans[2])})
+ ns = append(ns, &NS{ensureEndDot(ans[2])})
}
return
}
for _, ans := range rx.FindAllStringSubmatch(r, -1) {
last = ans[2]
}
- return fqdn(last), nil
+ return ensureEndDot(last), nil
}
func nslookupTXT(name string) (txt []string, err error) {