Split the package in multiple packages

dns - the standard rrtypes and such
    dnssec - validation, keytag calculation, etc
    resolver - for talking to servers
This commit is contained in:
Miek Gieben 2010-12-30 13:42:52 +01:00
parent bc624181dc
commit 15dd65171b
19 changed files with 311 additions and 271 deletions

View File

@ -1,20 +1,28 @@
# Copyright 2009 The Go Authors. All rights reserved. # Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style # Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file. # license that can be found in the LICENSE file.
.PHONY: dnssec resolver examples
include $(GOROOT)/src/Make.inc include $(GOROOT)/src/Make.inc
TARG=dns TARG=dns
GOFILES=\ GOFILES=\
dns.go\
msg.go\ msg.go\
resolver.go \
types.go\ types.go\
edns.go\ edns.go\
dnssec.go\
include $(GOROOT)/src/Make.pkg include $(GOROOT)/src/Make.pkg
.PHONY: examples all: package
gomake -C dnssec package
gomake -C resolver package
examples: install: $(INSTALLFILES)
(cd examples; make) gomake -C dnssec install
gomake -C resolver install
dnstest:
gotest
gomake -C dnssec test
gomake -C resolver test

107
dns.go Normal file
View File

@ -0,0 +1,107 @@
// 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.
// Extended and bugfixes by Miek Gieben
// Package dns implements a full featured interface to the DNS.
// Supported RFCs and features include:
// * 1034/1035
// * 2671 - EDNS
// * 4033/4034/4035 - DNSSEC + validation functions
// * 1982 - Serial Arithmetic
// * IP6 support
// The package allows full control over what is send out to the DNS.
//
// Basic usage pattern for creating new Resource Record:
//
// r := new(RR_TXT)
// r.TXT = "This is the content of the TXT record"
// r.Hdr = RR_Header{Name: "a.miek.nl", Rrtype: TypeTXT, Class: ClassINET, Ttl: 3600}
//
package dns
import ( "strconv")
const Year68 = 2 << (32 - 1)
type RR interface {
Header() *RR_Header
String() string
}
// An RRset is a slice of RRs.
type RRset []RR
func (r RRset) Len() int { return len(r) }
func (r RRset) Less(i, j int) bool { return r[i].Header().Name < r[j].Header().Name }
func (r RRset) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
// DNS resource records.
// There are many types of messages,
// but they all share the same header.
type RR_Header struct {
Name string "domain-name"
Rrtype uint16
Class uint16
Ttl uint32
Rdlength uint16 // length of data after header
}
func (h *RR_Header) Header() *RR_Header {
return h
}
func (h *RR_Header) String() string {
var s string
if h.Rrtype == TypeOPT {
s = ";"
// and maybe other things
}
if len(h.Name) == 0 {
s += ".\t"
} else {
s += h.Name + "\t"
}
s = s + strconv.Itoa(int(h.Ttl)) + "\t"
s = s + class_str[h.Class] + "\t"
s = s + rr_str[h.Rrtype] + "\t"
return s
}
// Or expose the pack/unpack functions??
// Return the rdata of the RR in wireform.
func WireRdata(r RR) ([]byte, bool) {
buf := make([]byte, 4096) // Too large, need to FIX TODO(mg)
off1, ok := packRR(r, buf, 0)
if !ok {
return nil, false
}
start := off1 - int(r.Header().Rdlength)
end := start + int(r.Header().Rdlength)
buf = buf[start:end]
return buf, true
}
// Return the wiredata of a domainname (sans compressions)
func WireDomainName(s string) ([]byte, bool) {
buf := make([]byte, 255)
off, ok := packDomainName(s, buf, 0)
if !ok {
return nil, ok
}
buf = buf[:off]
return buf, ok
}
func WireRR(r RR) ([]byte, bool) {
buf := make([]byte, 4096)
off, ok := packRR(r, buf, 0)
if !ok {
return nil, false
}
buf = buf[:off]
return buf, ok
}

11
dnssec/Makefile Normal file
View File

@ -0,0 +1,11 @@
# 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.
include $(GOROOT)/src/Make.inc
TARG=dns/dnssec
GOFILES=\
dnssec.go\
include $(GOROOT)/src/Make.pkg

View File

@ -1,4 +1,4 @@
package dns package dnssec
import ( import (
"crypto/sha1" "crypto/sha1"
@ -13,47 +13,46 @@ import (
"strings" "strings"
"fmt" //tmp "fmt" //tmp
"os" //tmp "os" //tmp
"dns"
) )
// DNSSEC encryption algorithm codes.
const ( const (
// RFC1982 serial arithmetic // DNSSEC algorithms
year68 = 2 << (32 - 1) AlgRSAMD5 = 1
AlgDH = 2
AlgDSA = 3
AlgECC = 4
AlgRSASHA1 = 5
AlgRSASHA256 = 8
AlgRSASHA512 = 10
AlgECCGOST = 12
) )
// An RRset is just a bunch a RRs. No restrictions // DNSSEC hashing codes.
type RRset []RR const (
HashSHA1 = iota
func (r RRset) Len() int { return len(r) } HashSHA256
func (r RRset) Less(i, j int) bool { return r[i].Header().Name < r[j].Header().Name } HashGOST94
func (r RRset) Swap(i, j int) { r[i], r[j] = r[j], r[i] } )
// Convert an DNSKEY record to a DS record. // Convert an DNSKEY record to a DS record.
func (k *RR_DNSKEY) ToDS(hash int) *RR_DS { func ToDS(k *dns.RR_DNSKEY, hash int) *dns.RR_DS {
ds := new(RR_DS) ds := new(dns.RR_DS)
ds.Hdr.Name = k.Hdr.Name ds.Hdr.Name = k.Hdr.Name
ds.Hdr.Class = k.Hdr.Class ds.Hdr.Class = k.Hdr.Class
ds.Hdr.Ttl = k.Hdr.Ttl ds.Hdr.Ttl = k.Hdr.Ttl
ds.Hdr.Rrtype = TypeDS
ds.KeyTag = k.KeyTag()
ds.Algorithm = k.Algorithm ds.Algorithm = k.Algorithm
ds.DigestType = uint8(hash) ds.DigestType = uint8(hash)
ds.KeyTag = KeyTag(k)
// Generic function that gives back a buffer with the rdata?? TODO(MG) wire, ok := dns.WireRdata(k)
// Find the rdata portion for the key (again)
// (keytag does this too)
buf := make([]byte, 4096)
off1, ok := packRR(k, buf, 0)
if !ok { if !ok {
return nil return nil
} }
start := off1 - int(k.Header().Rdlength) owner,ok1 := dns.WireDomainName(k.Hdr.Name)
end := start + int(k.Header().Rdlength) if !ok1 {
// buf[start:end] is the rdata of the key
buf = buf[start:end]
owner := make([]byte, 255)
off1, ok = packDomainName(k.Hdr.Name, owner, 0)
if !ok {
return nil return nil
} }
/* /*
@ -62,9 +61,8 @@ func (k *RR_DNSKEY) ToDS(hash int) *RR_DS {
* "|" denotes concatenation * "|" denotes concatenation
* DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. * DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
*/ */
owner = owner[:off1]
// digest buffer // digest buffer
digest := append(owner, buf...) digest := append(owner, wire...) // another copy TODO(mg)
switch hash { switch hash {
case HashSHA1: case HashSHA1:
@ -85,7 +83,7 @@ func (k *RR_DNSKEY) ToDS(hash int) *RR_DS {
} }
// Calculate the keytag of the DNSKEY. // Calculate the keytag of the DNSKEY.
func (k *RR_DNSKEY) KeyTag() uint16 { func KeyTag(k *dns.RR_DNSKEY) uint16 {
var keytag int var keytag int
switch k.Algorithm { switch k.Algorithm {
case AlgRSAMD5: case AlgRSAMD5:
@ -95,7 +93,7 @@ func (k *RR_DNSKEY) KeyTag() uint16 {
// Might encode header length too, so that // Might encode header length too, so that
// we dont need to pack/unpack all the time // we dont need to pack/unpack all the time
// Or a shadow structure, with the wiredata and header // Or a shadow structure, with the wiredata and header
wire, ok := wireRdata(k) wire, ok := dns.WireRdata(k)
if !ok { if !ok {
return 0 return 0
} }
@ -114,11 +112,11 @@ func (k *RR_DNSKEY) KeyTag() uint16 {
// Validate an rrset with the signature and key. This is the // Validate an rrset with the signature and key. This is the
// cryptographic test, the validity period most be check separately. // cryptographic test, the validity period most be check separately.
func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) bool { func Verify(s *dns.RR_RRSIG, k *dns.RR_DNSKEY, rrset dns.RRset) bool {
// Frist the easy checks // Frist the easy checks
if s.KeyTag != k.KeyTag() { if s.KeyTag != KeyTag(k) {
println(s.KeyTag) println(s.KeyTag)
println(k.KeyTag()) println(KeyTag(k))
return false return false
} }
if s.Hdr.Class != k.Hdr.Class { if s.Hdr.Class != k.Hdr.Class {
@ -149,8 +147,8 @@ func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) bool {
signeddata := make([]byte, 10240) // 10 Kb?? signeddata := make([]byte, 10240) // 10 Kb??
// Copy the sig, except the rrsig data // Copy the sig, except the rrsig data
// Can this be done easier? TODO(mg) // Can this be done easier? TODO(mg)
s1 := &RR_RRSIG{s.Hdr, s.TypeCovered, s.Algorithm, s.Labels, s.OrigTtl, s.Expiration, s.Inception, s.KeyTag, s.SignerName, ""} s1 := &dns.RR_RRSIG{s.Hdr, s.TypeCovered, s.Algorithm, s.Labels, s.OrigTtl, s.Expiration, s.Inception, s.KeyTag, s.SignerName, ""}
buf, ok := wireRdata(s1) buf, ok := dns.WireRdata(s1)
if !ok { if !ok {
return false return false
} }
@ -165,10 +163,10 @@ func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) bool {
h.Name = strings.ToLower(h.Name) h.Name = strings.ToLower(h.Name)
// 6.2. Canonical RR Form. (3) - domain rdata to lowercaser // 6.2. Canonical RR Form. (3) - domain rdata to lowercaser
switch h.Rrtype { switch h.Rrtype {
case TypeNS, TypeCNAME, TypeSOA, TypeMB, TypeMG, TypeMR, TypePTR: case dns.TypeNS, dns.TypeCNAME, dns.TypeSOA, dns.TypeMB, dns.TypeMG, dns.TypeMR, dns.TypePTR:
case TypeHINFO, TypeMINFO, TypeMX /* TypeRP, TypeAFSDB, TypeRT */ : case dns.TypeHINFO, dns.TypeMINFO, dns.TypeMX /* dns.TypeRP, dns.TypeAFSDB, dns.TypeRT */ :
case TypeSIG /* TypePX, TypeNXT /* TypeNAPTR, TypeKX */ : case dns.TypeSIG /* dns.TypePX, dns.TypeNXT /* dns.TypeNAPTR, dns.TypeKX */ :
case TypeSRV, /* TypeDNAME, TypeA6 */ TypeRRSIG, TypeNSEC: case dns.TypeSRV, /* dns.TypeDNAME, dns.TypeA6 */ dns.TypeRRSIG, dns.TypeNSEC:
/* do something */ /* do something */
// lower case the strings rdata // // lower case the strings rdata //
@ -177,10 +175,11 @@ func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) bool {
// 6.2. Canonical RR Form. (5) - origTTL // 6.2. Canonical RR Form. (5) - origTTL
ttl := h.Ttl ttl := h.Ttl
h.Ttl = s.OrigTtl h.Ttl = s.OrigTtl
off, ok = packRR(r, signeddata, off) wire, ok1 := dns.WireRR(r)
h.Ttl = ttl // restore the order in the universe h.Ttl = ttl // restore the order in the universe
h.Name = name h.Name = name
if !ok { wire = wire // fix this
if !ok1 {
println("Failure to pack") println("Failure to pack")
return false return false
} }
@ -223,22 +222,22 @@ func (s *RR_RRSIG) Verify(rrset RRset, k *RR_DNSKEY) bool {
} }
// Using RFC1982 calculate if a signature period is valid // Using RFC1982 calculate if a signature period is valid
func (s *RR_RRSIG) PeriodOK() bool { func PeriodOK(s *dns.RR_RRSIG) bool {
utc := time.UTC().Seconds() utc := time.UTC().Seconds()
modi := (int64(s.Inception) - utc) / year68 modi := (int64(s.Inception) - utc) / dns.Year68
mode := (int64(s.Expiration) - utc) / year68 mode := (int64(s.Expiration) - utc) / dns.Year68
ti := int64(s.Inception) + (modi * year68) ti := int64(s.Inception) + (modi * dns.Year68)
te := int64(s.Expiration) + (mode * year68) te := int64(s.Expiration) + (mode * dns.Year68)
return ti <= utc && utc <= te return ti <= utc && utc <= te
} }
// Translate the RRSIG's incep. and expir. time to the correct date. // Map for algorithm names.
// Taking into account serial arithmetic (RFC 1982) var alg_str = map[uint8]string{
func timeToDate(t uint32) string { AlgRSAMD5: "RSAMD5",
utc := time.UTC().Seconds() AlgDH: "DH",
mod := (int64(t) - utc) / year68 AlgDSA: "DSA",
AlgRSASHA1: "RSASHA1",
// If needed assume wrap around(s) AlgRSASHA256: "RSASHA256",
ti := time.SecondsToUTC(int64(t) + (mod * year68)) // abs()? TODO AlgRSASHA512: "RSASHA512",
return ti.Format("20060102030405") AlgECCGOST: "ECC-GOST",
} }

View File

@ -1,15 +1,16 @@
package dns package dnssec
import ( import (
"testing" "testing"
"fmt" "fmt"
"os" "os"
"dns"
) )
func TestSecure(t *testing.T) { func TestSecure(t *testing.T) {
// once this was valid // once this was valid
soa := new(RR_SOA) soa := new(dns.RR_SOA)
soa.Hdr = RR_Header{"Miek.nl.", TypeSOA, ClassINET, 875, 0} soa.Hdr = dns.RR_Header{"Miek.nl.", dns.TypeSOA, dns.ClassINET, 875, 0}
soa.Ns = "open.nlnetlabs.nl." soa.Ns = "open.nlnetlabs.nl."
soa.Mbox = "miekg.atoom.net." soa.Mbox = "miekg.atoom.net."
soa.Serial = 1293513905 soa.Serial = 1293513905
@ -18,9 +19,9 @@ func TestSecure(t *testing.T) {
soa.Expire = 604800 soa.Expire = 604800
soa.Minttl = 86400 soa.Minttl = 86400
sig := new(RR_RRSIG) sig := new(dns.RR_RRSIG)
sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} sig.Hdr = dns.RR_Header{"miek.nl.", dns.TypeRRSIG, dns.ClassINET, 14400, 0}
sig.TypeCovered = TypeSOA sig.TypeCovered = dns.TypeSOA
sig.Algorithm = AlgRSASHA256 sig.Algorithm = AlgRSASHA256
sig.Labels = 2 sig.Labels = 2
sig.Expiration = 1296098705 // date '+%s' -d"2011-01-27 04:25:05 sig.Expiration = 1296098705 // date '+%s' -d"2011-01-27 04:25:05
@ -30,10 +31,9 @@ func TestSecure(t *testing.T) {
sig.SignerName = "miek.nl." sig.SignerName = "miek.nl."
sig.Signature = "kLq/5oFy3Sh5ZxPGFMCyHq8MtN6E17R1Ln9+bJ2Q76YYAxFE8Xlie33A1GFctH2uhzRzJKuP/JSjUkrvGk2rjBm32z9zXtZsKx/4yV0da2nLRm44NOmX6gsP4Yia8mdqPUajjkyLzAzU2bevtesJm0Z65AcmPdq3tUZODdRAcng=" sig.Signature = "kLq/5oFy3Sh5ZxPGFMCyHq8MtN6E17R1Ln9+bJ2Q76YYAxFE8Xlie33A1GFctH2uhzRzJKuP/JSjUkrvGk2rjBm32z9zXtZsKx/4yV0da2nLRm44NOmX6gsP4Yia8mdqPUajjkyLzAzU2bevtesJm0Z65AcmPdq3tUZODdRAcng="
key := new(RR_DNSKEY) key := new(dns.RR_DNSKEY)
key.Hdr.Name = "miek.nl." key.Hdr.Name = "miek.nl."
key.Hdr.Rrtype = TypeDNSKEY key.Hdr.Class = dns.ClassINET
key.Hdr.Class = ClassINET
key.Hdr.Ttl = 14400 key.Hdr.Ttl = 14400
key.Flags = 256 key.Flags = 256
key.Protocol = 3 key.Protocol = 3
@ -42,7 +42,7 @@ func TestSecure(t *testing.T) {
fmt.Fprintf(os.Stderr, "%v\n%v\n", sig, soa) fmt.Fprintf(os.Stderr, "%v\n%v\n", sig, soa)
// It should validate, at least this month dec 2010 // It should validate, at least this month dec 2010
if ! sig.Verify([]RR{soa}, key) { if ! Verify(sig, key, []dns.RR{soa}) {
t.Log("Failure to validate") t.Log("Failure to validate")
t.Fail() t.Fail()
} }

View File

@ -1,22 +1,23 @@
package dns package dnssec
import ( import (
"testing" "testing"
"strings" "strings"
"dns"
) )
func TestKeyToDS(t *testing.T) { func TestKeyToDS(t *testing.T) {
key := new(RR_DNSKEY) key := new(dns.RR_DNSKEY)
key.Hdr.Name = "miek.nl" key.Hdr.Name = "miek.nl"
key.Hdr.Rrtype = TypeDNSKEY key.Hdr.Rrtype = dns.TypeDNSKEY
key.Hdr.Class = ClassINET key.Hdr.Class = dns.ClassINET
key.Hdr.Ttl = 3600 key.Hdr.Ttl = 3600
key.Flags = 256 key.Flags = 256
key.Protocol = 3 key.Protocol = 3
key.Algorithm = AlgRSASHA256 key.Algorithm = AlgRSASHA256
key.PubKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" key.PubKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
ds := key.ToDS(HashSHA1) ds := ToDS(key, HashSHA1)
if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" { if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" {
t.Logf("Wrong DS digest for Sha1\n%v\n", ds) t.Logf("Wrong DS digest for Sha1\n%v\n", ds)
t.Fail() t.Fail()

View File

@ -1,21 +1,22 @@
package dns package dnssec
import ( import (
"testing" "testing"
"dns"
) )
func TestTag(t *testing.T) { func TestTag(t *testing.T) {
key := new(RR_DNSKEY) key := new(dns.RR_DNSKEY)
key.Hdr.Name = "miek.nl" key.Hdr.Name = "miek.nl"
key.Hdr.Rrtype = TypeDNSKEY key.Hdr.Rrtype = dns.TypeDNSKEY
key.Hdr.Class = ClassINET key.Hdr.Class = dns.ClassINET
key.Hdr.Ttl = 3600 key.Hdr.Ttl = 3600
key.Flags = 256 key.Flags = 256
key.Protocol = 3 key.Protocol = 3
key.Algorithm = AlgRSASHA256 key.Algorithm = AlgRSASHA256
key.PubKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" key.PubKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
tag := key.KeyTag() tag := KeyTag(key)
if tag != 12051 { if tag != 12051 {
t.Logf("%v\n", key) t.Logf("%v\n", key)
t.Logf("Wrong key tag: %d\n", tag) t.Logf("Wrong key tag: %d\n", tag)

View File

@ -1,16 +1,16 @@
package dns package dnssec
import ( import (
"dns"
"testing" "testing"
) )
func TestSignature(t *testing.T) { func TestSignature(t *testing.T) {
sig := new(RR_RRSIG) sig := new(dns.RR_RRSIG)
sig.Hdr.Name = "miek.nl." sig.Hdr.Name = "miek.nl."
sig.Hdr.Rrtype = TypeRRSIG sig.Hdr.Class = dns.ClassINET
sig.Hdr.Class = ClassINET
sig.Hdr.Ttl = 3600 sig.Hdr.Ttl = 3600
sig.TypeCovered = TypeDNSKEY sig.TypeCovered = dns.TypeDNSKEY
sig.Algorithm = AlgRSASHA1 sig.Algorithm = AlgRSASHA1
sig.Labels = 2 sig.Labels = 2
sig.OrigTtl = 4000 sig.OrigTtl = 4000
@ -21,14 +21,14 @@ func TestSignature(t *testing.T) {
sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ" sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
// Should not be valid // Should not be valid
if sig.PeriodOK() { if PeriodOK(sig) {
t.Log("Should not be valid") t.Log("Should not be valid")
t.Fail() t.Fail()
} }
sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980 sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980
sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100 sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100
if ! sig.PeriodOK() { if ! PeriodOK(sig) {
t.Log("Should be valid") t.Log("Should be valid")
t.Fail() t.Fail()
} }

View File

@ -8,7 +8,7 @@ import (
func TestEDNS_RR(t *testing.T) { func TestEDNS_RR(t *testing.T) {
edns := new(RR_OPT) edns := new(RR_OPT)
edns.Hdr.Name = "." // must . be for edns edns.Hdr.Name = "." // must . be for edns
edns.Hdr.Rrtype = TypeOPT edns.Hdr.Rrtype = TypeOPT
edns.Hdr.Class = ClassINET edns.Hdr.Class = ClassINET
edns.Hdr.Ttl = 3600 edns.Hdr.Ttl = 3600
edns.Option = make([]Option, 1) edns.Option = make([]Option, 1)

View File

@ -5,18 +5,19 @@ package main
// (c) Miek Gieben - 2011 // (c) Miek Gieben - 2011
import ( import (
"dns" "dns"
"dns/resolver"
"os" "os"
"fmt" "fmt"
"net" "net"
) )
func main() { func main() {
r := new(dns.Resolver) r := new(resolver.Resolver)
qr := dns.NewQuerier(r) qr := resolver.NewQuerier(r)
r.Servers = []string{"127.0.0.1"} r.Servers = []string{"127.0.0.1"}
r.Timeout = 2 r.Timeout = 2
r.Attempts = 1 r.Attempts = 1
var in dns.DnsMsg var in resolver.DnsMsg
if len(os.Args) != 2 { if len(os.Args) != 2 {
fmt.Printf("%s NAMESERVER\n", os.Args[0]) fmt.Printf("%s NAMESERVER\n", os.Args[0])
@ -29,13 +30,13 @@ func main() {
// set the resolver to query the NS directly // set the resolver to query the NS directly
r.Servers = []string{a.String()} r.Servers = []string{a.String()}
m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS} m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS}
qr <- dns.DnsMsg{m, nil} qr <- resolver.DnsMsg{m, nil}
in = <-qr in = <-qr
if in.Dns != nil && in.Dns.Answer != nil { if in.Dns != nil && in.Dns.Answer != nil {
fmt.Printf("%v\n", in.Dns.Answer[0]) fmt.Printf("%v\n", in.Dns.Answer[0])
} }
m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS} m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS}
qr <- dns.DnsMsg{m, nil} qr <- resolver.DnsMsg{m, nil}
in = <-qr in = <-qr
if in.Dns != nil && in.Dns.Answer != nil { if in.Dns != nil && in.Dns.Answer != nil {
fmt.Printf("%v\n", in.Dns.Answer[0]) fmt.Printf("%v\n", in.Dns.Answer[0])
@ -43,18 +44,18 @@ func main() {
} }
// Stop the resolver, send it a null mesg // Stop the resolver, send it a null mesg
qr <- dns.DnsMsg{nil, nil} qr <- resolver.DnsMsg{nil, nil}
<-qr <-qr
} }
func addresses(qr chan dns.DnsMsg, name string) []net.IP { func addresses(qr chan resolver.DnsMsg, name string) []net.IP {
m := new(dns.Msg) m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true //only set this bit m.MsgHdr.Recursion_desired = true //only set this bit
m.Question = make([]dns.Question, 1) m.Question = make([]dns.Question, 1)
var ips []net.IP var ips []net.IP
m.Question[0] = dns.Question{os.Args[1], dns.TypeA, dns.ClassINET} m.Question[0] = dns.Question{os.Args[1], dns.TypeA, dns.ClassINET}
qr <- dns.DnsMsg{m, nil} qr <- resolver.DnsMsg{m, nil}
in := <-qr in := <-qr
if in.Dns.Rcode != dns.RcodeSuccess { if in.Dns.Rcode != dns.RcodeSuccess {
@ -65,7 +66,7 @@ func addresses(qr chan dns.DnsMsg, name string) []net.IP {
ips = append(ips, a.(*dns.RR_A).A) ips = append(ips, a.(*dns.RR_A).A)
} }
m.Question[0] = dns.Question{os.Args[1], dns.TypeAAAA, dns.ClassINET} m.Question[0] = dns.Question{os.Args[1], dns.TypeAAAA, dns.ClassINET}
qr <- dns.DnsMsg{m, nil} qr <- resolver.DnsMsg{m, nil}
in = <-qr in = <-qr
if in.Dns.Rcode != dns.RcodeSuccess { if in.Dns.Rcode != dns.RcodeSuccess {

View File

@ -2,6 +2,8 @@ package main
import ( import (
"dns" "dns"
"dns/dnssec"
"dns/resolver"
"fmt" "fmt"
) )
@ -15,7 +17,7 @@ func main() {
key.Hdr.Ttl = 3600 key.Hdr.Ttl = 3600
key.Flags = 257 key.Flags = 257
key.Protocol = 3 key.Protocol = 3
key.Algorithm = dns.AlgRSASHA1 key.Algorithm = dnssec.AlgRSASHA1
key.PubKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ" key.PubKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ"
sig := new(dns.RR_RRSIG) sig := new(dns.RR_RRSIG)
@ -24,18 +26,18 @@ func main() {
sig.Hdr.Class = dns.ClassINET sig.Hdr.Class = dns.ClassINET
sig.Hdr.Ttl = 3600 sig.Hdr.Ttl = 3600
sig.TypeCovered = dns.TypeDNSKEY sig.TypeCovered = dns.TypeDNSKEY
sig.Algorithm = dns.AlgRSASHA1 sig.Algorithm = dnssec.AlgRSASHA1
sig.OrigTtl = 4000 sig.OrigTtl = 4000
sig.Expiration = 1000 sig.Expiration = 1000
sig.Inception = 800 sig.Inception = 800
sig.KeyTag = 34641 sig.KeyTag = 34641
sig.SignerName = "miek.nl." sig.SignerName = "miek.nl."
sig.Sig = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ" sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ"
fmt.Printf("%v", sig) fmt.Printf("%v", sig)
res := new(dns.Resolver) res := new(resolver.Resolver)
ch := dns.NewQuerier(res) ch := resolver.NewQuerier(res)
// configure the resolver // configure the resolver
res.Servers = []string{"192.168.1.2"} res.Servers = []string{"192.168.1.2"}
@ -49,20 +51,20 @@ func main() {
m.Question = make([]dns.Question, 1) m.Question = make([]dns.Question, 1)
m.Question[0] = dns.Question{"miek.nl", dns.TypeDS, dns.ClassINET} m.Question[0] = dns.Question{"miek.nl", dns.TypeDS, dns.ClassINET}
ch <- dns.DnsMsg{m, nil} ch <- resolver.DnsMsg{m, nil}
in := <-ch in := <-ch
fmt.Printf("%v\n", in.Dns) fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"www.nlnetlabs.nl", dns.TypeRRSIG, dns.ClassINET} m.Question[0] = dns.Question{"www.nlnetlabs.nl", dns.TypeRRSIG, dns.ClassINET}
ch <- dns.DnsMsg{m, nil} ch <- resolver.DnsMsg{m, nil}
in = <-ch in = <-ch
fmt.Printf("%v\n", in.Dns) fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"xxxx.nlnetlabs.nl", dns.TypeDNSKEY, dns.ClassINET} m.Question[0] = dns.Question{"xxxx.nlnetlabs.nl", dns.TypeDNSKEY, dns.ClassINET}
ch <- dns.DnsMsg{m, nil} ch <- resolver.DnsMsg{m, nil}
in = <-ch in = <-ch
fmt.Printf("%v\n", in.Dns) fmt.Printf("%v\n", in.Dns)
ch <- dns.DnsMsg{nil, nil} ch <- resolver.DnsMsg{nil, nil}
<-ch <-ch
} }

View File

@ -4,13 +4,14 @@ package main
// (c) Miek Gieben - 2011 // (c) Miek Gieben - 2011
import ( import (
"dns" "dns"
"dns/resolver"
"os" "os"
"fmt" "fmt"
) )
func main() { func main() {
r := new(dns.Resolver) r := new(resolver.Resolver)
qr := dns.NewQuerier(r) qr := resolver.NewQuerier(r)
r.Servers = []string{"127.0.0.1"} r.Servers = []string{"127.0.0.1"}
r.Timeout = 2 r.Timeout = 2
r.Attempts = 1 r.Attempts = 1
@ -25,7 +26,7 @@ func main() {
m.Question = make([]dns.Question, 1) m.Question = make([]dns.Question, 1)
m.Question[0] = dns.Question{os.Args[1], dns.TypeMX, dns.ClassINET} m.Question[0] = dns.Question{os.Args[1], dns.TypeMX, dns.ClassINET}
qr <- dns.DnsMsg{m, nil} qr <- resolver.DnsMsg{m, nil}
in := <-qr in := <-qr
if in.Dns.Rcode != dns.RcodeSuccess { if in.Dns.Rcode != dns.RcodeSuccess {
@ -38,6 +39,6 @@ func main() {
} }
// Stop the resolver, send it a null mesg // Stop the resolver, send it a null mesg
qr <- dns.DnsMsg{nil, nil} qr <- resolver.DnsMsg{nil, nil}
<-qr <-qr
} }

4
msg.go
View File

@ -25,7 +25,7 @@ import (
"encoding/hex" "encoding/hex"
) )
const defaultMsgSize = 4096 const DefaultMsgSize = 4096
// Packing and unpacking. // Packing and unpacking.
// //
@ -616,7 +616,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
// Could work harder to calculate message size, // Could work harder to calculate message size,
// but this is far more than we need and not // but this is far more than we need and not
// big enough to hurt the allocator. // big enough to hurt the allocator.
msg = make([]byte, defaultMsgSize) // TODO, calculate REAL size msg = make([]byte, DefaultMsgSize) // TODO, calculate REAL size
// Pack it in: header and then the pieces. // Pack it in: header and then the pieces.
off := 0 off := 0

View File

@ -25,41 +25,6 @@ func TestPackUnpack(t *testing.T) {
t.Fail() t.Fail()
} }
key := new(RR_DNSKEY)
key.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 3600}
key = &RR_DNSKEY{Flags: 257, Protocol: 3, Algorithm: AlgRSASHA1}
key.PubKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
out.Answer[0] = key
msg, ok = out.Pack()
if !ok {
t.Log("Failed to pack msg with DNSKEY")
t.Fail()
}
if !in.Unpack(msg) {
t.Log("Failed to unpack msg with DNSKEY")
t.Fail()
}
sig := new(RR_RRSIG)
sig.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeRRSIG, Class: ClassINET, Ttl: 3600}
sig = &RR_RRSIG{TypeCovered: TypeDNSKEY, Algorithm: AlgRSASHA1, Labels: 2,
OrigTtl: 3600, Expiration: 4000, Inception: 4000, KeyTag: 34641, SignerName: "miek.nl.",
Signature: "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"}
out.Answer[0] = sig
msg, ok = out.Pack()
if !ok {
t.Log("Failed to pack msg with RRSIG")
t.Fail()
}
if !in.Unpack(msg) {
t.Log("Failed to unpack msg with RRSIG")
t.Fail()
}
edns := new(RR_OPT) edns := new(RR_OPT)
edns.Hdr.Name = "." edns.Hdr.Name = "."
edns.Hdr.Rrtype = TypeOPT edns.Hdr.Rrtype = TypeOPT

12
resolver/Makefile Normal file
View File

@ -0,0 +1,12 @@
# 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.
include $(GOROOT)/src/Make.inc
TARG=dns/resolver
GOFILES=\
resolver.go\
#DEPS=../
include $(GOROOT)/src/Make.pkg

View File

@ -20,13 +20,14 @@
// ch <- DnsMsg{m, nil} // send the query // ch <- DnsMsg{m, nil} // send the query
// in := <-ch // wait for reply // in := <-ch // wait for reply
// //
package dns package resolver
import ( import (
"os" "os"
"rand" "rand"
"time" "time"
"net" "net"
"dns"
) )
// When communicating with a resolver, we use this structure // When communicating with a resolver, we use this structure
@ -34,7 +35,7 @@ import (
// A resolver responds with a reply packet and a possible error. // A resolver responds with a reply packet and a possible error.
// Sending a nil message instructs to resolver to stop. // Sending a nil message instructs to resolver to stop.
type DnsMsg struct { type DnsMsg struct {
Dns *Msg Dns *dns.Msg
Error os.Error Error os.Error
} }
@ -62,7 +63,7 @@ func query(res *Resolver, msg chan DnsMsg) {
// TODO port number, error checking, robustness // TODO port number, error checking, robustness
var c net.Conn var c net.Conn
var err os.Error var err os.Error
var in *Msg var in *dns.Msg
var port string var port string
if len(res.Servers) == 0 { if len(res.Servers) == 0 {
msg <- DnsMsg{nil, nil} msg <- DnsMsg{nil, nil}
@ -124,7 +125,7 @@ func query(res *Resolver, msg chan DnsMsg) {
// Send a request on the connection and hope for a reply. // Send a request on the connection and hope for a reply.
// Up to res.Attempts attempts. // Up to res.Attempts attempts.
func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) { func exchange(c net.Conn, m []byte, r *Resolver) (*dns.Msg, os.Error) {
var timeout int64 var timeout int64
var attempts int var attempts int
if r.Mangle != nil { if r.Mangle != nil {
@ -148,7 +149,7 @@ func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) {
} }
c.SetReadTimeout(timeout * 1e9) // nanoseconds c.SetReadTimeout(timeout * 1e9) // nanoseconds
buf := make([]byte, defaultMsgSize) // More than enough. buf := make([]byte, dns.DefaultMsgSize) // More than enough.
n, err = c.Read(buf) n, err = c.Read(buf)
if err != nil { if err != nil {
// More Go foo needed // More Go foo needed
@ -158,7 +159,7 @@ func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) {
return nil, err return nil, err
} }
buf = buf[0:n] buf = buf[0:n]
in := new(Msg) in := new(dns.Msg)
if !in.Unpack(buf) { if !in.Unpack(buf) {
continue continue
} }

View File

@ -1,7 +1,8 @@
package dns package resolver
import ( import (
"testing" "testing"
"dns"
) )
func TestResolverEdns(t *testing.T) { func TestResolverEdns(t *testing.T) {
@ -12,15 +13,15 @@ func TestResolverEdns(t *testing.T) {
res.Timeout = 2 res.Timeout = 2
res.Attempts = 1 res.Attempts = 1
m := new(Msg) m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true //only set this bit m.MsgHdr.Recursion_desired = true //only set this bit
m.Question = make([]Question, 1) m.Question = make([]dns.Question, 1)
m.Extra = make([]RR, 1) m.Extra = make([]dns.RR, 1)
// Add EDNS rr // Add EDNS rr
edns := new(RR_OPT) edns := new(dns.RR_OPT)
edns.Hdr.Name = "." // must . be for edns edns.Hdr.Name = "." // must . be for edns
edns.Hdr.Rrtype = TypeOPT edns.Hdr.Rrtype = dns.TypeOPT
// You can handle an OTP RR as any other, but there // You can handle an OTP RR as any other, but there
// are some convience functions // are some convience functions
edns.UDPSize(4096, true) edns.UDPSize(4096, true)
@ -32,7 +33,7 @@ func TestResolverEdns(t *testing.T) {
// edns.Option[0].Data = "lalalala" // edns.Option[0].Data = "lalalala"
// ask something // ask something
m.Question[0] = Question{"nlnetlabs.nl", TypeSOA, ClassINET} m.Question[0] = dns.Question{"nlnetlabs.nl", dns.TypeSOA, dns.ClassINET}
m.Extra[0] = edns m.Extra[0] = edns
ch <- DnsMsg{m, nil} ch <- DnsMsg{m, nil}
@ -40,7 +41,7 @@ func TestResolverEdns(t *testing.T) {
//// t.Fail() //// t.Fail()
// t.Log("%v\n", in.Dns) // t.Log("%v\n", in.Dns)
if in.Dns.Rcode != RcodeSuccess { if in.Dns.Rcode != dns.RcodeSuccess {
t.Log("Failed to get an valid answer") t.Log("Failed to get an valid answer")
t.Fail() t.Fail()
} }

View File

@ -1,7 +1,8 @@
package dns package resolver
import ( import (
"testing" "testing"
"dns"
) )
@ -11,27 +12,27 @@ func TestResolver(t *testing.T) {
res.Servers = []string{"127.0.0.1"} res.Servers = []string{"127.0.0.1"}
m := new(Msg) m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true //only set this bit m.MsgHdr.Recursion_desired = true //only set this bit
m.Question = make([]Question, 1) m.Question = make([]dns.Question, 1)
// ask something // ask something
m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET} m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}
ch <- DnsMsg{m, nil} ch <- DnsMsg{m, nil}
in := <-ch in := <-ch
if in.Dns.Rcode != RcodeSuccess { if in.Dns.Rcode != dns.RcodeSuccess {
t.Log("Failed to get an valid answer") t.Log("Failed to get an valid answer")
t.Fail() t.Fail()
t.Logf("%v\n", in) t.Logf("%v\n", in)
} }
// ask something // ask something
m.Question[0] = Question{"www.nlnetlabs.nl", TypeRRSIG, ClassINET} m.Question[0] = dns.Question{"www.nlnetlabs.nl", dns.TypeRRSIG, dns.ClassINET}
ch <- DnsMsg{m, nil} ch <- DnsMsg{m, nil}
in = <-ch in = <-ch
if in.Dns.Rcode != RcodeSuccess { if in.Dns.Rcode != dns.RcodeSuccess {
t.Log("Failed to get an valid answer") t.Log("Failed to get an valid answer")
t.Fail() t.Fail()
t.Logf("%v\n", in) t.Logf("%v\n", in)

137
types.go
View File

@ -24,6 +24,7 @@ import (
"net" "net"
"strconv" "strconv"
"strings" "strings"
"time"
) )
// Packet formats // Packet formats
@ -106,26 +107,6 @@ const (
_CD = 1 << 4 // checking disabled _CD = 1 << 4 // checking disabled
) )
// DNSSEC encryption algorithm codes.
const (
// DNSSEC algorithms
AlgRSAMD5 = 1
AlgDH = 2
AlgDSA = 3
AlgECC = 4
AlgRSASHA1 = 5
AlgRSASHA256 = 8
AlgRSASHA512 = 10
AlgECCGOST = 12
)
// DNSSEC hashing codes.
const (
HashSHA1 = iota
HashSHA256
HashGOST94
)
// DNS queries. // DNS queries.
type Question struct { type Question struct {
Name string "domain-name" // "domain-name" specifies encoding; see packers below Name string "domain-name" // "domain-name" specifies encoding; see packers below
@ -141,45 +122,6 @@ func (q *Question) String() string {
return s return s
} }
// DNS responses (resource records).
// There are many types of messages,
// but they all share the same header.
type RR_Header struct {
Name string "domain-name"
Rrtype uint16
Class uint16
Ttl uint32
Rdlength uint16 // length of data after header
}
func (h *RR_Header) Header() *RR_Header {
return h
}
func (h *RR_Header) String() string {
var s string
if h.Rrtype == TypeOPT {
s = ";"
// and maybe other things
}
if len(h.Name) == 0 {
s += ".\t"
} else {
s += h.Name + "\t"
}
s = s + strconv.Itoa(int(h.Ttl)) + "\t"
s = s + class_str[h.Class] + "\t"
s = s + rr_str[h.Rrtype] + "\t"
return s
}
type RR interface {
Header() *RR_Header
String() string
}
type RR_CNAME struct { type RR_CNAME struct {
Hdr RR_Header Hdr RR_Header
Cname string "domain-name" Cname string "domain-name"
@ -506,29 +448,40 @@ func (rr *RR_NSEC3PARAM) String() string {
// Salt with strings.ToUpper() // Salt with strings.ToUpper()
} }
// Translate the RRSIG's incep. and expir. time to the correct date.
// Taking into account serial arithmetic (RFC 1982)
func timeToDate(t uint32) string {
utc := time.UTC().Seconds()
mod := (int64(t) - utc) / Year68
// If needed assume wrap around(s)
ti := time.SecondsToUTC(int64(t) + (mod * Year68)) // abs()? TODO
return ti.Format("20060102030405")
}
// Map of constructors for each RR wire type. // Map of constructors for each RR wire type.
var rr_mk = map[int]func() RR{ var rr_mk = map[int]func() RR{
TypeCNAME: func() RR { return new(RR_CNAME) }, TypeCNAME: func() RR { return new(RR_CNAME) },
TypeHINFO: func() RR { return new(RR_HINFO) }, TypeHINFO: func() RR { return new(RR_HINFO) },
TypeMB: func() RR { return new(RR_MB) }, TypeMB: func() RR { return new(RR_MB) },
TypeMG: func() RR { return new(RR_MG) }, TypeMG: func() RR { return new(RR_MG) },
TypeMINFO: func() RR { return new(RR_MINFO) }, TypeMINFO: func() RR { return new(RR_MINFO) },
TypeMR: func() RR { return new(RR_MR) }, TypeMR: func() RR { return new(RR_MR) },
TypeMX: func() RR { return new(RR_MX) }, TypeMX: func() RR { return new(RR_MX) },
TypeNS: func() RR { return new(RR_NS) }, TypeNS: func() RR { return new(RR_NS) },
TypePTR: func() RR { return new(RR_PTR) }, TypePTR: func() RR { return new(RR_PTR) },
TypeSOA: func() RR { return new(RR_SOA) }, TypeSOA: func() RR { return new(RR_SOA) },
TypeTXT: func() RR { return new(RR_TXT) }, TypeTXT: func() RR { return new(RR_TXT) },
TypeSRV: func() RR { return new(RR_SRV) }, TypeSRV: func() RR { return new(RR_SRV) },
TypeA: func() RR { return new(RR_A) }, TypeA: func() RR { return new(RR_A) },
TypeAAAA: func() RR { return new(RR_AAAA) }, TypeAAAA: func() RR { return new(RR_AAAA) },
TypeOPT: func() RR { return new(RR_OPT) }, TypeOPT: func() RR { return new(RR_OPT) },
TypeDS: func() RR { return new(RR_DS) }, TypeDS: func() RR { return new(RR_DS) },
TypeRRSIG: func() RR { return new(RR_RRSIG) }, TypeRRSIG: func() RR { return new(RR_RRSIG) },
TypeNSEC: func() RR { return new(RR_NSEC) }, TypeNSEC: func() RR { return new(RR_NSEC) },
TypeDNSKEY: func() RR { return new(RR_DNSKEY) }, TypeDNSKEY: func() RR { return new(RR_DNSKEY) },
TypeNSEC3: func() RR { return new(RR_NSEC3) }, TypeNSEC3: func() RR { return new(RR_NSEC3) },
TypeNSEC3PARAM: func() RR { return new(RR_NSEC3PARAM) }, TypeNSEC3PARAM: func() RR { return new(RR_NSEC3PARAM) },
} }
// Map of strings for each RR wire type. // Map of strings for each RR wire type.
@ -555,27 +508,3 @@ var rr_str = map[uint16]string{
TypeNSEC3: "NSEC3", TypeNSEC3: "NSEC3",
TypeNSEC3PARAM: "NSEC3PARAM", TypeNSEC3PARAM: "NSEC3PARAM",
} }
// Map for algorithm names.
var alg_str = map[uint8]string{
AlgRSAMD5: "RSAMD5",
AlgDH: "DH",
AlgDSA: "DSA",
AlgRSASHA1: "RSASHA1",
AlgRSASHA256: "RSASHA256",
AlgRSASHA512: "RSASHA512",
AlgECCGOST: "ECC-GOST",
}
// Return the rdata of the RR in wireform.
func wireRdata(r RR) ([]byte, bool) {
buf := make([]byte, 4096) // Too large, need to FIX TODO(mg)
off1, ok := packRR(r, buf, 0)
if !ok {
return nil, false
}
start := off1 - int(r.Header().Rdlength)
end := start + int(r.Header().Rdlength)
buf = buf[start:end]
return buf, true
}