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