diff --git a/src/pkg/net/lookup_plan9.go b/src/pkg/net/lookup_plan9.go index ee0c9e879ec..d779f4a5d71 100644 --- a/src/pkg/net/lookup_plan9.go +++ b/src/pkg/net/lookup_plan9.go @@ -157,12 +157,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 + } lines, err := queryDNS(target, "srv") if err != nil { return diff --git a/src/pkg/net/lookup_test.go b/src/pkg/net/lookup_test.go index 41066fe4809..c0fcd260472 100644 --- a/src/pkg/net/lookup_test.go +++ b/src/pkg/net/lookup_test.go @@ -26,6 +26,15 @@ func TestGoogleSRV(t *testing.T) { if len(addrs) == 0 { t.Errorf("no results") } + + // Non-standard back door. + _, addrs, err = LookupSRV("", "", "_xmpp-server._tcp.google.com") + if err != nil { + t.Errorf("back door failed: %s", err) + } + if len(addrs) == 0 { + t.Errorf("back door no results") + } } func TestGmailMX(t *testing.T) { diff --git a/src/pkg/net/lookup_unix.go b/src/pkg/net/lookup_unix.go index 387bb5976c9..6e79295a948 100644 --- a/src/pkg/net/lookup_unix.go +++ b/src/pkg/net/lookup_unix.go @@ -94,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 { diff --git a/src/pkg/net/lookup_windows.go b/src/pkg/net/lookup_windows.go index e138698241c..ea939f85986 100644 --- a/src/pkg/net/lookup_windows.go +++ b/src/pkg/net/lookup_windows.go @@ -91,9 +91,23 @@ 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. 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) { + var target string + if service == "" && proto == "" { + target = name + } else { + target = "_" + service + "._" + proto + "." + name + } var r *syscall.DNSRecord - target := "_" + service + "._" + proto + "." + name e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil) if int(e) != 0 { return "", nil, os.NewSyscallError("LookupSRV", int(e))