diff options
Diffstat (limited to 'src/pkg/net/lookup_unix.go')
| -rw-r--r-- | src/pkg/net/lookup_unix.go | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/src/pkg/net/lookup_unix.go b/src/pkg/net/lookup_unix.go index 8f5e66212..d500a1240 100644 --- a/src/pkg/net/lookup_unix.go +++ b/src/pkg/net/lookup_unix.go @@ -2,15 +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 netbsd openbsd + package net import ( - "os" + "errors" + "sync" +) + +var ( + protocols map[string]int + onceReadProtocols sync.Once ) -// 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) { +// 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) @@ -18,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) @@ -28,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) @@ -37,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) @@ -49,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 { @@ -70,24 +105,33 @@ 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) { - _, rr, err := lookup(name, dnsTypeMX) +func lookupMX(name string) (mx []*MX, err error) { + _, records, err := lookup(name, dnsTypeMX) if err != nil { return } - mx = make([]*MX, len(rr)) - for i := range rr { - r := rr[i].(*dnsRR_MX) + mx = make([]*MX, len(records)) + for i, rr := range records { + r := rr.(*dnsRR_MX) mx[i] = &MX{r.Mx, r.Pref} } byPref(mx).sort() 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 lookupTXT(name string) (txt []string, err error) { + _, records, err := lookup(name, dnsTypeTXT) + if err != nil { + return + } + txt = make([]string, len(records)) + for i, r := range records { + txt[i] = r.(*dnsRR_TXT).Txt + } + return +} + +func lookupAddr(addr string) (name []string, err error) { name = lookupStaticAddr(addr) if len(name) > 0 { return |
