github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/net/lookup.go (about) 1 // Copyright 2012 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 package net 6 7 import "time" 8 9 // protocols contains minimal mappings between internet protocol 10 // names and numbers for platforms that don't have a complete list of 11 // protocol numbers. 12 // 13 // See http://www.iana.org/assignments/protocol-numbers 14 var protocols = map[string]int{ 15 "icmp": 1, "ICMP": 1, 16 "igmp": 2, "IGMP": 2, 17 "tcp": 6, "TCP": 6, 18 "udp": 17, "UDP": 17, 19 "ipv6-icmp": 58, "IPV6-ICMP": 58, "IPv6-ICMP": 58, 20 } 21 22 // LookupHost looks up the given host using the local resolver. 23 // It returns an array of that host's addresses. 24 func LookupHost(host string) (addrs []string, err error) { 25 return lookupHost(host) 26 } 27 28 // LookupIP looks up host using the local resolver. 29 // It returns an array of that host's IPv4 and IPv6 addresses. 30 func LookupIP(host string) (addrs []IP, err error) { 31 return lookupIPMerge(host) 32 } 33 34 var lookupGroup singleflight 35 36 // lookupIPMerge wraps lookupIP, but makes sure that for any given 37 // host, only one lookup is in-flight at a time. The returned memory 38 // is always owned by the caller. 39 func lookupIPMerge(host string) (addrs []IP, err error) { 40 addrsi, err, shared := lookupGroup.Do(host, func() (interface{}, error) { 41 return lookupIP(host) 42 }) 43 if err != nil { 44 return nil, err 45 } 46 addrs = addrsi.([]IP) 47 if shared { 48 clone := make([]IP, len(addrs)) 49 copy(clone, addrs) 50 addrs = clone 51 } 52 return addrs, nil 53 } 54 55 func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) { 56 if deadline.IsZero() { 57 return lookupIPMerge(host) 58 } 59 60 // TODO(bradfitz): consider pushing the deadline down into the 61 // name resolution functions. But that involves fixing it for 62 // the native Go resolver, cgo, Windows, etc. 63 // 64 // In the meantime, just use a goroutine. Most users affected 65 // by http://golang.org/issue/2631 are due to TCP connections 66 // to unresponsive hosts, not DNS. 67 timeout := deadline.Sub(time.Now()) 68 if timeout <= 0 { 69 err = errTimeout 70 return 71 } 72 t := time.NewTimer(timeout) 73 defer t.Stop() 74 type res struct { 75 addrs []IP 76 err error 77 } 78 resc := make(chan res, 1) 79 go func() { 80 a, err := lookupIPMerge(host) 81 resc <- res{a, err} 82 }() 83 select { 84 case <-t.C: 85 err = errTimeout 86 case r := <-resc: 87 addrs, err = r.addrs, r.err 88 } 89 return 90 } 91 92 // LookupPort looks up the port for the given network and service. 93 func LookupPort(network, service string) (port int, err error) { 94 return lookupPort(network, service) 95 } 96 97 // LookupCNAME returns the canonical DNS host for the given name. 98 // Callers that do not care about the canonical name can call 99 // LookupHost or LookupIP directly; both take care of resolving 100 // the canonical name as part of the lookup. 101 func LookupCNAME(name string) (cname string, err error) { 102 return lookupCNAME(name) 103 } 104 105 // LookupSRV tries to resolve an SRV query of the given service, 106 // protocol, and domain name. The proto is "tcp" or "udp". 107 // The returned records are sorted by priority and randomized 108 // by weight within a priority. 109 // 110 // LookupSRV constructs the DNS name to look up following RFC 2782. 111 // That is, it looks up _service._proto.name. To accommodate services 112 // publishing SRV records under non-standard names, if both service 113 // and proto are empty strings, LookupSRV looks up name directly. 114 func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { 115 return lookupSRV(service, proto, name) 116 } 117 118 // LookupMX returns the DNS MX records for the given domain name sorted by preference. 119 func LookupMX(name string) (mx []*MX, err error) { 120 return lookupMX(name) 121 } 122 123 // LookupNS returns the DNS NS records for the given domain name. 124 func LookupNS(name string) (ns []*NS, err error) { 125 return lookupNS(name) 126 } 127 128 // LookupTXT returns the DNS TXT records for the given domain name. 129 func LookupTXT(name string) (txt []string, err error) { 130 return lookupTXT(name) 131 } 132 133 // LookupAddr performs a reverse lookup for the given address, returning a list 134 // of names mapping to that address. 135 func LookupAddr(addr string) (name []string, err error) { 136 return lookupAddr(addr) 137 }