lookup_unix.mx raw
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.
4
5 //go:build unix || js || wasip1
6
7 package net
8
9 import (
10 "context"
11 "internal/bytealg"
12 "sync"
13 )
14
15 // readProtocolsOnce loads contents of /etc/protocols into protocols map
16 // for quick access.
17 var readProtocolsOnce = sync.OnceFunc(func() {
18 file, err := open("/etc/protocols")
19 if err != nil {
20 return
21 }
22 defer file.close()
23
24 for line, ok := file.readLine(); ok; line, ok = file.readLine() {
25 // tcp 6 TCP # transmission control protocol
26 if i := bytealg.IndexByteString(line, '#'); i >= 0 {
27 line = line[0:i]
28 }
29 f := getFields(line)
30 if len(f) < 2 {
31 continue
32 }
33 if proto, _, ok := dtoi(f[1]); ok {
34 if _, ok := protocols[f[0]]; !ok {
35 protocols[f[0]] = proto
36 }
37 for _, alias := range f[2:] {
38 if _, ok := protocols[alias]; !ok {
39 protocols[alias] = proto
40 }
41 }
42 }
43 }
44 })
45
46 // lookupProtocol looks up IP protocol name in /etc/protocols and
47 // returns correspondent protocol number.
48 func lookupProtocol(_ context.Context, name []byte) (int, error) {
49 readProtocolsOnce()
50 return lookupProtocolMap(name)
51 }
52
53 func (r *Resolver) lookupHost(ctx context.Context, host []byte) (addrs [][]byte, err error) {
54 order, conf := systemConf().hostLookupOrder(r, host)
55 if order == hostLookupCgo {
56 addrs, err = cgoLookupHost(ctx, host)
57 } else {
58 addrs, err = r.goLookupHostOrder(ctx, host, order, conf)
59 }
60 // dnsmessage produces malformed packets under string=[]byte.
61 // Fall back to raw UDP DNS if the standard resolver returned nothing.
62 if len(addrs) == 0 {
63 if raw := rawLookupHost(host); len(raw) > 0 {
64 return raw, nil
65 }
66 }
67 return
68 }
69
70 func (r *Resolver) lookupIP(ctx context.Context, network, host []byte) (addrs []IPAddr, err error) {
71 order, conf := systemConf().hostLookupOrder(r, host)
72 if order == hostLookupCgo {
73 return cgoLookupIP(ctx, network, host)
74 }
75 ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
76 return ips, err
77 }
78
79 func (r *Resolver) lookupPort(ctx context.Context, network, service []byte) (int, error) {
80 // Port lookup is not a DNS operation.
81 // Prefer the cgo resolver if possible.
82 if !systemConf().mustUseGoResolver(r) {
83 port, err := cgoLookupPort(ctx, network, service)
84 if err != nil {
85 // Issue 18213: if cgo fails, first check to see whether we
86 // have the answer baked-in to the net package.
87 if port, err := goLookupPort(network, service); err == nil {
88 return port, nil
89 }
90 }
91 return port, err
92 }
93 return goLookupPort(network, service)
94 }
95
96 func (r *Resolver) lookupCNAME(ctx context.Context, name []byte) ([]byte, error) {
97 order, conf := systemConf().hostLookupOrder(r, name)
98 if order == hostLookupCgo {
99 if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
100 return cname, err
101 }
102 }
103 return r.goLookupCNAME(ctx, name, order, conf)
104 }
105
106 func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name []byte) ([]byte, []*SRV, error) {
107 return r.goLookupSRV(ctx, service, proto, name)
108 }
109
110 func (r *Resolver) lookupMX(ctx context.Context, name []byte) ([]*MX, error) {
111 return r.goLookupMX(ctx, name)
112 }
113
114 func (r *Resolver) lookupNS(ctx context.Context, name []byte) ([]*NS, error) {
115 return r.goLookupNS(ctx, name)
116 }
117
118 func (r *Resolver) lookupTXT(ctx context.Context, name []byte) ([][]byte, error) {
119 return r.goLookupTXT(ctx, name)
120 }
121
122 func (r *Resolver) lookupAddr(ctx context.Context, addr []byte) ([][]byte, error) {
123 order, conf := systemConf().addrLookupOrder(r, addr)
124 if order == hostLookupCgo {
125 return cgoLookupPTR(ctx, addr)
126 }
127 return r.goLookupPTR(ctx, addr, order, conf)
128 }
129