1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
14 var onceReadProtocols sync
.Once
16 // readProtocols loads contents of /etc/protocols into protocols map
18 func readProtocols() {
19 if file
, err
:= open("/etc/protocols"); err
== nil {
20 for line
, ok
:= file
.readLine(); ok
; line
, ok
= file
.readLine() {
21 // tcp 6 TCP # transmission control protocol
22 if i
:= byteIndex(line
, '#'); i
>= 0 {
29 if proto
, _
, ok
:= dtoi(f
[1]); ok
{
30 if _
, ok
:= protocols
[f
[0]]; !ok
{
31 protocols
[f
[0]] = proto
33 for _
, alias
:= range f
[2:] {
34 if _
, ok
:= protocols
[alias
]; !ok
{
35 protocols
[alias
] = proto
44 // lookupProtocol looks up IP protocol name in /etc/protocols and
45 // returns correspondent protocol number.
46 func lookupProtocol(_ context
.Context
, name
string) (int, error
) {
47 onceReadProtocols
.Do(readProtocols
)
48 return lookupProtocolMap(name
)
51 func (r
*Resolver
) lookupHost(ctx context
.Context
, host
string) (addrs
[]string, err error
) {
52 order
:= systemConf().hostLookupOrder(host
)
53 if !r
.PreferGo
&& order
== hostLookupCgo
{
54 if addrs
, err
, ok
:= cgoLookupHost(ctx
, host
); ok
{
57 // cgo not available (or netgo); fall back to Go's DNS resolver
58 order
= hostLookupFilesDNS
60 return goLookupHostOrder(ctx
, host
, order
)
63 func (r
*Resolver
) lookupIP(ctx context
.Context
, host
string) (addrs
[]IPAddr
, err error
) {
65 return goLookupIP(ctx
, host
)
67 order
:= systemConf().hostLookupOrder(host
)
68 if order
== hostLookupCgo
{
69 if addrs
, err
, ok
:= cgoLookupIP(ctx
, host
); ok
{
72 // cgo not available (or netgo); fall back to Go's DNS resolver
73 order
= hostLookupFilesDNS
75 addrs
, _
, err
= goLookupIPCNAMEOrder(ctx
, host
, order
)
79 func (r
*Resolver
) lookupPort(ctx context
.Context
, network
, service
string) (int, error
) {
80 if !r
.PreferGo
&& systemConf().canUseCgo() {
81 if port
, err
, ok
:= cgoLookupPort(ctx
, network
, service
); ok
{
83 // Issue 18213: if cgo fails, first check to see whether we
84 // have the answer baked-in to the net package.
85 if port
, err
:= goLookupPort(network
, service
); err
== nil {
92 return goLookupPort(network
, service
)
95 func (r
*Resolver
) lookupCNAME(ctx context
.Context
, name
string) (string, error
) {
96 if !r
.PreferGo
&& systemConf().canUseCgo() {
97 if cname
, err
, ok
:= cgoLookupCNAME(ctx
, name
); ok
{
101 return goLookupCNAME(ctx
, name
)
104 func (*Resolver
) lookupSRV(ctx context
.Context
, service
, proto
, name
string) (string, []*SRV
, error
) {
106 if service
== "" && proto
== "" {
109 target
= "_" + service
+ "._" + proto
+ "." + name
111 cname
, rrs
, err
:= lookup(ctx
, target
, dnsTypeSRV
)
115 srvs
:= make([]*SRV
, len(rrs
))
116 for i
, rr
:= range rrs
{
117 rr
:= rr
.(*dnsRR_SRV
)
118 srvs
[i
] = &SRV
{Target
: rr
.Target
, Port
: rr
.Port
, Priority
: rr
.Priority
, Weight
: rr
.Weight
}
120 byPriorityWeight(srvs
).sort()
121 return cname
, srvs
, nil
124 func (*Resolver
) lookupMX(ctx context
.Context
, name
string) ([]*MX
, error
) {
125 _
, rrs
, err
:= lookup(ctx
, name
, dnsTypeMX
)
129 mxs
:= make([]*MX
, len(rrs
))
130 for i
, rr
:= range rrs
{
132 mxs
[i
] = &MX
{Host
: rr
.Mx
, Pref
: rr
.Pref
}
138 func (*Resolver
) lookupNS(ctx context
.Context
, name
string) ([]*NS
, error
) {
139 _
, rrs
, err
:= lookup(ctx
, name
, dnsTypeNS
)
143 nss
:= make([]*NS
, len(rrs
))
144 for i
, rr
:= range rrs
{
145 nss
[i
] = &NS
{Host
: rr
.(*dnsRR_NS
).Ns
}
150 func (r
*Resolver
) lookupTXT(ctx context
.Context
, name
string) ([]string, error
) {
151 _
, rrs
, err
:= lookup(ctx
, name
, dnsTypeTXT
)
155 txts
:= make([]string, len(rrs
))
156 for i
, rr
:= range rrs
{
157 txts
[i
] = rr
.(*dnsRR_TXT
).Txt
162 func (r
*Resolver
) lookupAddr(ctx context
.Context
, addr
string) ([]string, error
) {
163 if !r
.PreferGo
&& systemConf().canUseCgo() {
164 if ptrs
, err
, ok
:= cgoLookupPTR(ctx
, addr
); ok
{
168 return goLookupPTR(ctx
, addr
)