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  }