Test Nameserver Inside responder pkg
This commit is contained in:
parent
04f2bf449a
commit
5786959b98
1
TODO
1
TODO
|
@ -3,6 +3,7 @@ Todo:
|
|||
* Tsig testing
|
||||
* Private key file parsing use io.Reader (or the like)
|
||||
* Parsing from /etc/resolv.conf - clean up the code, use normal packages
|
||||
* IP6 testing
|
||||
|
||||
Longer term:
|
||||
* Parsing from strings, going with goyacc and own lexer
|
||||
|
|
|
@ -29,10 +29,10 @@ type server responder.Server
|
|||
func (s *server) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) {
|
||||
inmsg := new(dns.Msg)
|
||||
if !inmsg.Unpack(in) {
|
||||
// NXdomain 'n stuff
|
||||
// FormErr
|
||||
println("Unpacking failed")
|
||||
}
|
||||
if inmsg.Hdr.Response == true {
|
||||
if inmsg.MsgHdr.Response == true {
|
||||
return // Don't answer responses
|
||||
}
|
||||
m := new(dns.Msg)
|
||||
|
@ -71,7 +71,7 @@ func (s *server) ResponderTCP(c *net.TCPConn, in []byte) {
|
|||
// NXdomain 'n stuff
|
||||
println("Unpacking failed")
|
||||
}
|
||||
if inmsg.Hdr.Response == true {
|
||||
if inmsg.MsgHdr.Response == true {
|
||||
return // Don't answer responses
|
||||
}
|
||||
return // we are lazy and don't support tcp
|
||||
|
|
4
dns.go
4
dns.go
|
@ -65,7 +65,9 @@ func (m *Meta) String() string {
|
|||
s += "\n;; MSG SIZE rcvd: " + strconv.Itoa(m.RLen) + ", sent: " + strconv.Itoa(m.QLen)
|
||||
rf := float32(m.RLen)
|
||||
qf := float32(m.QLen)
|
||||
s += " (" + strconv.Ftoa32(rf/qf, 'f', 2) + ":1)"
|
||||
if qf != 0 {
|
||||
s += " (" + strconv.Ftoa32(rf/qf, 'f', 2) + ":1)"
|
||||
}
|
||||
// WHEN??
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -128,7 +128,9 @@ func query(res *Resolver, msg chan Msg) {
|
|||
}
|
||||
break
|
||||
}
|
||||
meta.QLen = len(sending)
|
||||
if sending != nil {
|
||||
meta.QLen = len(sending)
|
||||
}
|
||||
if err != nil {
|
||||
msg <- Msg{nil, meta, err}
|
||||
} else {
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
// func (s *myserv) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) { /* UDP reply */ }
|
||||
// func (s *myserv) ResponderTCP(c *net.TCPConn, in []byte) { /* TCP reply */}
|
||||
//
|
||||
// su := new(Server) // create new sever
|
||||
// su.Address = "127.0.0.1" // listen address
|
||||
// su.Port = "8053" // listen port
|
||||
// var us *myserv
|
||||
// uch :=make(chan bool)
|
||||
// go su.NewResponder(us, uch) // start the responder
|
||||
// s := new(Server) // create new sever
|
||||
// s.Address = "127.0.0.1" // listen address
|
||||
// s.Port = "8053" // listen port
|
||||
// var m *myserv
|
||||
// ch :=make(chan bool)
|
||||
// go s.NewResponder(m, ch) // start the responder
|
||||
package responder
|
||||
|
||||
import (
|
||||
|
@ -41,7 +41,6 @@ type msg struct {
|
|||
addr net.Addr // remote address
|
||||
msg []byte // raw dns message
|
||||
err os.Error // any errors
|
||||
// Meta stuff
|
||||
}
|
||||
|
||||
// Every nameserver implements the Responder interface. It defines
|
||||
|
@ -86,9 +85,13 @@ func (res *Server) NewResponder(h Responder, stop chan bool) os.Error {
|
|||
break foreverTCP
|
||||
case s := <-tch:
|
||||
if s.err != nil {
|
||||
//continue
|
||||
}
|
||||
go h.ResponderTCP(s.ct, s.msg)
|
||||
// always fatal??
|
||||
println(s.err.String())
|
||||
close(stop)
|
||||
return s.err
|
||||
} else {
|
||||
go h.ResponderTCP(s.ct, s.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,8 +108,10 @@ func (res *Server) NewResponder(h Responder, stop chan bool) os.Error {
|
|||
break foreverUDP
|
||||
case s := <-uch:
|
||||
if s.err != nil {
|
||||
println(s.err)
|
||||
//continue?
|
||||
//continue
|
||||
println(s.err.String())
|
||||
close(stop)
|
||||
return s.err
|
||||
} else {
|
||||
go h.ResponderUDP(s.cu, s.addr, s.msg)
|
||||
}
|
||||
|
@ -207,3 +212,66 @@ func SendUDP(m []byte, c *net.UDPConn, a net.Addr) os.Error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Basic implementation of a reflector nameserver which responds
|
||||
// to queries for A types and replies with the qname as the ownername
|
||||
// and querier's IP as the rdata
|
||||
type reflectServer Server
|
||||
func (s *reflectServer) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) {
|
||||
o, ok := makePkt(a, in)
|
||||
if ok {
|
||||
out, ok1 := o.Pack()
|
||||
if ok1 {
|
||||
SendUDP(out, c, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *reflectServer) ResponderTCP(c *net.TCPConn, in []byte) {
|
||||
o, ok := makePkt(c.RemoteAddr(), in)
|
||||
if ok {
|
||||
out, ok1 := o.Pack()
|
||||
if ok1 {
|
||||
SendTCP(out, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makePkt(a net.Addr, i []byte) (*dns.Msg, bool) {
|
||||
msg := new(dns.Msg)
|
||||
if !msg.Unpack(i) {
|
||||
return nil, false
|
||||
}
|
||||
if msg.MsgHdr.Response == true {
|
||||
return nil, false
|
||||
}
|
||||
m := new(dns.Msg)
|
||||
m.MsgHdr.Id = msg.MsgHdr.Id
|
||||
m.MsgHdr.Authoritative = true
|
||||
m.MsgHdr.Response = true
|
||||
m.MsgHdr.Opcode = dns.OpcodeQuery
|
||||
m.MsgHdr.Rcode = dns.RcodeSuccess
|
||||
m.Question = make([]dns.Question, 1)
|
||||
m.Question[0] = msg.Question[0]
|
||||
if msg.Question[0].Qtype != dns.TypeA {
|
||||
// wrong question
|
||||
m.MsgHdr.Rcode = dns.RcodeFormatError
|
||||
return m ,true
|
||||
}
|
||||
m.Answer = make([]dns.RR, 1)
|
||||
r := new(dns.RR_A)
|
||||
r.Hdr = dns.RR_Header{Name: msg.Question[0].Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
|
||||
ip, _ := net.ResolveUDPAddr(a.String())
|
||||
r.A = ip.IP.To4()
|
||||
m.Answer[0] = r
|
||||
return m, true
|
||||
}
|
||||
|
||||
// A simple nameserver implementation. It reponds to queries for the A record and replies
|
||||
// with the qname as the ownername and the rdata of the A record set to the senders address.
|
||||
//
|
||||
// Sample (udp) usage:
|
||||
// stop := make(chan bool)
|
||||
// s := new(Server)
|
||||
// go s.NewResponder(Reflector, stop)
|
||||
var Reflector *reflectServer
|
||||
|
|
|
@ -36,25 +36,25 @@ func createpkg(id uint16, tcp bool, remove net.Addr) []byte {
|
|||
func (s *myserv) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) {
|
||||
inmsg := new(dns.Msg)
|
||||
inmsg.Unpack(in)
|
||||
if inmsg.MsgHdr.Response == true {
|
||||
// Uh... answering to an response??
|
||||
// dont think so
|
||||
return
|
||||
}
|
||||
if inmsg.MsgHdr.Response == true {
|
||||
// Uh... answering to an response??
|
||||
// dont think so
|
||||
return
|
||||
}
|
||||
out := createpkg(inmsg.MsgHdr.Id, false, a)
|
||||
SendUDP(out, c, a)
|
||||
// Meta.QLen/RLen/QueryStart/QueryEnd can be filled in at
|
||||
// this point for logging purposses or anything else
|
||||
// Meta.QLen/RLen/QueryStart/QueryEnd can be filled in at
|
||||
// this point for logging purposses or anything else
|
||||
}
|
||||
|
||||
func (s *myserv) ResponderTCP(c *net.TCPConn, in []byte) {
|
||||
inmsg := new(dns.Msg)
|
||||
inmsg.Unpack(in)
|
||||
if inmsg.MsgHdr.Response == true {
|
||||
// Uh... answering to an response??
|
||||
// dont think so
|
||||
return
|
||||
}
|
||||
if inmsg.MsgHdr.Response == true {
|
||||
// Uh... answering to an response??
|
||||
// dont think so
|
||||
return
|
||||
}
|
||||
out := createpkg(inmsg.MsgHdr.Id, true, c.RemoteAddr())
|
||||
SendTCP(out, c)
|
||||
}
|
||||
|
@ -77,8 +77,30 @@ func TestResponder(t *testing.T) {
|
|||
tch := make(chan bool)
|
||||
go st.NewResponder(ts, tch)
|
||||
time.Sleep(1 * 1e9)
|
||||
uch<-true
|
||||
tch<-true
|
||||
<-uch
|
||||
<-tch
|
||||
uch <- true
|
||||
tch <- true
|
||||
<-uch
|
||||
<-tch
|
||||
}
|
||||
|
||||
func TestReflectorResponder(t *testing.T) {
|
||||
stop := make(chan bool)
|
||||
s := new(Server)
|
||||
s.Port = "8053"
|
||||
s.Address = "127.0.0.1"
|
||||
|
||||
stoptcp := make(chan bool)
|
||||
stcp := new(Server)
|
||||
stcp.Port = "8053"
|
||||
stcp.Address = "127.0.0.1"
|
||||
stcp.Tcp = true
|
||||
|
||||
go stcp.NewResponder(Reflector, stoptcp)
|
||||
go s.NewResponder(Reflector, stop)
|
||||
|
||||
time.Sleep(1 * 1e9)
|
||||
stop <- true
|
||||
stoptcp <- true
|
||||
<-stop
|
||||
<-stoptcp
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue