github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/net/lookup_unix.go (about) 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 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package net 8 9 import "sync" 10 11 var onceReadProtocols sync.Once 12 13 // readProtocols loads contents of /etc/protocols into protocols map 14 // for quick access. 15 func readProtocols() { 16 if file, err := open("/etc/protocols"); err == nil { 17 for line, ok := file.readLine(); ok; line, ok = file.readLine() { 18 // tcp 6 TCP # transmission control protocol 19 if i := byteIndex(line, '#'); i >= 0 { 20 line = line[0:i] 21 } 22 f := getFields(line) 23 if len(f) < 2 { 24 continue 25 } 26 if proto, _, ok := dtoi(f[1], 0); ok { 27 if _, ok := protocols[f[0]]; !ok { 28 protocols[f[0]] = proto 29 } 30 for _, alias := range f[2:] { 31 if _, ok := protocols[alias]; !ok { 32 protocols[alias] = proto 33 } 34 } 35 } 36 } 37 file.close() 38 } 39 } 40 41 // lookupProtocol looks up IP protocol name in /etc/protocols and 42 // returns correspondent protocol number. 43 func lookupProtocol(name string) (int, error) { 44 onceReadProtocols.Do(readProtocols) 45 proto, found := protocols[name] 46 if !found { 47 return 0, &AddrError{Err: "unknown IP protocol specified", Addr: name} 48 } 49 return proto, nil 50 } 51 52 func lookupHost(host string) (addrs []string, err error) { 53 order := systemConf().hostLookupOrder(host) 54 if order == hostLookupCgo { 55 if addrs, err, ok := cgoLookupHost(host); ok { 56 return addrs, err 57 } 58 // cgo not available (or netgo); fall back to Go's DNS resolver 59 order = hostLookupFilesDNS 60 } 61 return goLookupHostOrder(host, order) 62 } 63 64 func lookupIP(host string) (addrs []IPAddr, err error) { 65 order := systemConf().hostLookupOrder(host) 66 if order == hostLookupCgo { 67 if addrs, err, ok := cgoLookupIP(host); ok { 68 return addrs, err 69 } 70 // cgo not available (or netgo); fall back to Go's DNS resolver 71 order = hostLookupFilesDNS 72 } 73 return goLookupIPOrder(host, order) 74 } 75 76 func lookupPort(network, service string) (int, error) { 77 if systemConf().canUseCgo() { 78 if port, err, ok := cgoLookupPort(network, service); ok { 79 return port, err 80 } 81 } 82 return goLookupPort(network, service) 83 } 84 85 func lookupCNAME(name string) (string, error) { 86 if systemConf().canUseCgo() { 87 if cname, err, ok := cgoLookupCNAME(name); ok { 88 return cname, err 89 } 90 } 91 return goLookupCNAME(name) 92 } 93 94 func lookupSRV(service, proto, name string) (string, []*SRV, error) { 95 var target string 96 if service == "" && proto == "" { 97 target = name 98 } else { 99 target = "_" + service + "._" + proto + "." + name 100 } 101 cname, rrs, err := lookup(target, dnsTypeSRV) 102 if err != nil { 103 return "", nil, err 104 } 105 srvs := make([]*SRV, len(rrs)) 106 for i, rr := range rrs { 107 rr := rr.(*dnsRR_SRV) 108 srvs[i] = &SRV{Target: rr.Target, Port: rr.Port, Priority: rr.Priority, Weight: rr.Weight} 109 } 110 byPriorityWeight(srvs).sort() 111 return cname, srvs, nil 112 } 113 114 func lookupMX(name string) ([]*MX, error) { 115 _, rrs, err := lookup(name, dnsTypeMX) 116 if err != nil { 117 return nil, err 118 } 119 mxs := make([]*MX, len(rrs)) 120 for i, rr := range rrs { 121 rr := rr.(*dnsRR_MX) 122 mxs[i] = &MX{Host: rr.Mx, Pref: rr.Pref} 123 } 124 byPref(mxs).sort() 125 return mxs, nil 126 } 127 128 func lookupNS(name string) ([]*NS, error) { 129 _, rrs, err := lookup(name, dnsTypeNS) 130 if err != nil { 131 return nil, err 132 } 133 nss := make([]*NS, len(rrs)) 134 for i, rr := range rrs { 135 nss[i] = &NS{Host: rr.(*dnsRR_NS).Ns} 136 } 137 return nss, nil 138 } 139 140 func lookupTXT(name string) ([]string, error) { 141 _, rrs, err := lookup(name, dnsTypeTXT) 142 if err != nil { 143 return nil, err 144 } 145 txts := make([]string, len(rrs)) 146 for i, rr := range rrs { 147 txts[i] = rr.(*dnsRR_TXT).Txt 148 } 149 return txts, nil 150 } 151 152 func lookupAddr(addr string) ([]string, error) { 153 if systemConf().canUseCgo() { 154 if ptrs, err, ok := cgoLookupPTR(addr); ok { 155 return ptrs, err 156 } 157 } 158 return goLookupPTR(addr) 159 }