summaryrefslogtreecommitdiff
path: root/src/pkg/net/lookup_unix.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/lookup_unix.go')
-rw-r--r--src/pkg/net/lookup_unix.go87
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