1
0
mirror of https://github.com/golang/go synced 2024-11-18 18:04:46 -07:00

net: fix LookupSRV

R=rsc, chris
CC=golang-dev
https://golang.org/cl/2420041
This commit is contained in:
Chris Jones 2010-11-04 10:30:39 -04:00 committed by Russ Cox
parent 8ce3362f4e
commit 25b1e83262
3 changed files with 105 additions and 2 deletions

View File

@ -196,12 +196,16 @@ func isDomainName(s string) bool {
if len(s) == 0 {
return false
}
if len(s) > 255 {
return false
}
if s[len(s)-1] != '.' { // simplify checking loop: make name end in dot
s += "."
}
last := byte('.')
ok := false // ok once we've seen a letter
partlen := 0
for i := 0; i < len(s); i++ {
c := s[i]
switch {
@ -209,18 +213,25 @@ func isDomainName(s string) bool {
return false
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_':
ok = true
partlen++
case '0' <= c && c <= '9':
// fine
partlen++
case c == '-':
// byte before dash cannot be dot
if last == '.' {
return false
}
partlen++
case c == '.':
// byte before dot cannot be dot, dash
if last == '.' || last == '-' {
return false
}
if partlen > 63 || partlen == 0 {
return false
}
partlen = 0
}
last = c
}
@ -315,9 +326,14 @@ type SRV struct {
Weight uint16
}
func LookupSRV(name string) (cname string, addrs []*SRV, 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().
func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os.Error) {
target := "_" + service + "._" + proto + "." + name
var records []dnsRR
cname, records, err = lookup(name, dnsTypeSRV)
cname, records, err = lookup(target, dnsTypeSRV)
if err != nil {
return
}

View File

@ -0,0 +1,65 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package net
import (
"testing"
)
type testCase struct {
name string
result bool
}
var tests = []testCase{
// RFC2181, section 11.
testCase{"_xmpp-server._tcp.google.com", true},
testCase{"_xmpp-server._tcp.google.com", true},
testCase{"foo.com", true},
testCase{"1foo.com", true},
testCase{"26.0.0.73.com", true},
testCase{"fo-o.com", true},
testCase{"fo1o.com", true},
testCase{"foo1.com", true},
testCase{"a.b..com", false},
}
func getTestCases(ch chan<- *testCase) {
defer close(ch)
var char59 = ""
var char63 = ""
var char64 = ""
for i := 0; i < 59; i++ {
char59 += "a"
}
char63 = char59 + "aaaa"
char64 = char63 + "a"
for _, tc := range tests {
ch <- &tc
}
ch <- &testCase{char63 + ".com", true}
ch <- &testCase{char64 + ".com", false}
// 255 char name is fine:
ch <- &testCase{char59 + "." + char63 + "." + char63 + "." +
char63 + ".com",
true}
// 256 char name is bad:
ch <- &testCase{char59 + "a." + char63 + "." + char63 + "." +
char63 + ".com",
false}
}
func TestDNSNames(t *testing.T) {
ch := make(chan *testCase)
go getTestCases(ch)
for tc := range ch {
if isDomainName(tc.name) != tc.result {
t.Errorf("isDomainName(%v) failed: Should be %v",
tc.name, tc.result)
}
}
}

22
src/pkg/net/srv_test.go Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// TODO It would be nice to use a mock DNS server, to eliminate
// external dependencies.
package net
import (
"testing"
)
func TestGoogleSRV(t *testing.T) {
_, addrs, err := LookupSRV("xmpp-server", "tcp", "google.com")
if err != nil {
t.Errorf("failed: %s", err)
}
if len(addrs) == 0 {
t.Errorf("no results")
}
}