This commit is contained in:
Miek Gieben 2012-02-23 19:37:08 +01:00
parent 69cecf63bd
commit 89c05b4f74
8 changed files with 114 additions and 122 deletions

View File

@ -214,10 +214,10 @@ func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
l++
longer = 1
}
// Preloop check for root label
if s == "." {
return 0, 1, true
}
// Preloop check for root label
if s == "." {
return 0, 1, true
}
last := byte('.')
ok := false // ok once we've seen a letter or digit
@ -264,37 +264,37 @@ func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
// IsSubDomain checks if child is indeed a child of the parent.
func IsSubDomain(parent, child string) bool {
// If the number of labels both domain name have
// in common equals the number of labels of parent,
// child is a subdomain of parent.
plabs := SplitLabels(parent)
clabs := SplitLabels(child)
if len(clabs) < len(plabs) {
// child is smaller than parent, reversed arguments?
return false
}
// Copied from CompareLabels to prevent another SplitLabels
n := 0
p := len(plabs) - 1
c := len(clabs) - 1
for {
if p < 0 || c < 0 {
break
}
if plabs[p] == clabs[c] {
n++
} else {
break
}
p--
c--
}
return n == len(plabs)
// If the number of labels both domain name have
// in common equals the number of labels of parent,
// child is a subdomain of parent.
plabs := SplitLabels(parent)
clabs := SplitLabels(child)
if len(clabs) < len(plabs) {
// child is smaller than parent, reversed arguments?
return false
}
// Copied from CompareLabels to prevent another SplitLabels
n := 0
p := len(plabs) - 1
c := len(clabs) - 1
for {
if p < 0 || c < 0 {
break
}
if plabs[p] == clabs[c] {
n++
} else {
break
}
p--
c--
}
return n == len(plabs)
}
// IsFqdn checks if a domain name is fully qualified.
func IsFqdn(s string) bool {
l := len(s)
l := len(s)
if l == 0 {
return false // ?
}

14
dns.go
View File

@ -174,13 +174,13 @@ func (h *RR_Header) Len() int {
// Create a copy of the header
func (h *RR_Header) Copy() *RR_Header {
h1 := new(RR_Header)
h1.Name = h.Name
h1.Rrtype = h.Rrtype
h1.Class = h.Class
h1.Ttl = h.Ttl
h1.Rdlength = h.Rdlength
return h1
h1 := new(RR_Header)
h1.Name = h.Name
h1.Rrtype = h.Rrtype
h1.Class = h.Class
h1.Ttl = h.Ttl
h1.Rdlength = h.Rdlength
return h1
}
func zoneMatch(pattern, zone string) (ok bool) {

View File

@ -80,24 +80,24 @@ func TestEDNS_RR(t *testing.T) {
}
func TestBailiwick(t *testing.T) {
yes := map[string]string{
"miek.nl": "ns.miek.nl",
".": "miek.nl",
}
for parent, child := range yes {
if !IsSubDomain(parent, child) {
t.Logf("%s should be child of %s\n", child, parent)
t.Fail()
}
}
no := map[string]string{
"www.miek.nl": "ns.miek.nl",
"miek.nl": ".",
}
for parent, child := range no {
if IsSubDomain(parent, child) {
t.Logf("%s should not be child of %s\n", child, parent)
t.Fail()
}
}
yes := map[string]string{
"miek.nl": "ns.miek.nl",
".": "miek.nl",
}
for parent, child := range yes {
if !IsSubDomain(parent, child) {
t.Logf("%s should be child of %s\n", child, parent)
t.Fail()
}
}
no := map[string]string{
"www.miek.nl": "ns.miek.nl",
"miek.nl": ".",
}
for parent, child := range no {
if IsSubDomain(parent, child) {
t.Logf("%s should not be child of %s\n", child, parent)
t.Fail()
}
}
}

View File

@ -498,8 +498,8 @@ func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func rawSignatureData(rrset []RR, s *RR_RRSIG) (buf []byte) {
wires := make(wireSlice, len(rrset))
for i, r := range rrset {
r1 := r
h1 := r1.Header()
r1 := r
h1 := r1.Header()
labels := SplitLabels(h1.Name)
// 6.2. Canonical RR Form. (4) - wildcards
if len(labels) > int(s.Labels) {
@ -512,7 +512,7 @@ func rawSignatureData(rrset []RR, s *RR_RRSIG) (buf []byte) {
// NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
// HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
// SRV, DNAME, A6
switch x := r1.(type) {
switch x := r1.(type) {
case *RR_NS:
x.Ns = strings.ToLower(x.Ns)
case *RR_CNAME:

View File

@ -91,7 +91,7 @@ func readPrivateKeyECDSA(m map[string]string) (PrivateKey, error) {
// parseKey reads a private key from r. It returns a map[string]string,
// with the key-value pairs, or an error when the file is not correct.
func parseKey(r io.Reader, file string) (map[string]string, error) {
s := scanInit(r)
s := scanInit(r)
m := make(map[string]string)
c := make(chan lex)
k := ""
@ -160,7 +160,7 @@ func klexer(s *scan, c chan lex) {
}
str += string(x)
}
x, err = s.tokenText()
x, err = s.tokenText()
}
if len(str) > 0 {
// Send remainder

View File

@ -6,9 +6,9 @@ package dns
// www.miek.nl. returns []string{"www", "miek", "nl"}
// The root label (.) returns nil.
func SplitLabels(s string) []string {
if (s == ".") {
return nil
}
if s == "." {
return nil
}
k := 0
labels := make([]string, 0)

View File

@ -132,8 +132,8 @@ z3.miek.nl. IN NSEC miek.nl. TXT RRSIG NSEC`
func TestDomainName(t *testing.T) {
tests := []string{"r\\.gieben.miek.nl.", "www\\.www.miek.nl.",
"www.*.miek.nl.", "www.*.miek.nl.",
}
"www.*.miek.nl.", "www.*.miek.nl.",
}
dbuff := make([]byte, 40)
for _, ts := range tests {
@ -157,21 +157,19 @@ func TestDomainName(t *testing.T) {
func TestParseDirectiveMisc(t *testing.T) {
tests := map[string]string{
"$ORIGIN miek.nl.\na IN NS b": "a.miek.nl.\t3600\tIN\tNS\tb.miek.nl.",
"$TTL 2H\nmiek.nl. IN NS b.": "miek.nl.\t7200\tIN\tNS\tb.",
"miek.nl. 1D IN NS b.": "miek.nl.\t86400\tIN\tNS\tb.",
`name. IN SOA a6.nstld.com. hostmaster.nic.name. (
"$ORIGIN miek.nl.\na IN NS b": "a.miek.nl.\t3600\tIN\tNS\tb.miek.nl.",
"$TTL 2H\nmiek.nl. IN NS b.": "miek.nl.\t7200\tIN\tNS\tb.",
"miek.nl. 1D IN NS b.": "miek.nl.\t86400\tIN\tNS\tb.",
`name. IN SOA a6.nstld.com. hostmaster.nic.name. (
203362132 ; serial
5m ; refresh (5 minutes)
5m ; retry (5 minutes)
2w ; expire (2 weeks)
300 ; minimum (5 minutes)
)`: "name.\t3600\tIN\tSOA\ta6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300",
". 3600000 IN NS ONE.MY-ROOTS.NET.":
".\t3600000\tIN\tNS\tONE.MY-ROOTS.NET.",
"ONE.MY-ROOTS.NET. 3600000 IN A 192.168.1.1":
"ONE.MY-ROOTS.NET.\t3600000\tIN\tA\t192.168.1.1",
}
". 3600000 IN NS ONE.MY-ROOTS.NET.": ".\t3600000\tIN\tNS\tONE.MY-ROOTS.NET.",
"ONE.MY-ROOTS.NET. 3600000 IN A 192.168.1.1": "ONE.MY-ROOTS.NET.\t3600000\tIN\tA\t192.168.1.1",
}
for i, o := range tests {
rr, e := NewRR(i)
if e != nil {
@ -191,11 +189,10 @@ func TestParseDirectiveMisc(t *testing.T) {
// Another one hear, geared to NSECx
func TestParseNSEC(t *testing.T) {
nsectests := map[string]string{
"nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F",
"p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM":
"p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM",
"localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC",
}
"nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F",
"p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM": "p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM",
"localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC",
}
for i, o := range nsectests {
rr, e := NewRR(i)
if e != nil {
@ -214,27 +211,23 @@ func TestParseNSEC(t *testing.T) {
func TestQuotes(t *testing.T) {
tests := map[string]string{
`t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"",
`t.example.com. IN TXT "a
bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\\n bc\"",
`t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"",
`t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"",
`t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
`t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
`t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
`t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa \"",
`t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
`t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
`t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
"cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.":
"cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.",
"cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.":
"cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.",
"cid.urn.arpa. NAPTR 100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.":
"cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.",
"cid.urn.arpa. NAPTR 100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .":
"cid.urn.arpa.\t3600\tIN\tNAPTR\t100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .",
}
`t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"",
`t.example.com. IN TXT "a
bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\\n bc\"",
`t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"",
`t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"",
`t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
`t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
`t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
`t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa \"",
`t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
`t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
`t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
"cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.",
"cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.",
"cid.urn.arpa. NAPTR 100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.",
"cid.urn.arpa. NAPTR 100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .",
}
for i, o := range tests {
rr, e := NewRR(i)
if e != nil {
@ -257,11 +250,10 @@ func TestParseBrace(t *testing.T) {
"miek.nl. (3600) IN MX (10) elektron.atoom.net.": "miek.nl.\t3600\tIN\tMX\t10 elektron.atoom.net.",
`miek.nl. IN (
3600 A 127.0.0.1)`: "miek.nl.\t3600\tIN\tA\t127.0.0.1",
"(miek.nl.) (A) (127.0.0.1)": "miek.nl.\t3600\tIN\tA\t127.0.0.1",
"miek.nl A 127.0.0.1": "miek.nl.\t3600\tIN\tA\t127.0.0.1",
"_ssh._tcp.local. 60 IN (PTR) stora._ssh._tcp.local.":
"_ssh._tcp.local.\t60\tIN\tPTR\tstora._ssh._tcp.local.",
"miek.nl. NS ns.miek.nl": "miek.nl.\t3600\tIN\tNS\tns.miek.nl.",
"(miek.nl.) (A) (127.0.0.1)": "miek.nl.\t3600\tIN\tA\t127.0.0.1",
"miek.nl A 127.0.0.1": "miek.nl.\t3600\tIN\tA\t127.0.0.1",
"_ssh._tcp.local. 60 IN (PTR) stora._ssh._tcp.local.": "_ssh._tcp.local.\t60\tIN\tPTR\tstora._ssh._tcp.local.",
"miek.nl. NS ns.miek.nl": "miek.nl.\t3600\tIN\tNS\tns.miek.nl.",
`(miek.nl.) (
(IN)
(AAAA)
@ -374,7 +366,7 @@ func TestZoneParsing(t *testing.T) {
// moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp.
// moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp.
func ExampleZone() {
zone :=`$ORIGIN .
zone := `$ORIGIN .
$TTL 3600 ; 1 hour
name IN SOA a6.nstld.com. hostmaster.nic.name. (
203362132 ; serial
@ -414,20 +406,20 @@ moutamassey NS ns01.yahoodomains.jp.
// www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
func ExampleHIP() {
h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578
h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578
AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
rvs.example.com. )`
if hip, err := NewRR(h); err == nil {
fmt.Printf("%s\n", hip.String())
}
if hip, err := NewRR(h); err == nil {
fmt.Printf("%s\n", hip.String())
}
}
// example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100
func ExampleSOA() {
s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
if soa, err := NewRR(s); err == nil {
fmt.Printf("%s\n", soa.String())
}
s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
if soa, err := NewRR(s); err == nil {
fmt.Printf("%s\n", soa.String())
}
}

View File

@ -1,10 +1,10 @@
package dns
import (
"encoding/base64"
"net"
"strconv"
"strings"
"encoding/base64"
)
// Parse the rdata of each rrtype.
@ -49,7 +49,7 @@ func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
case TypeNAPTR:
r, e = setNAPTR(h, c, o, f)
goto Slurp
case TypeTALINK:
case TypeTALINK:
r, e = setTALINK(h, c, o, f)
goto Slurp
case TypeLOC:
@ -410,7 +410,7 @@ func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
if rr.PreviousName[ld-1] != '.' {
rr.PreviousName = appendOrigin(rr.PreviousName, o)
}
<-c // _BLANK
<-c // _BLANK
l = <-c
rr.NextName = l.token
_, ld, ok = IsDomainName(l.token)
@ -437,12 +437,12 @@ func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
<-c // _BLANK
l = <-c // _STRING
rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
rr.HitLength = uint8(len(rr.Hit))/2
rr.HitLength = uint8(len(rr.Hit)) / 2
<-c // _BLANK
l = <-c // _STRING
rr.PublicKey = l.token // This cannot contain spaces
rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
// RendezvousServers (if any)
l = <-c