This commit is contained in:
Miek Gieben 2011-07-23 23:43:43 +02:00
parent b56e9b4e04
commit da0603089a
14 changed files with 6154 additions and 4164 deletions

View File

@ -108,7 +108,7 @@ func (mux *QueryMux) HandleQueryFunc(pattern string, handler func(RequestWriter,
func (mux *QueryMux) QueryDNS(w RequestWriter, r *Msg) {
h := mux.match(r.Question[0].Name)
if h == nil {
panic("dns: no handler found for " + r.Question[0].Name)
panic("dns: no handler found for " + r.Question[0].Name)
}
h.QueryDNS(w, r)
}
@ -122,7 +122,7 @@ type Client struct {
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
// LocalAddr string // Local address to use
// LocalAddr string // Local address to use
}
// Create a new client, with some defaults.
@ -144,7 +144,7 @@ func (q *Query) Query() os.Error {
if handler == nil {
handler = DefaultQueryMux
}
//forever:
//forever:
for {
select {
case in := <-q.ChannelQuery:
@ -210,7 +210,7 @@ func (c *Client) Exchange(m *Msg, a string) *Msg {
return nil
}
p = p[:n]
r := new(Msg)
r := new(Msg)
if ok := r.Unpack(p); !ok {
return nil
}

View File

@ -2,7 +2,7 @@ package dns
import (
"testing"
"time"
"time"
)
func TestClientSync(t *testing.T) {
@ -80,19 +80,19 @@ func TestClientTsigAXFR(t *testing.T) {
m := new(Msg)
m.SetAxfr("miek.nl")
m.SetTsig("axfr", HmacMD5, 300, uint64(time.Seconds()))
secrets := make(map[string]string)
secrets["axfr"] = "so6ZGir4GPAqINNh9U5c3A=="
m.SetTsig("axfr", HmacMD5, 300, uint64(time.Seconds()))
secrets := make(map[string]string)
secrets["axfr"] = "so6ZGir4GPAqINNh9U5c3A=="
c := NewClient()
c.Net = "tcp"
c.TsigSecret = secrets
c := NewClient()
c.Net = "tcp"
c.TsigSecret = secrets
c.XfrReceive(m, "85.223.71.124:53")
/*
if err != nil {
t.Log("%s\n", err.String())
t.Fail()
}
*/
c.XfrReceive(m, "85.223.71.124:53")
/*
if err != nil {
t.Log("%s\n", err.String())
t.Fail()
}
*/
}

View File

@ -38,7 +38,7 @@ func ClientConfigFromFile(conf string) (*ClientConfig, os.Error) {
b := bufio.NewReader(file)
c.Servers = make([]string, 3)[0:0] // small, but the standard limit
c.Search = make([]string, 0)
c.Port = "53"
c.Port = "53"
c.Ndots = 1
c.Timeout = 5
c.Attempts = 2

192
dnssec.go
View File

@ -6,8 +6,8 @@ import (
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"crypto/rand"
"encoding/hex"
@ -22,25 +22,25 @@ import (
// DNSSEC encryption algorithm codes.
const (
RSAMD5 = 1
DH = 2
DSA = 3
ECC = 4
RSASHA1 = 5
RSASHA256 = 8
RSASHA512 = 10
ECCGOST = 12
ECDSAP256SHA256 = 13
ECDSAP384SHA384 = 14
RSAMD5 = 1
DH = 2
DSA = 3
ECC = 4
RSASHA1 = 5
RSASHA256 = 8
RSASHA512 = 10
ECCGOST = 12
ECDSAP256SHA256 = 13
ECDSAP384SHA384 = 14
)
// DNSSEC hashing algorithm codes.
const (
_ = iota
SHA1 // RFC 4034
SHA256 // RFC 4509
GOST94 // RFC 5933
SHA384 // Experimental
_ = iota
SHA1 // RFC 4034
SHA256 // RFC 4509
GOST94 // RFC 5933
SHA384 // Experimental
)
// DNSKEY flag values.
@ -151,8 +151,8 @@ func (k *RR_DNSKEY) ToDS(h int) *RR_DS {
s := sha256.New()
io.WriteString(s, string(digest))
ds.Digest = hex.EncodeToString(s.Sum())
case SHA384:
s := sha512.New384()
case SHA384:
s := sha512.New384()
io.WriteString(s, string(digest))
ds.Digest = hex.EncodeToString(s.Sum())
case GOST94:
@ -213,49 +213,49 @@ func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) bool {
}
signdata = append(signdata, wire...)
var sighash []byte
var h hash.Hash
var ch crypto.Hash // Only need for RSA
switch s.Algorithm {
case RSAMD5:
h = md5.New()
ch = crypto.MD5
case RSASHA1:
h = sha1.New()
ch = crypto.SHA1
case RSASHA256, ECDSAP256SHA256:
h = sha256.New()
ch = crypto.SHA256
case ECDSAP384SHA384:
h = sha512.New384()
case RSASHA512:
h = sha512.New()
ch = crypto.SHA512
default:
return false // Illegal alg
}
io.WriteString(h, string(signdata))
sighash = h.Sum()
var sighash []byte
var h hash.Hash
var ch crypto.Hash // Only need for RSA
switch s.Algorithm {
case RSAMD5:
h = md5.New()
ch = crypto.MD5
case RSASHA1:
h = sha1.New()
ch = crypto.SHA1
case RSASHA256, ECDSAP256SHA256:
h = sha256.New()
ch = crypto.SHA256
case ECDSAP384SHA384:
h = sha512.New384()
case RSASHA512:
h = sha512.New()
ch = crypto.SHA512
default:
return false // Illegal alg
}
io.WriteString(h, string(signdata))
sighash = h.Sum()
switch p := k.(type) {
case *rsa.PrivateKey:
signature, err := rsa.SignPKCS1v15(rand.Reader, p, ch, sighash)
if err != nil {
return false
}
s.Signature = unpackBase64(signature)
case *ecdsa.PrivateKey:
r1, s1, err := ecdsa.Sign(rand.Reader, p, sighash)
if err != nil {
return false
}
signature := r1.Bytes()
signature = append(signature, s1.Bytes()...)
s.Signature =unpackBase64(signature)
default:
// Not given the correct key
return false
}
switch p := k.(type) {
case *rsa.PrivateKey:
signature, err := rsa.SignPKCS1v15(rand.Reader, p, ch, sighash)
if err != nil {
return false
}
s.Signature = unpackBase64(signature)
case *ecdsa.PrivateKey:
r1, s1, err := ecdsa.Sign(rand.Reader, p, sighash)
if err != nil {
return false
}
signature := r1.Bytes()
signature = append(signature, s1.Bytes()...)
s.Signature = unpackBase64(signature)
default:
// Not given the correct key
return false
}
return true
}
@ -394,23 +394,23 @@ func (k *RR_DNSKEY) pubKeyRSA() *rsa.PublicKey {
// Extract the Curve public key from the Key record
func (k *RR_DNSKEY) pubKeyCurve() *ecdsa.PublicKey {
keybuf, err := packBase64([]byte(k.PublicKey))
if err != nil {
return nil
}
var c *elliptic.Curve
switch k.Algorithm {
case ECDSAP256SHA256:
c = elliptic.P256()
case ECDSAP384SHA384:
c = elliptic.P384()
}
x, y := c.Unmarshal(keybuf)
pubkey := new(ecdsa.PublicKey)
pubkey.X = x
pubkey.Y = y
pubkey.Curve = c
return pubkey
keybuf, err := packBase64([]byte(k.PublicKey))
if err != nil {
return nil
}
var c *elliptic.Curve
switch k.Algorithm {
case ECDSAP256SHA256:
c = elliptic.P256()
case ECDSAP384SHA384:
c = elliptic.P384()
}
x, y := c.Unmarshal(keybuf)
pubkey := new(ecdsa.PublicKey)
pubkey.X = x
pubkey.Y = y
pubkey.Curve = c
return pubkey
}
// Set the public key (the value E and N)
@ -426,12 +426,12 @@ func (k *RR_DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
// Set the public key for Elliptic Curves
func (k *RR_DNSKEY) setPublicKeyCurve(_X, _Y *big.Int) bool {
if _X == nil || _Y == nil {
return false
}
buf := curveToBuf(_X, _Y)
k.PublicKey = unpackBase64(buf)
return true
if _X == nil || _Y == nil {
return false
}
buf := curveToBuf(_X, _Y)
k.PublicKey = unpackBase64(buf)
return true
}
// Set the public key (the values E and N) for RSA
@ -455,9 +455,9 @@ func exponentToBuf(_E int) []byte {
// Set the public key for X and Y for Curve
// Experimental
func curveToBuf(_X, _Y *big.Int) []byte {
buf := _X.Bytes()
buf = append(buf, _Y.Bytes()...)
return buf
buf := _X.Bytes()
buf = append(buf, _Y.Bytes()...)
return buf
}
// return a saw signature data
@ -500,13 +500,13 @@ func rawSignatureData(rrset RRset, s *RR_RRSIG) (buf []byte) {
// Map for algorithm names.
var alg_str = map[uint8]string{
RSAMD5: "RSAMD5",
DH: "DH",
DSA: "DSA",
RSASHA1: "RSASHA1",
RSASHA256: "RSASHA256",
RSASHA512: "RSASHA512",
ECCGOST: "ECC-GOST",
ECDSAP256SHA256: "ECDSAP256SHA256",
ECDSAP384SHA384: "ECDSAP384SHA384",
RSAMD5: "RSAMD5",
DH: "DH",
DSA: "DSA",
RSASHA1: "RSASHA1",
RSASHA256: "RSASHA256",
RSASHA512: "RSASHA512",
ECCGOST: "ECC-GOST",
ECDSAP256SHA256: "ECDSAP256SHA256",
ECDSAP384SHA384: "ECDSAP384SHA384",
}

View File

@ -119,10 +119,10 @@ func TestSignVerify(t *testing.T) {
}
func TestKeyGen(t *testing.T) {
algs := []uint8{RSASHA256, ECDSAP256SHA256}
bits := []int{1024, 256}
algs := []uint8{RSASHA256, ECDSAP256SHA256}
bits := []int{1024, 256}
i := 0
i := 0
key := new(RR_DNSKEY)
key.Hdr.Name = "keygen.miek.nl."
key.Hdr.Rrtype = TypeDNSKEY
@ -130,13 +130,13 @@ func TestKeyGen(t *testing.T) {
key.Hdr.Ttl = 3600
key.Flags = 256
key.Protocol = 3
for _, v := range algs {
key.Algorithm = v
key.Generate(bits[i])
i++
t.Logf("%s\n", key)
}
//Really hard to figure out what to check here... Parse it back to a proper key?
for _, v := range algs {
key.Algorithm = v
key.Generate(bits[i])
i++
t.Logf("%s\n", key)
}
//Really hard to figure out what to check here... Parse it back to a proper key?
}
/*

200
keygen.go
View File

@ -2,12 +2,12 @@ package dns
import (
"os"
"io"
"io"
"big"
"strconv"
"crypto/rsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
)
@ -31,14 +31,14 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
if bits < 1024 || bits > 4096 {
return nil, ErrKeySize
}
case ECDSAP256SHA256:
if bits != 256 {
return nil, ErrKeySize
}
case ECDSAP384SHA384:
if bits != 384 {
return nil, ErrKeySize
}
case ECDSAP256SHA256:
if bits != 256 {
return nil, ErrKeySize
}
case ECDSAP384SHA384:
if bits != 384 {
return nil, ErrKeySize
}
}
switch r.Algorithm {
@ -47,22 +47,22 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
if err != nil {
return nil, err
}
r.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
r.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
return priv, nil
case ECDSAP256SHA256, ECDSAP384SHA384:
var c *elliptic.Curve
switch r.Algorithm {
case ECDSAP256SHA256:
c = elliptic.P256()
case ECDSAP384SHA384:
c = elliptic.P384()
}
priv, err := ecdsa.GenerateKey(c, rand.Reader)
if err != nil {
return nil, err
}
r.setPublicKeyCurve(priv.PublicKey.X, priv.PublicKey.Y)
return priv, nil
case ECDSAP256SHA256, ECDSAP384SHA384:
var c *elliptic.Curve
switch r.Algorithm {
case ECDSAP256SHA256:
c = elliptic.P256()
case ECDSAP384SHA384:
c = elliptic.P384()
}
priv, err := ecdsa.GenerateKey(c, rand.Reader)
if err != nil {
return nil, err
}
r.setPublicKeyCurve(priv.PublicKey.X, priv.PublicKey.Y)
return priv, nil
default:
return nil, ErrAlg
}
@ -106,81 +106,81 @@ func (r *RR_DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
"Exponent1: " + exponent1 + "\n" +
"Exponent2: " + exponent2 + "\n" +
"Coefficient: " + coefficient + "\n"
case *ecdsa.PrivateKey:
//
case *ecdsa.PrivateKey:
//
}
return
}
func (k *RR_DNSKEY) Read(q io.Reader) os.Error {
p := NewParser(q)
r := p.RR()
if r == nil {
return nil
}
if _, ok := r.(*RR_DNSKEY); !ok {
panic("did not read a DNSKEY")
}
k.Hdr = r.(*RR_DNSKEY).Hdr
k.Flags = r.(*RR_DNSKEY).Flags
k.Protocol = r.(*RR_DNSKEY).Protocol
k.Algorithm = r.(*RR_DNSKEY).Algorithm
k.PublicKey = r.(*RR_DNSKEY).PublicKey
return nil
p := NewParser(q)
r := p.RR()
if r == nil {
return nil
}
if _, ok := r.(*RR_DNSKEY); !ok {
panic("did not read a DNSKEY")
}
k.Hdr = r.(*RR_DNSKEY).Hdr
k.Flags = r.(*RR_DNSKEY).Flags
k.Protocol = r.(*RR_DNSKEY).Protocol
k.Algorithm = r.(*RR_DNSKEY).Algorithm
k.PublicKey = r.(*RR_DNSKEY).PublicKey
return nil
}
func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, os.Error) {
p := NewParser(q)
kv, _ := p.PrivateKey()
if _, ok := kv["private-key-format"]; !ok {
return nil, ErrPrivKey
}
if kv["private-key-format"] != "v1.2" && kv["private-key-format"] != "v1.3" {
return nil, ErrPrivKey
}
switch kv["algorithm"] {
case "RSAMD5", "RSASHA1", "RSASHA256", "RSASHA512":
return k.readPrivateKeyRSA(kv)
case "ECDSAP256SHA256", "ECDSAP384SHA384":
return k.readPrivateKeyECDSA(kv)
}
p := NewParser(q)
kv, _ := p.PrivateKey()
if _, ok := kv["private-key-format"]; !ok {
return nil, ErrPrivKey
}
if kv["private-key-format"] != "v1.2" && kv["private-key-format"] != "v1.3" {
return nil, ErrPrivKey
}
switch kv["algorithm"] {
case "RSAMD5", "RSASHA1", "RSASHA256", "RSASHA512":
return k.readPrivateKeyRSA(kv)
case "ECDSAP256SHA256", "ECDSAP384SHA384":
return k.readPrivateKeyECDSA(kv)
}
return nil, ErrPrivKey
}
// Read a private key (file) string and create a public key. Return the private key.
func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, os.Error) {
p := new(rsa.PrivateKey)
p.Primes = []*big.Int{nil,nil}
for k, v := range kv {
switch k {
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
switch k {
case "modulus":
p.PublicKey.N = big.NewInt(0)
p.PublicKey.N.SetBytes(v1)
case "publicexponent":
i := big.NewInt(0)
i.SetBytes(v1)
p.PublicKey.E = int(i.Int64()) // int64 should be large enough
case "privateexponent":
p.D = big.NewInt(0)
p.D.SetBytes(v1)
case "prime1":
p.Primes[0] = big.NewInt(0)
p.Primes[0].SetBytes(v1)
case "prime2":
p.Primes[1] = big.NewInt(0)
p.Primes[1].SetBytes(v1)
}
case "exponent1", "exponent2", "coefficient":
// not used in Go (yet)
case "created", "publish", "activate":
// not used in Go (yet)
}
p.Primes = []*big.Int{nil, nil}
for k, v := range kv {
switch k {
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
switch k {
case "modulus":
p.PublicKey.N = big.NewInt(0)
p.PublicKey.N.SetBytes(v1)
case "publicexponent":
i := big.NewInt(0)
i.SetBytes(v1)
p.PublicKey.E = int(i.Int64()) // int64 should be large enough
case "privateexponent":
p.D = big.NewInt(0)
p.D.SetBytes(v1)
case "prime1":
p.Primes[0] = big.NewInt(0)
p.Primes[0].SetBytes(v1)
case "prime2":
p.Primes[1] = big.NewInt(0)
p.Primes[1].SetBytes(v1)
}
case "exponent1", "exponent2", "coefficient":
// not used in Go (yet)
case "created", "publish", "activate":
// not used in Go (yet)
}
}
return p, nil
}
@ -188,18 +188,18 @@ func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, os.Erro
func (k *RR_DNSKEY) readPrivateKeyECDSA(kv map[string]string) (PrivateKey, os.Error) {
p := new(ecdsa.PrivateKey)
p.D = big.NewInt(0)
// Need to check if we have everything
for k, v := range kv {
switch k {
case "privatekey:":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
p.D.SetBytes(v1)
case "created:", "publish:", "activate:":
/* not used in Go (yet) */
}
}
// Need to check if we have everything
for k, v := range kv {
switch k {
case "privatekey:":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
p.D.SetBytes(v1)
case "created:", "publish:", "activate:":
/* not used in Go (yet) */
}
}
return p, nil
}

3963
kparse.go

File diff suppressed because it is too large Load Diff

10
msg.go
View File

@ -127,7 +127,7 @@ var Class_str = map[uint16]string{
ClassCSNET: "CS",
ClassCHAOS: "CH",
ClassHESIOD: "HS",
ClassNONE: "NONE",
ClassNONE: "NONE",
ClassANY: "ANY",
}
@ -363,8 +363,8 @@ func packStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool)
i := fv.Uint()
switch fv.Type().Kind() {
default:
//fmt.Fprintf(os.Stderr, "dns: unknown packing type %v\n", f.Type)
return len(msg), false
//fmt.Fprintf(os.Stderr, "dns: unknown packing type %v\n", f.Type)
return len(msg), false
case reflect.Uint8:
if off+1 > len(msg) {
//fmt.Fprintf(os.Stderr, "dns: overflow packing uint8")
@ -597,8 +597,8 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
switch fv.Type().Kind() {
default:
//fmt.Fprintf(os.Stderr, "dns: unknown packing type %v\n", f.Type)
return len(msg), false
//fmt.Fprintf(os.Stderr, "dns: unknown packing type %v\n", f.Type)
return len(msg), false
case reflect.Uint8:
if off+1 > len(msg) {

View File

@ -1,10 +1,10 @@
package dns
import (
"os"
"time"
"bufio"
"strings"
"os"
"time"
"bufio"
"strings"
"testing"
"crypto/rsa"
)
@ -27,21 +27,21 @@ Publish: 20110302104537
Activate: 20110302104537`
k := new(RR_DNSKEY)
k.Read(strings.NewReader(pub))
k.Read(strings.NewReader(pub))
p, err := k.ReadPrivateKey(strings.NewReader(priv))
if err != nil {
t.Logf("%v\n", err)
t.Fail()
}
if err != nil {
t.Logf("%v\n", err)
t.Fail()
}
switch priv := p.(type) {
case *rsa.PrivateKey:
if 65537 != priv.PublicKey.E {
t.Log("Exponenent should be 65537")
t.Fail()
}
default:
t.Logf("We should have read an RSA key: %v", priv)
t.Fail()
default:
t.Logf("We should have read an RSA key: %v", priv)
t.Fail()
}
if k.KeyTag() != 37350 {
t.Logf("%d %v\n", k.KeyTag(), k)
@ -68,113 +68,111 @@ Activate: 20110302104537`
sig.Algorithm = k.Algorithm
sig.Sign(p, []RR{soa})
if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
t.Log("Signature is not correct")
t.Logf("%v\n", sig)
t.Fail()
}
if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
t.Log("Signature is not correct")
t.Logf("%v\n", sig)
t.Fail()
}
}
func TestDotInName(t *testing.T) {
buf := make([]byte, 20)
packDomainName("aa\\.bb.nl.", buf, 0)
// index 3 must be a real dot
if buf[3] != '.' {
t.Log("Dot should be a real dot")
t.Fail()
}
// index 3 must be a real dot
if buf[3] != '.' {
t.Log("Dot should be a real dot")
t.Fail()
}
if buf[6] != 2 {
t.Log("This must have the value 2")
t.Fail()
}
dom, _, _ := unpackDomainName(buf, 0)
// printing it should yield the backspace again
if dom != "aa\\.bb.nl." {
t.Log("Dot should have been escaped: " + dom)
t.Fail()
}
if buf[6] != 2 {
t.Log("This must have the value 2")
t.Fail()
}
dom, _, _ := unpackDomainName(buf, 0)
// printing it should yield the backspace again
if dom != "aa\\.bb.nl." {
t.Log("Dot should have been escaped: " + dom)
t.Fail()
}
}
// Make this a decend test case. For now, good enough
// New style (Ragel) parsing
func TestParse(t *testing.T) {
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",
"miek.nl. A 127.0.0.1": "miek.nl.\t0\tCLASS0\tA\t127.0.0.1",
"miek.nl. IN AAAA ::1": "miek.nl.\t0\tIN\tAAAA\t::1",
"miek.nl. IN A 127.0.0.1": "miek.nl.\t0\tIN\tA\t127.0.0.1",
"miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ":
"miek.nl.\t0\tIN\tDNSKEY\t256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ",
"nlnetlabs.nl. 3175 IN DNSKEY 256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh":
"nlnetlabs.nl.\t3175\tIN\tDNSKEY\t256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh",
}
for test, result := range tests {
p := NewParser(strings.NewReader(test))
z, err := p.Zone()
if err != nil || z == nil{
t.Logf("Error of nil r %v %s\n", err, test)
t.Fail()
}
r := z.Pop().(RR)
if r.String() != result {
t.Logf("\"%s\" should be equal to\n\"%s\"\n", r, result)
t.Fail()
}
}
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",
"miek.nl. A 127.0.0.1": "miek.nl.\t0\tCLASS0\tA\t127.0.0.1",
"miek.nl. IN AAAA ::1": "miek.nl.\t0\tIN\tAAAA\t::1",
"miek.nl. IN A 127.0.0.1": "miek.nl.\t0\tIN\tA\t127.0.0.1",
"miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ": "miek.nl.\t0\tIN\tDNSKEY\t256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ",
"nlnetlabs.nl. 3175 IN DNSKEY 256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh": "nlnetlabs.nl.\t3175\tIN\tDNSKEY\t256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3cRCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcjY6RyVweh",
}
for test, result := range tests {
p := NewParser(strings.NewReader(test))
z, err := p.Zone()
if err != nil || z == nil {
t.Logf("Error of nil r %v %s\n", err, test)
t.Fail()
}
r := z.Pop().(RR)
if r.String() != result {
t.Logf("\"%s\" should be equal to\n\"%s\"\n", r, result)
t.Fail()
}
}
}
func TestSetString(t *testing.T) {
a := NewRR("miek.nl. IN A 127.0.0.1")
if a.String() != "miek.nl.\t0\tIN\tA\t127.0.0.1" {
t.Log(a.String(), "!= miek.nl. IN A 127.0.0.1")
t.Fail()
}
b := NewRR("miek.nl. IN AAAA ::1")
if b.String() != "miek.nl.\t0\tIN\tAAAA\t::1" {
t.Log(b.String(), "!= miek.nl. IN AAAA ::1")
t.Fail()
}
c := NewRR("miek.nl. IN MX 10 miek.nl.")
if c.String() != "miek.nl.\t0\tIN\tMX\t10 miek.nl." {
t.Log(c.String(), "!= miek.nl. IN MX 10 miek.nl.")
t.Fail()
}
d := NewRR("miek.nl. IN NS ns1.miek.nl")
if d.String() != "miek.nl.\t0\tIN\tNS\tns1.miek.nl" {
t.Log(d.String(), "!= miek.nl. IN NS ns1.miek.nl")
t.Fail()
}
a := NewRR("miek.nl. IN A 127.0.0.1")
if a.String() != "miek.nl.\t0\tIN\tA\t127.0.0.1" {
t.Log(a.String(), "!= miek.nl. IN A 127.0.0.1")
t.Fail()
}
b := NewRR("miek.nl. IN AAAA ::1")
if b.String() != "miek.nl.\t0\tIN\tAAAA\t::1" {
t.Log(b.String(), "!= miek.nl. IN AAAA ::1")
t.Fail()
}
c := NewRR("miek.nl. IN MX 10 miek.nl.")
if c.String() != "miek.nl.\t0\tIN\tMX\t10 miek.nl." {
t.Log(c.String(), "!= miek.nl. IN MX 10 miek.nl.")
t.Fail()
}
d := NewRR("miek.nl. IN NS ns1.miek.nl")
if d.String() != "miek.nl.\t0\tIN\tNS\tns1.miek.nl" {
t.Log(d.String(), "!= miek.nl. IN NS ns1.miek.nl")
t.Fail()
}
}
func BenchmarkZoneParsing(b *testing.B) {
file, err := os.Open("miek.nl")
defer file.Close()
if err != nil {
return
}
p := NewParser(bufio.NewReader(file))
// Don't care about errors (there shouldn't be any)
p.Zone()
file, err := os.Open("miek.nl")
defer file.Close()
if err != nil {
return
}
p := NewParser(bufio.NewReader(file))
// Don't care about errors (there shouldn't be any)
p.Zone()
}
func TestZoneParsing(t *testing.T) {
file, err := os.Open("miek.nl")
defer file.Close()
if err != nil {
return
}
p := NewParser(bufio.NewReader(file))
file, err := os.Open("miek.nl")
defer file.Close()
if err != nil {
return
}
p := NewParser(bufio.NewReader(file))
// Don't care about errors (there shouldn't be any)
start := time.Nanoseconds()
z, err := p.Zone()
if err != nil {
t.Logf("error %v\n", err.String())
t.Fail()
}
delta := time.Nanoseconds() - start
t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", z.Len()-1, float32(delta)/1e9, float32(z.Len()-1)/(float32(delta)/1e9))
// Don't care about errors (there shouldn't be any)
start := time.Nanoseconds()
z, err := p.Zone()
if err != nil {
t.Logf("error %v\n", err.String())
t.Fail()
}
delta := time.Nanoseconds() - start
t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", z.Len()-1, float32(delta)/1e9, float32(z.Len()-1)/(float32(delta)/1e9))
}

View File

@ -23,7 +23,7 @@ type Handler interface {
type ResponseWriter interface {
// RemoteAddr returns the net.Addr of the client that sent the current request.
RemoteAddr() net.Addr
// Write a reply back to the client.
// Write a reply back to the client.
Write([]byte) (int, os.Error)
}
@ -164,12 +164,12 @@ func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
// A Server defines parameters for running an DNS server.
// Note how much it starts to look like 'Client struct'
type Server struct {
Addr string // address to listen on, ":dns" if empty
Net string // if "tcp" it will invoke a TCP listener, otherwise an UDP one
Handler Handler // handler to invoke, dns.DefaultServeMux if nil
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
Addr string // address to listen on, ":dns" if empty
Net string // if "tcp" it will invoke a TCP listener, otherwise an UDP one
Handler Handler // handler to invoke, dns.DefaultServeMux if nil
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
}
// ...
@ -333,7 +333,7 @@ func (w *response) Write(data []byte) (n int, err os.Error) {
case w.conn._UDP != nil:
n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr)
if err != nil {
println(err.String())
println(err.String())
return 0, err
}
case w.conn._TCP != nil:

View File

@ -28,19 +28,19 @@ func TestServing(t *testing.T) {
}
func BenchmarkServing(b *testing.B) {
b.StopTimer()
// Again start a server
b.StopTimer()
// Again start a server
HandleFunc("miek.nl.", HelloServer)
go func() {
ListenAndServe("127.0.0.1:8053", "udp", nil)
ListenAndServe("127.0.0.1:8053", "udp", nil)
}()
c := NewClient()
m := new(Msg)
m.SetQuestion("miek.nl", TypeSOA)
c := NewClient()
m := new(Msg)
m.SetQuestion("miek.nl", TypeSOA)
b.StartTimer()
for i := 0; i < b.N; i++ {
c.Exchange(m, "127.0.0.1:8053")
}
b.StartTimer()
for i := 0; i < b.N; i++ {
c.Exchange(m, "127.0.0.1:8053")
}
}

View File

@ -149,11 +149,11 @@ func (q *Question) String() string {
// NewRR returns the last RR contained in s.
func NewRR(s string) RR {
p := NewParser(strings.NewReader(s))
x := p.RR()
x := p.RR()
if x == nil {
return nil
}
return x
return x
}
type RR_CNAME struct {

12
zone.go
View File

@ -5,30 +5,30 @@
package dns
import (
"container/vector"
"container/vector"
)
// Zone implements the concept of RFC 1035 master zone files.
type Zone struct {
v vector.Vector
v vector.Vector
}
// Add a new RR to the zone.
func (z *Zone) Push(r RR) {
z.v.Push(r)
z.v.Push(r)
}
// Remove a RR from the zone.
func (z *Zone) Pop() RR {
return z.v.Pop().(RR)
return z.v.Pop().(RR)
}
// Return the RR at index i of zone.
func (z *Zone) At(i int) RR {
return z.v.At(i).(RR)
return z.v.At(i).(RR)
}
// The number of RRs in zone.
func (z *Zone) Len() int {
return z.v.Len()
return z.v.Len()
}

5645
zparse.go

File diff suppressed because it is too large Load Diff