diff options
Diffstat (limited to 'src/pkg/net/lookup_unix.go')
-rw-r--r-- | src/pkg/net/lookup_unix.go | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/src/pkg/net/lookup_unix.go b/src/pkg/net/lookup_unix.go index 7368b751e..d500a1240 100644 --- a/src/pkg/net/lookup_unix.go +++ b/src/pkg/net/lookup_unix.go @@ -2,17 +2,57 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin freebsd linux openbsd +// +build darwin freebsd linux netbsd openbsd package net import ( - "os" + "errors" + "sync" ) -// LookupHost looks up the given host using the local resolver. -// It returns an array of that host's addresses. -func LookupHost(host string) (addrs []string, err os.Error) { +var ( + protocols map[string]int + onceReadProtocols sync.Once +) + +// readProtocols loads contents of /etc/protocols into protocols map +// for quick access. +func readProtocols() { + protocols = make(map[string]int) + if file, err := open("/etc/protocols"); err == nil { + for line, ok := file.readLine(); ok; line, ok = file.readLine() { + // tcp 6 TCP # transmission control protocol + if i := byteIndex(line, '#'); i >= 0 { + line = line[0:i] + } + f := getFields(line) + if len(f) < 2 { + continue + } + if proto, _, ok := dtoi(f[1], 0); ok { + protocols[f[0]] = proto + for _, alias := range f[2:] { + protocols[alias] = proto + } + } + } + file.close() + } +} + +// lookupProtocol looks up IP protocol name in /etc/protocols and +// returns correspondent protocol number. +func lookupProtocol(name string) (proto int, err error) { + onceReadProtocols.Do(readProtocols) + proto, found := protocols[name] + if !found { + return 0, errors.New("unknown IP protocol specified: " + name) + } + return +} + +func lookupHost(host string) (addrs []string, err error) { addrs, err, ok := cgoLookupHost(host) if !ok { addrs, err = goLookupHost(host) @@ -20,9 +60,7 @@ func LookupHost(host string) (addrs []string, err os.Error) { return } -// LookupIP looks up host using the local resolver. -// It returns an array of that host's IPv4 and IPv6 addresses. -func LookupIP(host string) (addrs []IP, err os.Error) { +func lookupIP(host string) (addrs []IP, err error) { addrs, err, ok := cgoLookupIP(host) if !ok { addrs, err = goLookupIP(host) @@ -30,8 +68,7 @@ func LookupIP(host string) (addrs []IP, err os.Error) { return } -// LookupPort looks up the port for the given network and service. -func LookupPort(network, service string) (port int, err os.Error) { +func lookupPort(network, service string) (port int, err error) { port, err, ok := cgoLookupPort(network, service) if !ok { port, err = goLookupPort(network, service) @@ -39,11 +76,7 @@ func LookupPort(network, service string) (port int, err os.Error) { return } -// LookupCNAME returns the canonical DNS host for the given name. -// Callers that do not care about the canonical name can call -// LookupHost or LookupIP directly; both take care of resolving -// the canonical name as part of the lookup. -func LookupCNAME(name string) (cname string, err os.Error) { +func lookupCNAME(name string) (cname string, err error) { cname, err, ok := cgoLookupCNAME(name) if !ok { cname, err = goLookupCNAME(name) @@ -51,13 +84,13 @@ func LookupCNAME(name string) (cname string, err os.Error) { return } -// LookupSRV tries to resolve an SRV query of the given service, -// protocol, and domain name, as specified in RFC 2782. In most cases -// the proto argument can be the same as the corresponding -// Addr.Network(). The returned records are sorted by priority -// and randomized by weight within a priority. -func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os.Error) { - target := "_" + service + "._" + proto + "." + name +func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { + var target string + if service == "" && proto == "" { + target = name + } else { + target = "_" + service + "._" + proto + "." + name + } var records []dnsRR cname, records, err = lookup(target, dnsTypeSRV) if err != nil { @@ -72,8 +105,7 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os. return } -// LookupMX returns the DNS MX records for the given domain name sorted by preference. -func LookupMX(name string) (mx []*MX, err os.Error) { +func lookupMX(name string) (mx []*MX, err error) { _, records, err := lookup(name, dnsTypeMX) if err != nil { return @@ -87,8 +119,7 @@ func LookupMX(name string) (mx []*MX, err os.Error) { return } -// LookupTXT returns the DNS TXT records for the given domain name. -func LookupTXT(name string) (txt []string, err os.Error) { +func lookupTXT(name string) (txt []string, err error) { _, records, err := lookup(name, dnsTypeTXT) if err != nil { return @@ -100,9 +131,7 @@ func LookupTXT(name string) (txt []string, err os.Error) { return } -// LookupAddr performs a reverse lookup for the given address, returning a list -// of names mapping to that address. -func LookupAddr(addr string) (name []string, err os.Error) { +func lookupAddr(addr string) (name []string, err error) { name = lookupStaticAddr(addr) if len(name) > 0 { return |