if canUseCgo && dnsConf.err != nil && !errors.Is(dnsConf.err, fs.ErrNotExist) && !errors.Is(dnsConf.err, fs.ErrPermission) { // We can't read the resolv.conf file, so use cgo if we can. return hostLookupCgo, dnsConf }
内置go解析器,分了四种
const ( // hostLookupCgo means defer to cgo. hostLookupCgo hostLookupOrder = iota hostLookupFilesDNS // files first hostLookupDNSFiles // dns first hostLookupFiles // only files hostLookupDNS // only DNS)var lookupOrderName = map[hostLookupOrder]string{ hostLookupCgo: "cgo", hostLookupFilesDNS: "files,dns", hostLookupDNSFiles: "dns,files", hostLookupFiles: "files", hostLookupDNS: "dns",}
通过 nsswitch.conf 可以指定解析顺序,比如ubuntu:
# /etc/nsswitch.conf## Example configuration of GNU Name Service Switch functionality.# If you have the `glibc-doc-reference' and `info' packages installed, try:# `info libc "Name Service Switch"' for information about this file.passwd: files systemdgroup: files systemdshadow: files systemdgshadow: files systemdhosts: files dnsnetworks: filesprotocols: db filesservices: db filesethers: db filesrpc: db filesnetgroup: nis
nss := getSystemNSS() srcs := nss.sources["hosts"] // If /etc/nsswitch.conf doesn't exist or doesn't specify any // sources for "hosts", assume Go's DNS will work fine. if errors.Is(nss.err, fs.ErrNotExist) || (nss.err == nil && len(srcs) == 0) { if canUseCgo && c.goos == "solaris" { // illumos defaults to // "nis [NOTFOUND=return] files", // which the go resolver doesn't support. return hostLookupCgo, dnsConf } return hostLookupFilesDNS, dnsConf } if nss.err != nil { // We failed to parse or open nsswitch.conf, so // we have nothing to base an order on. return fallbackOrder, dnsConf }
case s == "single-request" || s == "single-request-reopen": // Linux option: // http://man7.org/linux/man-pages/man5/resolv.conf.5.html // "By default, glibc performs IPv4 and IPv6 lookups in parallel [...] // This option disables the behavior and makes glibc // perform the IPv6 and IPv4 requests sequentially." conf.singleRequest = true
在 dig 命令的输出中,ADDITIONAL 部分表示附加的资源记录(Additional Resource Records)。这些记录通常包含额外的信息,例如与查询相关的其他 DNS 服务器的地址。这些附加记录可以帮助解析器更快地找到所需的信息。
例如,当查询某个域名时,ADDITIONAL 部分可能包含该域名的名称服务器(NS)记录的 IP 地址,以便解析器可以直接联系这些服务器进行进一步查询。
dig-addtional
// libresolv continues to the next server when it receives // an invalid referral response. See golang.org/issue/15434. if rcode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone && !hasAdd { return errLameReferral } // extractExtendedRCode extracts the extended RCode from the OPT resource (EDNS(0))// If an OPT record is not found, the RCode from the hdr is returned.// Another return value indicates whether an additional resource was found.func extractExtendedRCode(p dnsmessage.Parser, hdr dnsmessage.Header) (dnsmessage.RCode, bool) { p.SkipAllAnswers() p.SkipAllAuthorities() hasAdd := false for { ahdr, err := p.AdditionalHeader() if err != nil { return hdr.RCode, hasAdd } hasAdd = true if ahdr.Type == dnsmessage.TypeOPT { return ahdr.ExtendedRCode(hdr.RCode), hasAdd } if err := p.SkipAdditional(); err != nil { return hdr.RCode, hasAdd } }}