2011-01-16 00:40:54 +11:00
package dns
2010-12-31 06:00:26 +11:00
2011-01-18 06:29:40 +11:00
import (
2011-12-10 07:45:57 +11:00
"crypto/rsa"
2012-02-18 06:37:19 +11:00
"fmt"
2012-10-05 17:49:31 +10:00
"net"
2011-12-16 03:37:07 +11:00
"os"
2012-10-05 17:49:31 +10:00
"strconv"
2011-07-24 07:43:43 +10:00
"strings"
2011-01-18 06:29:40 +11:00
"testing"
2011-12-16 03:37:07 +11:00
"time"
2011-01-18 06:29:40 +11:00
)
2010-12-31 06:00:26 +11:00
2012-04-07 03:29:50 +10:00
func TestSignRSA ( t * testing . T ) {
2011-07-18 04:51:27 +10:00
pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ"
2011-01-18 05:52:28 +11:00
2011-07-18 04:51:27 +10:00
priv := ` Private - key - format : v1 .3
2011-01-18 05:52:28 +11:00
Algorithm : 5 ( RSASHA1 )
2011-07-18 04:51:27 +10:00
Modulus : v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8 / FCczL25wLKUD4W4f1xKMhw9 / g + ol926keT1foQFiPGsItjinX / IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k =
2011-01-18 05:52:28 +11:00
PublicExponent : AQAB
2011-07-18 04:51:27 +10:00
PrivateExponent : YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66 / EN / GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV + YDyEu7Hp / rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV / 1 wRDK1A5NxsHPDMYi2SoK63Enm / 1 ptk =
Prime1 : / wjOG + fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx / x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw ==
Prime2 : wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA + t + iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw ==
Exponent1 : N0A7FsSRIg + IAN8YPQqlawoTtG1t1OkJ + nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ ==
Exponent2 : SvuYRaGyvo0zemE3oS + WRm2scxR8eiA8WJGeOc + obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW / vwMA46lpLzJNw ==
Coefficient : 8 + 7 ZN / JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs + hGw ==
Created : 20110302104537
Publish : 20110302104537
Activate : 20110302104537 `
2011-01-18 05:52:28 +11:00
2011-12-17 03:32:15 +11:00
xk , _ := NewRR ( pub )
2011-12-16 03:37:07 +11:00
k := xk . ( * RR_DNSKEY )
2012-04-16 04:55:25 +10:00
p , err := k . NewPrivateKey ( priv )
2011-07-24 07:43:43 +10:00
if err != nil {
t . Logf ( "%v\n" , err )
t . Fail ( )
}
2011-01-18 06:29:40 +11:00
switch priv := p . ( type ) {
case * rsa . PrivateKey :
if 65537 != priv . PublicKey . E {
2011-03-25 01:52:37 +11:00
t . Log ( "Exponenent should be 65537" )
2011-01-18 06:29:40 +11:00
t . Fail ( )
}
2011-07-24 07:43:43 +10:00
default :
t . Logf ( "We should have read an RSA key: %v" , priv )
t . Fail ( )
2011-01-18 06:29:40 +11:00
}
2011-07-18 04:51:27 +10:00
if k . KeyTag ( ) != 37350 {
2011-07-17 23:47:03 +10:00
t . Logf ( "%d %v\n" , k . KeyTag ( ) , k )
2011-07-18 04:51:27 +10:00
t . Log ( "Keytag should be 37350" )
2011-01-18 06:29:40 +11:00
t . Fail ( )
}
2011-01-18 21:25:47 +11:00
2011-02-22 06:33:36 +11:00
soa := new ( RR_SOA )
soa . Hdr = RR_Header { "miek.nl." , TypeSOA , ClassINET , 14400 , 0 }
soa . Ns = "open.nlnetlabs.nl."
soa . Mbox = "miekg.atoom.net."
soa . Serial = 1293945905
soa . Refresh = 14400
soa . Retry = 3600
soa . Expire = 604800
soa . Minttl = 86400
2011-01-18 21:25:47 +11:00
2011-02-22 06:33:36 +11:00
sig := new ( RR_RRSIG )
sig . Hdr = RR_Header { "miek.nl." , TypeRRSIG , ClassINET , 14400 , 0 }
sig . Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
sig . Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
sig . KeyTag = k . KeyTag ( )
sig . SignerName = k . Hdr . Name
sig . Algorithm = k . Algorithm
2011-01-18 21:25:47 +11:00
2011-02-22 06:33:36 +11:00
sig . Sign ( p , [ ] RR { soa } )
2011-07-24 07:43:43 +10:00
if sig . Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
t . Log ( "Signature is not correct" )
t . Logf ( "%v\n" , sig )
t . Fail ( )
}
2011-01-18 05:52:28 +11:00
}
2011-02-22 04:23:39 +11:00
2012-04-11 23:13:17 +10:00
func TestSignECDSA ( t * testing . T ) {
pub := ` example . net . 3600 IN DNSKEY 257 3 14 (
xKYaNhWdGOfJ + nPrL8 / arkwf2EY3MDJ + SErKivBVSum1
w / egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ + OB + v8
/ uX45NBwY8rp65F6Glur8I / mlVNgF6W / qTI37m40 ) `
priv := ` Private - key - format : v1 .2
Algorithm : 14 ( ECDSAP384SHA384 )
PrivateKey : WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR `
eckey , err := NewRR ( pub )
if err != nil {
2012-04-11 23:42:33 +10:00
t . Fatal ( err . Error ( ) )
2012-04-11 23:13:17 +10:00
}
2012-04-16 04:55:25 +10:00
privkey , err := eckey . ( * RR_DNSKEY ) . NewPrivateKey ( priv )
2012-04-11 23:13:17 +10:00
if err != nil {
t . Fatal ( err . Error ( ) )
}
ds := eckey . ( * RR_DNSKEY ) . ToDS ( SHA384 )
if ds . KeyTag != 10771 {
t . Fatal ( "Wrong keytag on DS" )
}
if ds . Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" {
t . Fatal ( "Wrong DS Digest" )
}
a , _ := NewRR ( "www.example.net. 3600 IN A 192.0.2.1" )
sig := new ( RR_RRSIG )
sig . Hdr = RR_Header { "example.net." , TypeRRSIG , ClassINET , 14400 , 0 }
2012-09-17 16:56:27 +10:00
sig . Expiration , _ = StringToTime ( "20100909102025" )
sig . Inception , _ = StringToTime ( "20100812102025" )
2012-04-11 23:13:17 +10:00
sig . KeyTag = eckey . ( * RR_DNSKEY ) . KeyTag ( )
sig . SignerName = eckey . ( * RR_DNSKEY ) . Hdr . Name
sig . Algorithm = eckey . ( * RR_DNSKEY ) . Algorithm
sig . Sign ( privkey , [ ] RR { a } )
t . Logf ( "%s" , sig . String ( ) )
2012-04-12 00:20:29 +10:00
if e := sig . Verify ( eckey . ( * RR_DNSKEY ) , [ ] RR { a } ) ; e != nil {
t . Logf ( "Failure to validate: %s" , e . Error ( ) )
t . Fail ( )
}
2012-04-11 23:13:17 +10:00
}
2011-02-22 06:33:36 +11:00
func TestDotInName ( t * testing . T ) {
buf := make ( [ ] byte , 20 )
2012-01-12 02:16:09 +11:00
PackDomainName ( "aa\\.bb.nl." , buf , 0 , nil , false )
2011-07-24 07:43:43 +10:00
// index 3 must be a real dot
if buf [ 3 ] != '.' {
t . Log ( "Dot should be a real dot" )
t . Fail ( )
}
2011-02-22 06:33:36 +11:00
2011-07-24 07:43:43 +10:00
if buf [ 6 ] != 2 {
t . Log ( "This must have the value 2" )
t . Fail ( )
}
2011-12-10 07:12:03 +11:00
dom , _ , _ := UnpackDomainName ( buf , 0 )
2011-07-24 07:43:43 +10:00
// printing it should yield the backspace again
if dom != "aa\\.bb.nl." {
t . Log ( "Dot should have been escaped: " + dom )
t . Fail ( )
}
2011-02-22 04:23:39 +11:00
}
2011-12-16 03:37:07 +11:00
2011-12-18 23:42:59 +11:00
func TestParseZone ( t * testing . T ) {
2011-12-18 23:56:27 +11:00
zone := ` z1 . miek . nl . 86400 IN RRSIG NSEC 8 3 86400 20110823011301 20110724011301 12051 miek . nl . lyRljEQFOmajcdo6bBI67DsTlQTGU3ag9vlE07u7ynqt9aYBXyE9mkasAK4V0oI32YGb2pOSB6RbbdHwUmSt + cYhOA49tl2t0Qoi3pH21dicJiupdZuyjfqUEqJlQoEhNXGtP / pRvWjNA4pQeOsOAoWq / BDcWCSQB9mh2LvUOH4 = ; { keyid = sksak }
2011-12-19 04:15:09 +11:00
z2 . miek . nl . 86400 IN NSEC miek . nl . TXT RRSIG NSEC
$ TTL 100
z3 . miek . nl . IN NSEC miek . nl . TXT RRSIG NSEC `
2012-02-14 23:46:40 +11:00
to := ParseZone ( strings . NewReader ( zone ) , "" , "" )
2011-12-19 04:15:09 +11:00
i := 0
2011-12-18 23:42:59 +11:00
for x := range to {
if x . Error == nil {
2011-12-19 04:15:09 +11:00
switch i {
case 0 :
2012-01-12 21:17:01 +11:00
if x . RR . Header ( ) . Name != "z1.miek.nl." {
2011-12-19 04:15:09 +11:00
t . Log ( "Failed to parse z1" )
t . Fail ( )
}
case 1 :
2012-01-12 21:17:01 +11:00
if x . RR . Header ( ) . Name != "z2.miek.nl." {
2011-12-19 04:15:09 +11:00
t . Log ( "Failed to parse z2" )
t . Fail ( )
}
case 2 :
2012-01-13 08:49:26 +11:00
if x . RR . String ( ) != "z3.miek.nl.\t100\tIN\tNSEC\tmiek.nl. TXT RRSIG NSEC" {
2012-01-12 21:17:01 +11:00
t . Logf ( "Failed to parse z3 %s" , x . RR . String ( ) )
2011-12-19 04:15:09 +11:00
t . Fail ( )
2012-01-13 08:49:26 +11:00
}
2011-12-19 04:15:09 +11:00
}
2011-12-17 20:16:24 +11:00
} else {
2011-12-19 04:15:09 +11:00
t . Logf ( "Failed to parse: %v\n" , x . Error )
2011-12-18 23:42:59 +11:00
t . Fail ( )
2011-12-17 20:16:24 +11:00
}
2011-12-19 04:15:09 +11:00
i ++
2011-12-17 20:16:24 +11:00
}
}
2012-01-09 00:53:55 +11:00
func TestDomainName ( t * testing . T ) {
2012-02-15 20:28:55 +11:00
tests := [ ] string { "r\\.gieben.miek.nl." , "www\\.www.miek.nl." ,
2012-02-24 05:37:08 +11:00
"www.*.miek.nl." , "www.*.miek.nl." ,
}
2012-01-13 08:49:26 +11:00
dbuff := make ( [ ] byte , 40 )
2012-01-09 00:53:55 +11:00
2012-01-13 08:49:26 +11:00
for _ , ts := range tests {
2012-10-10 07:15:33 +11:00
if _ , err := PackDomainName ( ts , dbuff , 0 , nil , false ) ; err != nil {
2012-01-13 08:49:26 +11:00
t . Log ( "Not a valid domain name" )
t . Fail ( )
continue
}
2012-10-10 07:15:33 +11:00
n , _ , err := UnpackDomainName ( dbuff , 0 )
if err != nil {
2012-01-13 08:49:26 +11:00
t . Log ( "Failed to unpack packed domain name" )
t . Fail ( )
continue
}
if ts != n {
t . Logf ( "Must be equal: in: %s, out: %s\n" , ts , n )
t . Fail ( )
}
}
2012-01-09 00:53:55 +11:00
}
2012-02-15 19:04:09 +11:00
func TestParseDirectiveMisc ( t * testing . T ) {
2012-02-12 21:45:44 +11:00
tests := map [ string ] string {
2012-02-24 05:37:08 +11:00
"$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 . (
2012-02-15 19:04:09 +11:00
203362132 ; serial
5 m ; refresh ( 5 minutes )
5 m ; retry ( 5 minutes )
2 w ; expire ( 2 weeks )
300 ; minimum ( 5 minutes )
) ` : "name.\t3600\tIN\tSOA\ta6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300" ,
2012-02-24 05:37:08 +11:00
". 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" ,
}
2012-02-12 21:45:44 +11:00
for i , o := range tests {
rr , e := NewRR ( i )
if e != nil {
t . Log ( "Failed to parse RR: " + e . Error ( ) )
t . Fail ( )
continue
}
if rr . String ( ) != o {
t . Logf ( "`%s' should be equal to\n`%s', but is `%s'\n" , i , o , rr . String ( ) )
t . Fail ( )
} else {
t . Logf ( "RR is OK: `%s'" , rr . String ( ) )
}
}
}
2012-02-12 08:59:34 +11:00
func TestParseNSEC ( t * testing . T ) {
nsectests := map [ string ] string {
2012-03-02 08:40:34 +11:00
"nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F" : "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F" ,
2012-02-24 05:37:08 +11:00
"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" ,
2012-03-02 08:40:34 +11:00
"localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC" : "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC" ,
"localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC TYPE65534" : "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534" ,
2012-02-24 05:37:08 +11:00
}
2012-02-12 08:59:34 +11:00
for i , o := range nsectests {
rr , e := NewRR ( i )
if e != nil {
t . Log ( "Failed to parse RR: " + e . Error ( ) )
t . Fail ( )
continue
}
if rr . String ( ) != o {
t . Logf ( "`%s' should be equal to\n`%s', but is `%s'\n" , i , o , rr . String ( ) )
t . Fail ( )
} else {
t . Logf ( "RR is OK: `%s'" , rr . String ( ) )
}
}
}
2012-05-01 05:42:58 +10:00
func TestParseLOC ( t * testing . T ) {
2012-05-01 05:57:42 +10:00
lt := map [ string ] string {
2012-05-06 01:37:48 +10:00
"SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m" : "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m" ,
"SW1A2AA.find.me.uk. LOC 51 0 0.0 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m" : "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 00 0.000 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m" ,
2012-05-01 05:57:42 +10:00
}
for i , o := range lt {
rr , e := NewRR ( i )
if e != nil {
t . Log ( "Failed to parse RR: " + e . Error ( ) )
t . Fail ( )
continue
}
if rr . String ( ) != o {
t . Logf ( "`%s' should be equal to\n`%s', but is `%s'\n" , i , o , rr . String ( ) )
t . Fail ( )
} else {
t . Logf ( "RR is OK: `%s'" , rr . String ( ) )
}
2012-05-01 05:42:58 +10:00
}
}
2012-02-13 05:06:32 +11:00
func TestQuotes ( t * testing . T ) {
tests := map [ string ] string {
2012-02-24 05:37:08 +11:00
` 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\" ." ,
}
2012-02-13 05:06:32 +11:00
for i , o := range tests {
rr , e := NewRR ( i )
if e != nil {
t . Log ( "Failed to parse RR: " + e . Error ( ) )
t . Fail ( )
continue
}
if rr . String ( ) != o {
2012-02-13 07:50:02 +11:00
t . Logf ( "`%s' should be equal to\n`%s', but is\n`%s'\n" , i , o , rr . String ( ) )
2012-02-13 05:06:32 +11:00
t . Fail ( )
} else {
t . Logf ( "RR is OK: `%s'" , rr . String ( ) )
}
}
}
2011-12-17 21:28:54 +11:00
func TestParseBrace ( t * testing . T ) {
2011-12-17 20:16:24 +11:00
tests := map [ string ] string {
"(miek.nl.) 3600 IN A 127.0.0.1" : "miek.nl.\t3600\tIN\tA\t127.0.0.1" ,
"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" ,
2012-02-24 05:37:08 +11:00
"(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." ,
2011-12-17 21:28:54 +11:00
` ( miek . nl . ) (
( IN )
( AAAA )
( : : 1 ) ) ` : "miek.nl.\t3600\tIN\tAAAA\t::1" ,
2011-12-17 20:16:24 +11:00
` ( miek . nl . ) (
( IN )
( AAAA )
( : : 1 ) ) ` : "miek.nl.\t3600\tIN\tAAAA\t::1" ,
2012-01-13 08:49:26 +11:00
` ( ( m ) ( i ) ek . ( n ) l . ) ( SOA ) ( soa . ) ( soa . ) (
2012-01-12 20:50:01 +11:00
2009032802 ; serial
21600 ; refresh ( 6 hours )
7 ( 2 ) 00 ; retry ( 2 hours )
604 ( ) 800 ; expire ( 1 week )
3600 ; minimum ( 1 hour )
) ` : "miek.nl.\t3600\tIN\tSOA\tsoa. soa. 2009032802 21600 7200 604800 3600" ,
2012-01-13 08:49:26 +11:00
"miek\\.nl. IN A 127.0.0.1" : "miek\\.nl.\t3600\tIN\tA\t127.0.0.1" ,
"miek.nl. IN 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" ,
2011-12-17 20:16:24 +11:00
` miek . nl . 86400 IN SOA elektron . atoom . net . miekg . atoom . net . (
2009032802 ; serial
21600 ; refresh ( 6 hours )
7200 ; retry ( 2 hours )
604800 ; expire ( 1 week )
3600 ; minimum ( 1 hour )
) ` : "miek.nl.\t86400\tIN\tSOA\telektron.atoom.net. miekg.atoom.net. 2009032802 21600 7200 604800 3600" ,
2011-07-24 07:43:43 +10:00
}
2011-12-16 03:37:07 +11:00
for i , o := range tests {
2011-12-17 21:28:54 +11:00
rr , e := NewRR ( i )
if e != nil {
2011-12-18 23:42:59 +11:00
t . Log ( "Failed to parse RR: " + e . Error ( ) )
2011-12-16 20:26:32 +11:00
t . Fail ( )
2011-12-18 23:42:59 +11:00
continue
2011-12-16 20:26:32 +11:00
}
2011-12-16 08:40:07 +11:00
if rr . String ( ) != o {
t . Logf ( "`%s' should be equal to\n`%s', but is `%s'\n" , i , o , rr . String ( ) )
t . Fail ( )
} else {
2011-12-16 20:26:32 +11:00
t . Logf ( "RR is OK: `%s'" , rr . String ( ) )
}
2011-07-24 07:43:43 +10:00
}
2011-07-16 01:41:26 +10:00
}
2011-07-18 23:19:47 +10:00
2011-07-25 01:08:33 +10:00
func TestParseFailure ( t * testing . T ) {
2011-12-16 03:37:07 +11:00
tests := [ ] string { "miek.nl. IN A 327.0.0.1" ,
"miek.nl. IN AAAA ::x" ,
"miek.nl. IN MX a0 miek.nl." ,
"miek.nl aap IN MX mx.miek.nl." ,
"miek.nl. IN CNAME " ,
"miek.nl. PA MX 10 miek.nl." ,
2011-12-17 20:16:24 +11:00
"miek.nl. ) IN MX 10 miek.nl." ,
2011-12-16 03:37:07 +11:00
}
2011-07-25 01:08:33 +10:00
2011-12-16 03:37:07 +11:00
for _ , s := range tests {
2011-12-16 03:49:43 +11:00
_ , err := NewRR ( s )
2011-12-16 03:37:07 +11:00
if err == nil {
t . Log ( "Should have triggered an error" )
t . Fail ( )
}
}
2011-07-18 23:19:47 +10:00
}
2011-07-23 06:06:07 +10:00
2011-12-18 21:22:40 +11:00
// A bit useless, how to use b.N?
2011-07-23 06:06:07 +10:00
func BenchmarkZoneParsing ( b * testing . B ) {
2012-08-26 05:30:16 +10:00
b . StopTimer ( )
2012-01-23 06:44:52 +11:00
f , err := os . Open ( "t/miek.nl.signed_test" )
2011-07-24 07:43:43 +10:00
if err != nil {
return
}
2011-12-16 03:37:07 +11:00
defer f . Close ( )
2012-08-26 05:30:16 +10:00
b . StartTimer ( )
for i := 0 ; i < b . N ; i ++ {
to := ParseZone ( f , "" , "t/miek.nl.signed_test" )
for _ = range to {
}
2011-12-17 00:38:52 +11:00
}
2011-07-23 06:06:07 +10:00
}
func TestZoneParsing ( t * testing . T ) {
2012-01-23 06:44:52 +11:00
f , err := os . Open ( "t/miek.nl.signed_test" )
2011-07-24 07:43:43 +10:00
if err != nil {
return
}
2011-12-16 03:37:07 +11:00
defer f . Close ( )
2011-12-19 07:01:32 +11:00
start := time . Now ( ) . UnixNano ( )
2012-02-14 23:46:40 +11:00
to := ParseZone ( f , "" , "t/miek.nl.signed_test" )
2011-12-16 03:37:07 +11:00
var i int
2011-12-17 00:38:52 +11:00
for x := range to {
2012-01-12 21:17:01 +11:00
t . Logf ( "%s\n" , x . RR )
2011-12-16 03:37:07 +11:00
i ++
2011-07-24 07:43:43 +10:00
}
2011-12-19 07:01:32 +11:00
delta := time . Now ( ) . UnixNano ( ) - start
2011-12-16 03:37:07 +11:00
t . Logf ( "%d RRs parsed in %.2f s (%.2f RR/s)" , i , float32 ( delta ) / 1e9 , float32 ( i ) / ( float32 ( delta ) / 1e9 ) )
2011-07-23 06:06:07 +10:00
}
2012-02-18 06:37:19 +11:00
// name. 3600 IN SOA a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300
2012-03-01 19:16:28 +11:00
// name. 10800 IN NS name.
2012-02-18 06:37:19 +11:00
// name. 10800 IN NS g6.nstld.com.
2012-02-28 04:48:53 +11:00
// name. 7200 IN NS h6.nstld.com.
// name. 3600 IN NS j6.nstld.com.
// name. 3600 IN NS k6.nstld.com.
2012-02-18 06:37:19 +11:00
// name. 10800 IN NS l6.nstld.com.
// name. 10800 IN NS a6.nstld.com.
// name. 10800 IN NS c6.nstld.com.
// name. 10800 IN NS d6.nstld.com.
// name. 10800 IN NS f6.nstld.com.
// name. 10800 IN NS m6.nstld.com.
// 0-0onlus.name. 10800 IN NS ns7.ehiweb.it.
// 0-0onlus.name. 10800 IN NS ns8.ehiweb.it.
// 0-g.name. 10800 IN MX 10 mx01.nic.name.
// 0-g.name. 10800 IN MX 10 mx02.nic.name.
// 0-g.name. 10800 IN MX 10 mx03.nic.name.
// 0-g.name. 10800 IN MX 10 mx04.nic.name.
2012-02-24 05:15:06 +11:00
// 0-g.name. 10800 IN TXT "10 mx\"04.nic"
2012-02-18 06:37:19 +11:00
// moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp.
// moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp.
func ExampleZone ( ) {
2012-02-24 05:37:08 +11:00
zone := ` $ ORIGIN .
2012-02-18 06:37:19 +11:00
$ TTL 3600 ; 1 hour
name IN SOA a6 . nstld . com . hostmaster . nic . name . (
203362132 ; serial
300 ; refresh ( 5 minutes )
300 ; retry ( 5 minutes )
1209600 ; expire ( 2 weeks )
300 ; minimum ( 5 minutes )
)
$ TTL 10800 ; 3 hours
2012-03-01 19:16:28 +11:00
@ 10800 IN NS @
2012-02-28 04:48:53 +11:00
IN NS g6 . nstld . com .
7200 NS h6 . nstld . com .
3600 IN NS j6 . nstld . com .
IN 3600 NS k6 . nstld . com .
2012-02-18 06:37:19 +11:00
NS l6 . nstld . com .
NS a6 . nstld . com .
NS c6 . nstld . com .
NS d6 . nstld . com .
NS f6 . nstld . com .
NS m6 . nstld . com .
$ ORIGIN name .
0 - 0 onlus NS ns7 . ehiweb . it .
NS ns8 . ehiweb . it .
0 - g MX 10 mx01 . nic
MX 10 mx02 . nic
MX 10 mx03 . nic
MX 10 mx04 . nic
2012-02-24 05:15:06 +11:00
TXT "10 mx\"04.nic"
2012-02-18 06:37:19 +11:00
$ ORIGIN 0 - g . name
moutamassey NS ns01 . yahoodomains . jp .
NS ns02 . yahoodomains . jp .
`
to := ParseZone ( strings . NewReader ( zone ) , "" , "testzone" )
for x := range to {
fmt . Printf ( "%s\n" , x . RR )
}
}
2012-02-19 21:27:16 +11:00
2012-02-19 22:28:31 +11:00
// www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
2012-02-19 21:27:16 +11:00
func ExampleHIP ( ) {
2012-02-24 05:37:08 +11:00
h := ` www . example . com IN HIP ( 2 200100107 B1A74DF365639CC39F1D578
2012-02-19 22:28:31 +11:00
AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
9 + LrV4e19WzK00 + CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu + Upr1gsNrut79ryra + bSRGQ
b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
rvs . example . com . ) `
2012-02-24 05:37:08 +11:00
if hip , err := NewRR ( h ) ; err == nil {
fmt . Printf ( "%s\n" , hip . String ( ) )
}
2012-02-19 21:27:16 +11:00
}
2012-02-20 04:36:59 +11:00
// example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100
func ExampleSOA ( ) {
2012-02-24 05:37:08 +11:00
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 ( ) )
}
2012-02-20 04:36:59 +11:00
}
2012-03-04 03:40:30 +11:00
func TestLineNumberError ( t * testing . T ) {
s := "example.com. 1000 SOA master.example.com. admin.example.com. monkey 4294967294 4294967293 4294967295 100"
if _ , err := NewRR ( s ) ; err != nil {
if err . Error ( ) != "dns: bad SOA zone parameter: \"monkey\" at line: 1:68" {
t . Logf ( "Not expecting this error: " + err . Error ( ) )
t . Fail ( )
}
}
}
// Test with no known RR on the line
func TestLineNumberError2 ( t * testing . T ) {
s := "example.com. 1000 SO master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
_ , err := NewRR ( s )
if err == nil {
t . Fail ( )
} else {
2012-04-12 00:20:29 +10:00
// fmt.Printf("%s\n", err.Error())
2012-03-04 03:40:30 +11:00
}
}
2012-05-15 20:24:57 +10:00
// Test if the calculations are correct
func TestRfc1982 ( t * testing . T ) {
// If the current time and the timestamp are more than 68 years apart
// it means the date has wrapped. 0 is 1970
// fall in the current 68 year span
strtests := [ ] string { "20120525134203" , "19700101000000" , "20380119031408" }
for _ , v := range strtests {
2012-09-17 16:56:27 +10:00
if x , _ := StringToTime ( v ) ; v != TimeToString ( x ) {
2012-09-12 05:45:21 +10:00
t . Logf ( "1982 arithmetic string failure %s (%s:%d)" , v , TimeToString ( x ) , x )
2012-05-15 20:24:57 +10:00
t . Fail ( )
}
}
inttests := map [ uint32 ] string { 0 : "19700101000000" ,
1 << 31 : "20380119031408" ,
1 << 32 - 1 : "21060207062815" ,
}
for i , v := range inttests {
2012-09-12 05:45:21 +10:00
if TimeToString ( i ) != v {
t . Logf ( "1982 arithmetic int failure %d:%s (%s)" , i , v , TimeToString ( i ) )
2012-05-15 20:24:57 +10:00
t . Fail ( )
}
}
// Future tests, these dates get parsed to a date within the current 136 year span
future := map [ string ] string { "22680119031408" : "20631123173144" ,
"19010101121212" : "20370206184028" ,
"19210101121212" : "20570206184028" ,
"19500101121212" : "20860206184028" ,
"19700101000000" : "19700101000000" ,
"19690101000000" : "21050207062816" ,
"29210101121212" : "21040522212236" ,
}
for from , to := range future {
2012-09-17 16:56:27 +10:00
x , _ := StringToTime ( from )
2012-09-12 05:45:21 +10:00
y := TimeToString ( x )
2012-05-15 20:24:57 +10:00
if y != to {
t . Logf ( "1982 arithmetic future failure %s:%s (%s)" , from , to , y )
t . Fail ( )
}
}
}
2012-05-20 23:28:27 +10:00
2012-05-20 23:31:35 +10:00
func TestEmpty ( t * testing . T ) {
for _ = range ParseZone ( strings . NewReader ( "" ) , "" , "" ) {
t . Logf ( "Should be empty" )
t . Fail ( )
}
}
2012-05-20 23:41:14 +10:00
// 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER1.EXAMPLE.
// 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER2.EXAMPLE.
// 1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.
// 2.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 2.0.0.0.192.IN-ADDR.ARPA.
// 3.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 3.0.0.0.192.IN-ADDR.ARPA.
// 4.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 4.0.0.0.192.IN-ADDR.ARPA.
// 5.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 5.0.0.0.192.IN-ADDR.ARPA.
// 6.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 6.0.0.0.192.IN-ADDR.ARPA.
// 7.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 7.0.0.0.192.IN-ADDR.ARPA.
// 8.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 8.0.0.0.192.IN-ADDR.ARPA.
func ExampleGenerate ( ) {
// From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761
zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0"
to := ParseZone ( strings . NewReader ( zone ) , "0.0.192.IN-ADDR.ARPA." , "" )
2012-05-20 23:28:27 +10:00
for x := range to {
if x . Error == nil {
2012-05-20 23:41:14 +10:00
fmt . Printf ( "%s\n" , x . RR . String ( ) )
2012-05-20 23:28:27 +10:00
}
}
}
2012-10-05 17:49:31 +10:00
func TestSRVPacking ( t * testing . T ) {
msg := Msg { }
things := [ ] string { "1.2.3.4:8484" ,
"45.45.45.45:8484" ,
"84.84.84.84:8484" ,
}
for i , n := range things {
h , p , err := net . SplitHostPort ( n )
if err != nil {
continue
}
port := 8484
tmp , err := strconv . Atoi ( p )
if err == nil {
port = tmp
}
rr := & RR_SRV {
Hdr : RR_Header { Name : "somename." ,
Rrtype : TypeSRV ,
Class : ClassINET ,
Ttl : 5 } ,
Priority : uint16 ( i ) ,
Weight : 5 ,
Port : uint16 ( port ) ,
Target : h + "." ,
}
msg . Answer = append ( msg . Answer , rr )
}
2012-10-10 07:15:33 +11:00
_ , err := msg . Pack ( )
2012-10-11 07:17:50 +11:00
if err != nil {
2012-10-05 17:49:31 +10:00
t . Fatalf ( "Couldn't pack %v\n" , msg )
}
}
2012-11-15 19:39:32 +11:00
func TestParseBackslash ( t * testing . T ) {
r , e := NewRR ( "nul\\000gap.test.globnix.net. 600 IN A 192.0.2.10" )
if e != nil {
t . Fatalf ( "Could not create RR with \\000 in it" )
} else {
t . Logf ( "Parsed %s\n" , r . String ( ) )
}
}
2012-11-18 19:10:28 +11:00
func TestILNP ( t * testing . T ) {
tests := [ ] string {
2012-11-18 20:29:05 +11:00
"host1.example.com.\t3600\tIN\tNID\t10 0014:4fff:ff20:ee64" ,
"host1.example.com.\t3600\tIN\tNID\t20 0015:5fff:ff21:ee65" ,
"host2.example.com.\t3600\tIN\tNID\t10 0016:6fff:ff22:ee66" ,
"host1.example.com.\t3600\tIN\tL32\t10 10.1.2.0" ,
"host1.example.com.\t3600\tIN\tL32\t20 10.1.4.0" ,
"host2.example.com.\t3600\tIN\tL32\t10 10.1.8.0" ,
"host1.example.com.\t3600\tIN\tL64\t10 2001:0DB8:1140:1000" ,
"host1.example.com.\t3600\tIN\tL64\t20 2001:0DB8:2140:2000" ,
"host2.example.com.\t3600\tIN\tL64\t10 2001:0DB8:4140:4000" ,
"host1.example.com.\t3600\tIN\tLP\t10 l64-subnet1.example.com." ,
"host1.example.com.\t3600\tIN\tLP\t10 l64-subnet2.example.com." ,
"host1.example.com.\t3600\tIN\tLP\t20 l32-subnet1.example.com." ,
2012-11-18 19:10:28 +11:00
}
for _ , t1 := range tests {
r , e := NewRR ( t1 )
if e != nil {
t . Fatalf ( "An error occured: %s\n" , e . Error ( ) )
} else {
2012-11-18 20:29:05 +11:00
if t1 != r . String ( ) {
t . Fatalf ( "Strings should be equal %s %s" , t1 , r . String ( ) )
}
2012-11-18 19:10:28 +11:00
}
}
}