add mangler option to the resolver

This commit is contained in:
Miek Gieben 2010-12-19 09:45:21 +01:00
parent 406c80bebf
commit 718abd1f50
3 changed files with 73 additions and 7 deletions

View File

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

54
manglertest.go Normal file
View File

@ -0,0 +1,54 @@
package main
import (
"dns"
"time"
"fmt"
)
const (
NLOOP = 5
)
func identity(msg []byte) []byte {
return msg
}
func byteflip(msg []byte) []byte {
msg[len(msg) - 1] = 0
msg[2] = 0 // See what happens
return msg
}
func bitflip(msg []byte) []byte {
return msg
}
func main() {
res := new(dns.Resolver)
ch := dns.NewQuerier(res)
// configure the resolver
res.Servers = []string{"192.168.1.2"}
res.Timeout = 2
res.Attempts = 1
res.Mangle = byteflip
// Setup done, now for some real work
// Create a new message
m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true //only set this bit
m.Question = make([]dns.Question, 1)
// ask something
m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}
ch <- dns.DnsMsg{m, nil}
// wait for an reply
in := <-ch
fmt.Printf("%v\n", in.Dns)
ch <- dns.DnsMsg{nil, nil}
time.Sleep(1.0e9) // wait for Go routine to do something
}

View File

@ -16,6 +16,8 @@ import (
"net"
)
// For communicating with a resolver
// A nil msg ends the resolver goroutine
type DnsMsg struct {
Dns *Msg
Error os.Error
@ -30,9 +32,9 @@ 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
Mangle func([]byte) []byte // Mangle the packet
}
// Start a new querier as a goroutine, return
// the communication channel
func NewQuerier(res *Resolver) (ch chan DnsMsg) {
@ -72,7 +74,7 @@ func query(res *Resolver, msg chan DnsMsg) {
err = cerr
continue
}
in, err = exchange(c, sending, res.Attempts, res.Timeout)
in, err = exchange(c, sending, res)
// Check id in.id != out.id
c.Close()
@ -94,14 +96,18 @@ func query(res *Resolver, msg chan DnsMsg) {
// Send a request on the connection and hope for a reply.
// Up to res.Attempts attempts.
func exchange(c net.Conn, m []byte, attempts, timeout int) (*Msg, os.Error) {
for attempt := 0; attempt < attempts; attempt++ {
func exchange(c net.Conn, m []byte, r *Resolver) (*Msg, os.Error) {
if r.Mangle != nil {
m = r.Mangle(m)
}
for attempt := 0; attempt < r.Attempts; attempt++ {
n, err := c.Write(m)
if err != nil {
return nil, err
}
c.SetReadTimeout(int64(timeout) * 1e9) // nanoseconds
c.SetReadTimeout(int64(r.Timeout) * 1e9) // nanoseconds
// EDNS TODO
buf := make([]byte, 2000) // More than enough.
n, err = c.Read(buf)