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