diff options
Diffstat (limited to 'libgo/go/net/lookup_unix.go')
-rw-r--r-- | libgo/go/net/lookup_unix.go | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/libgo/go/net/lookup_unix.go b/libgo/go/net/lookup_unix.go index 8f5e66212b3..6e79295a948 100644 --- a/libgo/go/net/lookup_unix.go +++ b/libgo/go/net/lookup_unix.go @@ -2,12 +2,56 @@ // 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 + package net import ( "os" + "sync" +) + +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 os.Error) { + onceReadProtocols.Do(readProtocols) + proto, found := protocols[name] + if !found { + return 0, os.NewError("unknown IP protocol specified: " + name) + } + return +} + // 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) { @@ -50,12 +94,21 @@ func LookupCNAME(name string) (cname string, err os.Error) { } // 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. +// protocol, and domain name. The proto is "tcp" or "udp". +// The returned records are sorted by priority and randomized +// by weight within a priority. +// +// LookupSRV constructs the DNS name to look up following RFC 2782. +// That is, it looks up _service._proto.name. To accommodate services +// publishing SRV records under non-standard names, if both service +// and proto are empty strings, LookupSRV looks up name directly. func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os.Error) { - target := "_" + service + "._" + proto + "." + name + 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,19 +125,32 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os. // 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) + _, 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 } +// LookupTXT returns the DNS TXT records for the given domain name. +func LookupTXT(name string) (txt []string, err os.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 +} + // 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) { |