add mangler option to the resolver
This commit is contained in:
parent
406c80bebf
commit
718abd1f50
10
Makefile
10
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
16
resolver.go
16
resolver.go
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue