commit other changes too

This commit is contained in:
Miek Gieben 2010-12-20 22:20:13 +01:00
parent 02c4a4b165
commit 0ed946d772
7 changed files with 174 additions and 80 deletions

View File

@ -13,7 +13,7 @@ GOFILES=\
include $(GOROOT)/src/Make.pkg
p: restest manglertest packtest
p: restest manglertest packtest dnssectest
# too lazy to lookup how this works again in Makefiles
restest: restest.go $(GOFILES)
@ -24,3 +24,6 @@ manglertest: manglertest.go $(GOFILES)
packtest: packtest.go $(GOFILES)
6g -I _obj packtest.go && 6l -L _obj -o packtest packtest.6
dnssectest: dnssectest.go $(GOFILES)
6g -I _obj dnssectest.go && 6l -L _obj -o dnssectest dnssectest.6

View File

@ -6,14 +6,39 @@ import (
"fmt"
)
const (
NLOOP = 5
)
func main() {
key := new(dns.RR_DNSKEY)
key.Hdr.Name = "miek.nl"
key.Hdr.Rrtype = dns.TypeDNSKEY
key.Hdr.Class = dns.ClassINET
key.Hdr.Ttl = 3600
key.Flags = 257
key.Protocol = 3
key.Algorithm = dns.AlgRSASHA1
key.PubKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ"
sig := new(dns.RR_RRSIG)
sig.Hdr.Name = "miek.nl."
sig.Hdr.Rrtype = dns.TypeRRSIG
sig.Hdr.Class = dns.ClassINET
sig.Hdr.Ttl = 3600
sig.TypeCovered = dns.TypeDNSKEY
sig.Algorithm = dns.AlgRSASHA1
sig.OrigTtl = 4000
sig.Expiration = 1000
sig.Inception = 800
sig.KeyTag = 34641
sig.SignerName = "miek.nl."
sig.Sig = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ"
fmt.Printf("%v", sig)
res := new(dns.Resolver)
ch := dns.NewQuerier(res)
// configure the resolver
res.Servers = []string{"192.168.1.2"}
res.Timeout = 2
@ -25,39 +50,17 @@ func main() {
m.MsgHdr.Recursion_desired = true //only set this bit
m.Question = make([]dns.Question, 1)
for i:=0; i< NLOOP; i++ {
// ask something
m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
m.Question[0] = dns.Question{"nlnetlabs.nl", dns.TypeDNSKEY, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
in := <-ch
fmt.Printf("%v\n", in.Dns)
// wait for an reply
in := <-ch
fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"a.miek.nl", dns.TypeTXT, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
in = <-ch
fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"miek.nl", dns.TypeTXT, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
in = <-ch
fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"nl", dns.TypeDNSKEY, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
in = <-ch
fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"pa1ton.nl", dns.TypeDS, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
in = <-ch
fmt.Printf("%v\n", in.Dns)
m.Question[0] = dns.Question{"www.nlnetlabs.nl", dns.TypeRRSIG, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
in = <-ch
fmt.Printf("%v\n", in.Dns)
}
ch <- dns.DnsMsg{nil, nil}
time.Sleep(2.0e9) // wait for Go routine to do something
time.Sleep(1.0e9) // wait for Go routine to do something
}

35
msg.go
View File

@ -57,9 +57,11 @@ var opcode_str = map[int]string{
// Map of strings for rcode
var rcode_str = map[int]string{
0: "NOERROR",
1: "FORMERR",
2: "SERVFAIL",
3: "NXDOMAIN",
4: "NOTIMPL",
5: "REFUSED",
}
// Pack a domain name s into msg[off:].
@ -237,7 +239,12 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o
default:
return len(msg), false
case "base64":
//TODO
b64len := base64.StdEncoding.DecodedLen(len(s))
_, err := base64.StdEncoding.Decode(msg[off:off+b64len], []byte(s))
if err != nil {
return len(msg), false
}
off += b64len
case "domain-name":
off, ok = packDomainName(s, msg, off)
if !ok {
@ -338,6 +345,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int,
case "hex":
// Rest of the RR is hex encoded
rdlength := int(val.FieldByName("Hdr").(*reflect.StructValue).FieldByName("Rdlength").(*reflect.UintValue).Get())
// hoeft hier ook niet
var consumed int
switch val.Type().Name() {
case "RR_DS":
@ -350,17 +358,21 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int,
case "base64":
// Rest of the RR is base64 encoded value
rdlength := int(val.FieldByName("Hdr").(*reflect.StructValue).FieldByName("Rdlength").(*reflect.UintValue).Get())
// Need to know how much of rdlength is already consumed
// Need to know how much of rdlength is already consumed, in this packet
var consumed int
// Can't I figure out via reflect how many bytes there are already consumed??
switch val.Type().Name() {
case "RR_DNSKEY":
consumed = 4 // Flags(2) + Protocol(1) + Algorithm(1)
case "RR_DS":
consumed = 4 // KeyTag(2) + Algorithm(1) + DigestType(1)
case "RR_RRSIG":
consumed = 18 // TypeCovered(2) + Algorithm(1) + Labels(1) +
// OrigTTL(4) + SigExpir(4) + SigIncep(4) + KeyTag(2) + len(signername)
// Should already be set in the sequence of parsing (comes before)
// Work because of rfc4034, section 3.17
consumed += len(val.FieldByName("SignerName").(*reflect.StringValue).Get()) + 1
default:
consumed = 0 // TODO
}
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(msg[off:off+rdlength-consumed])))
base64.StdEncoding.Encode(b64, msg[off:off+rdlength-consumed])
s = string(b64)
@ -394,6 +406,7 @@ func unpackStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
return off, ok
}
// THIS can GO TODO
// Generic struct printer.
// Doesn't care about the string tag "domain-name",
func printStructValue(val *reflect.StructValue) string {
@ -432,6 +445,7 @@ func packRR(rr RR, msg []byte, off int) (off2 int, ok bool) {
if !ok {
return len(msg), false
}
// TODO make this quicker?
// pack a third time; redo header with correct data length
rr.Header().Rdlength = uint16(off2 - off1)
packStruct(rr.Header(), msg, off)
@ -454,10 +468,13 @@ func unpackRR(msg []byte, off int) (rr RR, off1 int, ok bool) {
if !known {
return &h, end, true
}
rr = mk()
off, ok = unpackStruct(rr, msg, off0)
if off != end {
return &h, end, true
// added MG
// println("Hier gaat het dan fout, echt waar en was if off0", off0)
return &h, end, true // TIJDELIJK EVEN WEG
}
return rr, off, ok
}
@ -551,7 +568,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
// Could work harder to calculate message size,
// but this is far more than we need and not
// big enough to hurt the allocator.
msg = make([]byte, 2000)
msg = make([]byte, 4096) // TODO, calculate REAL size
// Pack it in: header and then the pieces.
off := 0

View File

@ -2,60 +2,85 @@ package dns
import (
"testing"
"fmt"
"net"
)
func main() {
out := new(dns.Msg)
r := new(dns.RR_AAAA)
func TestPackUnpack(t *testing.T) {
out := new(Msg)
r := new(RR_AAAA)
r.AAAA = net.ParseIP("2001:7b8:206:1:200:39ff:fe59:b187").To16()
r.Hdr.Name = "a.miek.nl"
r.Hdr.Rrtype = dns.TypeAAAA
r.Hdr.Class = dns.ClassINET
r.Hdr.Rrtype = TypeAAAA
r.Hdr.Class = ClassINET
r.Hdr.Ttl = 3600
out.Answer = make([]dns.RR, 1)
out.Answer = make([]RR, 1)
out.Answer[0] = r
msg, err := out.Pack()
if err != nil {
msg, ok := out.Pack()
if ! ok {
t.Log("Failed to pack msg with AAAA")
t.Fail()
}
in := new(dns.Msg)
if in.Unpack(msg) != true {
in := new(Msg)
if ! in.Unpack(msg) {
t.Log("Failed to unpack msg with AAAA")
t.Fail()
}
fmt.Printf("%v\n", in)
sig := new(dns.RR_RRSIG)
sig.Hdr.Name = "miek.nl."
sig.Hdr.Rrtype = dns.TypeRRSIG
sig.Hdr.Class = dns.ClassINET
sig.Hdr.Ttl = 3600
sig.TypeCovered = dns.TypeDNSKEY
sig.Algorithm = dns.AlgRSASHA1
sig.OrigTtl = 4000
sig.Expiration = 1000
sig.Inception = 800
sig.KeyTag = 34641
sig.SignerName = "miek.nl."
sig.Sig = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ"
key := new(RR_DNSKEY)
key.Hdr.Name = "miek.nl."
key.Hdr.Rrtype = TypeDNSKEY
key.Hdr.Class = ClassINET
key.Hdr.Ttl = 3600
key.Flags = 257
key.Protocol = 3
key.Algorithm = AlgRSASHA1
key.PubKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
out.Answer[0] = sig
msg, err = out.Pack()
if err != nil {
t.Log("Failed to pack msg with RRSIG")
out.Answer[0] = key
msg, ok = out.Pack()
// fmt.Printf("%v\n", msg)
if ! ok {
t.Log("Failed to pack msg with DNSKEY")
t.Fail()
}
if in.Unpack(msg) != true {
t.Log("Failed to unpack msg with RRSIG")
if ! in.Unpack(msg) {
t.Log("Failed to unpack msg with DNSKEY")
t.Fail()
}
fmt.Printf("%v\n", in)
sig := new(RR_RRSIG)
sig.Hdr.Name = "miek.nl."
sig.Hdr.Rrtype = TypeRRSIG
sig.Hdr.Class = ClassINET
sig.Hdr.Ttl = 3600
sig.TypeCovered = TypeDNSKEY
sig.Algorithm = AlgRSASHA1
sig.Labels = 2
sig.OrigTtl = 4000
sig.Expiration = 1000
sig.Inception = 800
sig.KeyTag = 34641
sig.SignerName = "miek.nl."
sig.Sig = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
out.Answer[0] = sig
msg, ok = out.Pack()
// fmt.Printf("%v\n", msg)
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()
}
fmt.Printf("%v\n", in)
}

View File

@ -24,4 +24,26 @@ func main() {
in := new(dns.Msg)
in.Unpack(msg)
fmt.Printf("%v\n", in)
sig := new(dns.RR_RRSIG)
sig.Hdr.Name = "miek.nl."
sig.Hdr.Rrtype = dns.TypeRRSIG
sig.Hdr.Class = dns.ClassINET
sig.Hdr.Ttl = 3600
sig.TypeCovered = dns.TypeDNSKEY
sig.Algorithm = dns.AlgRSASHA1
sig.OrigTtl = 4000
sig.Expiration = 1000
sig.Inception = 800
sig.KeyTag = 34641
sig.SignerName = "miek.nl."
sig.Sig = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFq NDzr//kZ"
out.Answer[0] = sig
msg, _ = out.Pack()
in.Unpack(msg)
fmt.Printf("%v\n", in)
}

View File

@ -32,6 +32,7 @@ type Resolver struct {
Timeout int // seconds before giving up on packet
Attempts int // lost packets before giving up on server
Rotate bool // round robin among servers
Tcp bool // use TCP
Mangle func([]byte) []byte // Mangle the packet
}
@ -67,9 +68,13 @@ func query(res *Resolver, msg chan DnsMsg) {
}
for i := 0; i < len(res.Servers); i++ {
// server := res.Servers[i] + ":" + res.Port
server := res.Servers[i] + ":53"
c, cerr = net.Dial("udp", "", server)
if res.Tcp == true {
c, cerr = net.Dial("tcp", "", server)
} else {
c, cerr = net.Dial("udp", "", server)
}
if cerr != nil {
err = cerr
continue

View File

@ -85,6 +85,7 @@ const (
_RA = 1 << 7 // recursion available
// _AD = 1 << ? // authenticated data
// _CD = 1 << ? // checking disabled
// _DO = 1 << ? // dnssec ok
)
const (
@ -146,7 +147,7 @@ func (h *RR_Header) String() string {
} else {
s = h.Name + "\t"
}
s = s + strconv.Itoa(int(h.Ttl)) + "\t" // why no strconv.Uint16??
s = s + strconv.Itoa(int(h.Ttl)) + "\t"
s = s + class_str[h.Class] + "\t"
s = s + rr_str[h.Rrtype] + "\t"
return s
@ -363,14 +364,32 @@ func (rr *RR_AAAA) String() string {
// DNSSEC types
type RR_RRSIG struct {
Hdr RR_Header
Hdr RR_Header
TypeCovered uint16
Algorithm uint8
Labels uint8
OrigTtl uint32
Expiration uint32
Inception uint32
KeyTag uint16
SignerName string "domain-name"
Sig string "base64"
}
func (rr *RR_RRSIG) Header() *RR_Header {
return &rr.Hdr
}
func (rr *RR_RRSIG) String() string {
return "BLAH"
return rr.Hdr.String() +
" " + rr_str[rr.TypeCovered] +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + strconv.Itoa(int(rr.Labels)) +
" " + strconv.Itoa(int(rr.OrigTtl)) +
" " + strconv.Itoa(int(rr.Expiration)) + // date calc! TODO
" " + strconv.Itoa(int(rr.Inception)) + // date calc! TODO
" " + strconv.Itoa(int(rr.KeyTag)) +
" " + rr.SignerName +
" " + rr.Sig
}
type RR_NSEC struct {
@ -421,7 +440,7 @@ func (rr *RR_DNSKEY) String() string {
return rr.Hdr.String() +
" " + strconv.Itoa(int(rr.Flags)) +
" " + strconv.Itoa(int(rr.Protocol)) +
" " + alg_str[rr.Algorithm] +
" " + strconv.Itoa(int(rr.Algorithm)) +
" " + rr.PubKey // encoding/base64
}