fix reflect
This commit is contained in:
parent
fd0704f111
commit
a7a8b616f0
2
TODO
2
TODO
|
@ -5,6 +5,8 @@ o clean, small API
|
|||
o fast data structures (rb-tree, when they come available)
|
||||
o api-use should lead to self documenting code
|
||||
o compression (only ownernames?)
|
||||
o Tsig will probably become an interface which has all configuration
|
||||
stuff, but this will come later
|
||||
|
||||
|
||||
Todo:
|
||||
|
|
|
@ -18,99 +18,78 @@ package main
|
|||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"net"
|
||||
"dns"
|
||||
"fmt"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func reply(a net.Addr, in *dns.Msg, tcp bool) *dns.Msg {
|
||||
if in.MsgHdr.Response == true {
|
||||
return nil // Don't answer responses
|
||||
}
|
||||
func reply(c *dns.Conn, in *dns.Msg) []byte {
|
||||
m := new(dns.Msg)
|
||||
m.MsgHdr.Id = in.MsgHdr.Id
|
||||
m.MsgHdr.Authoritative = true
|
||||
m.MsgHdr.Response = true
|
||||
m.MsgHdr.Opcode = dns.OpcodeQuery
|
||||
m.SetReply(in.MsgHdr.Id)
|
||||
|
||||
m.MsgHdr.Rcode = dns.RcodeSuccess
|
||||
m.Question = make([]dns.Question, 1)
|
||||
m.Answer = make([]dns.RR, 1)
|
||||
m.Extra = make([]dns.RR, 1)
|
||||
|
||||
r := new(dns.RR_A)
|
||||
r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
|
||||
ip, _ := net.ResolveUDPAddr(a.String())
|
||||
r.A = ip.IP
|
||||
m.Question[0] = in.Question[0]
|
||||
|
||||
var ad net.IP
|
||||
if c.UDP != nil {
|
||||
ad = c.Addr.(*net.UDPAddr).IP
|
||||
} else {
|
||||
ad = c.Addr.(*net.TCPAddr).IP
|
||||
}
|
||||
if ad.To4() != nil {
|
||||
r := new(dns.RR_A)
|
||||
r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
|
||||
if c.UDP != nil {
|
||||
r.A = c.Addr.(*net.UDPAddr).IP
|
||||
} else {
|
||||
r.A = c.Addr.(*net.TCPAddr).IP
|
||||
}
|
||||
m.Answer[0] = r
|
||||
} else {
|
||||
r := new(dns.RR_AAAA)
|
||||
r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
|
||||
if c.UDP != nil {
|
||||
r.AAAA = c.Addr.(*net.UDPAddr).IP
|
||||
} else {
|
||||
r.AAAA = c.Addr.(*net.TCPAddr).IP
|
||||
}
|
||||
m.Answer[0] = r
|
||||
}
|
||||
|
||||
t := new(dns.RR_TXT)
|
||||
t.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
|
||||
if tcp {
|
||||
t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (tcp)"
|
||||
if c.TCP != nil {
|
||||
t.Txt = "Port: " + strconv.Itoa(c.Port) + " (tcp)"
|
||||
} else {
|
||||
t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (udp)"
|
||||
t.Txt = "Port: " + strconv.Itoa(c.Port) + " (udp)"
|
||||
}
|
||||
|
||||
m.Question[0] = in.Question[0]
|
||||
m.Answer[0] = r
|
||||
m.Extra[0] = t
|
||||
return m
|
||||
|
||||
b, _ := m.Pack()
|
||||
return b
|
||||
}
|
||||
|
||||
func replyUDP(c *net.UDPConn, a net.Addr, in *dns.Msg) {
|
||||
m := reply(a, in, false)
|
||||
if m == nil {
|
||||
return
|
||||
func handle(c *dns.Conn, in *dns.Msg) {
|
||||
if in.MsgHdr.Response == true {
|
||||
return // We don't do responses
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "%v\n", m)
|
||||
out, ok := m.Pack()
|
||||
if !ok {
|
||||
println("Failed to pack")
|
||||
return
|
||||
}
|
||||
dns.SendUDP(out, c, a)
|
||||
}
|
||||
|
||||
func replyTCP(c *net.TCPConn, a net.Addr, in *dns.Msg) {
|
||||
m := reply(a, in, true)
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "%v\n", m)
|
||||
out, ok := m.Pack()
|
||||
if !ok {
|
||||
println("Failed to pack")
|
||||
return
|
||||
}
|
||||
dns.SendTCP(out, c, a)
|
||||
answer := reply(c, in)
|
||||
c.Write(answer)
|
||||
}
|
||||
|
||||
func tcp(addr string, e chan os.Error) {
|
||||
a, err := net.ResolveTCPAddr(addr)
|
||||
if err != nil {
|
||||
e <- err
|
||||
}
|
||||
l, err := net.ListenTCP("tcp", a)
|
||||
if err != nil {
|
||||
e <- err
|
||||
}
|
||||
err = dns.ServeTCP(l, replyTCP)
|
||||
err := dns.ListenAndServeTCP(addr, handle)
|
||||
e <- err
|
||||
return
|
||||
}
|
||||
|
||||
func udp(addr string, e chan os.Error) {
|
||||
a, err := net.ResolveUDPAddr(addr)
|
||||
if err != nil {
|
||||
e <- err
|
||||
}
|
||||
l, err := net.ListenUDP("udp", a)
|
||||
if err != nil {
|
||||
e <- err
|
||||
}
|
||||
err = dns.ServeUDP(l, replyUDP)
|
||||
err := dns.ListenAndServeUDP(addr, handle)
|
||||
e <- err
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
package dns
|
||||
|
||||
// Create a reply packet.
|
||||
func (dns *Msg) SetReply(id uint16) {
|
||||
dns.MsgHdr.Id = id
|
||||
dns.MsgHdr.Authoritative = true
|
||||
dns.MsgHdr.Response = true
|
||||
dns.MsgHdr.Opcode = OpcodeQuery
|
||||
dns.MsgHdr.Rcode = RcodeSuccess
|
||||
}
|
||||
|
||||
// Create a notify packet.
|
||||
func (dns *Msg) SetNotify(z string, class uint16) {
|
||||
dns.MsgHdr.Opcode = OpcodeNotify
|
||||
|
|
27
dns.go
27
dns.go
|
@ -58,6 +58,9 @@ type Conn struct {
|
|||
// The remote side of the connection.
|
||||
Addr net.Addr
|
||||
|
||||
// The remote port number of the connection.
|
||||
Port int
|
||||
|
||||
// If TSIG is used, this holds all the information
|
||||
Tsig *Tsig
|
||||
|
||||
|
@ -68,6 +71,20 @@ type Conn struct {
|
|||
Attempts int
|
||||
}
|
||||
|
||||
// Create a new buffer of the appropiate size.
|
||||
func (d *Conn) NewBuffer() []byte {
|
||||
if d.TCP != nil {
|
||||
b := make([]byte, MaxMsgSize)
|
||||
return b
|
||||
}
|
||||
if d.UDP != nil {
|
||||
b := make([]byte, DefaultMsgSize)
|
||||
return b
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (d *Conn) Read(p []byte) (n int, err os.Error) {
|
||||
if d.UDP != nil && d.TCP != nil {
|
||||
return 0, &Error{Error: "UDP and TCP or both non-nil"}
|
||||
|
@ -80,6 +97,7 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
|
|||
return n, err
|
||||
}
|
||||
d.Addr = addr
|
||||
d.Port = addr.(*net.UDPAddr).Port
|
||||
case d.TCP != nil:
|
||||
if len(p) < 1 {
|
||||
return 0, &Error{Error: "Buffer too small to read"}
|
||||
|
@ -88,6 +106,8 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
|
|||
if err != nil || n != 2 {
|
||||
return n, err
|
||||
}
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
d.Port = d.TCP.RemoteAddr().(*net.TCPAddr).Port
|
||||
l, _ := unpackUint16(p[0:2], 0)
|
||||
if l == 0 {
|
||||
return 0, &Error{Error: "received nil msg length", Server: d.Addr}
|
||||
|
@ -132,7 +152,6 @@ func (d *Conn) Write(p []byte) (n int, err os.Error) {
|
|||
attempts = d.Attempts
|
||||
}
|
||||
d.SetTimeout()
|
||||
|
||||
if d.Tsig != nil {
|
||||
// Create a new buffer with the TSIG added.
|
||||
q, err = d.Tsig.Generate(p)
|
||||
|
@ -233,11 +252,7 @@ func (d *Conn) Exchange(request []byte, nosend bool) (reply []byte, err os.Error
|
|||
}
|
||||
}
|
||||
// Layer violation to save memory. Its okay then...
|
||||
if d.UDP == nil {
|
||||
reply = make([]byte, MaxMsgSize)
|
||||
} else {
|
||||
reply = make([]byte, DefaultMsgSize)
|
||||
}
|
||||
reply = d.NewBuffer()
|
||||
n, err = d.Read(reply)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
12
resolver.go
12
resolver.go
|
@ -43,7 +43,11 @@ type Resolver struct {
|
|||
// in, err := res.Query(m, nil) // Ask the question
|
||||
//
|
||||
// Note that message id checking is left to the caller.
|
||||
func (res *Resolver) Query(q *Msg, tsig *Tsig) (d *Msg, err os.Error) {
|
||||
func (res *Resolver) Query(q *Msg) (d *Msg, err os.Error) {
|
||||
return res.QueryTsig(q, nil)
|
||||
}
|
||||
|
||||
func (res *Resolver) QueryTsig(q *Msg, tsig *Tsig) (d *Msg, err os.Error) {
|
||||
var c net.Conn
|
||||
var inb []byte
|
||||
in := new(Msg)
|
||||
|
@ -88,7 +92,11 @@ func (res *Resolver) Query(q *Msg, tsig *Tsig) (d *Msg, err os.Error) {
|
|||
return in, nil
|
||||
}
|
||||
|
||||
func (res *Resolver) Xfr(q *Msg, t *Tsig, m chan Xfr) {
|
||||
func (res *Resolver) Xfr(q *Msg, m chan Xfr) {
|
||||
res.XfrTsig(q, nil, m)
|
||||
}
|
||||
|
||||
func (res *Resolver) XfrTsig(q *Msg, t *Tsig, m chan Xfr) {
|
||||
port, err := check(res, q)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
13
server.go
13
server.go
|
@ -12,8 +12,9 @@ import (
|
|||
)
|
||||
|
||||
// For both -> logging
|
||||
// Add tsig stuff as in resolver.go
|
||||
|
||||
func ServeUDP(l *net.UDPConn, f func(*Conn, *Msg)) os.Error {
|
||||
func HandleUDP(l *net.UDPConn, f func(*Conn, *Msg)) os.Error {
|
||||
for {
|
||||
m := make([]byte, DefaultMsgSize)
|
||||
n, addr, e := l.ReadFromUDP(m)
|
||||
|
@ -25,6 +26,7 @@ func ServeUDP(l *net.UDPConn, f func(*Conn, *Msg)) os.Error {
|
|||
d := new(Conn)
|
||||
d.UDP = l
|
||||
d.Addr = addr
|
||||
d.Port = addr.Port // Why not the same as in dns.go, line 96
|
||||
|
||||
msg := new(Msg)
|
||||
if !msg.Unpack(m) {
|
||||
|
@ -35,7 +37,7 @@ func ServeUDP(l *net.UDPConn, f func(*Conn, *Msg)) os.Error {
|
|||
panic("not reached")
|
||||
}
|
||||
|
||||
func ServeTCP(l *net.TCPListener, f func(*Conn, *Msg)) os.Error {
|
||||
func HandleTCP(l *net.TCPListener, f func(*Conn, *Msg)) os.Error {
|
||||
for {
|
||||
c, e := l.AcceptTCP()
|
||||
if e != nil {
|
||||
|
@ -44,8 +46,9 @@ func ServeTCP(l *net.TCPListener, f func(*Conn, *Msg)) os.Error {
|
|||
d := new(Conn)
|
||||
d.TCP = c
|
||||
d.Addr = c.RemoteAddr()
|
||||
d.Port = d.TCP.RemoteAddr().(*net.TCPAddr).Port
|
||||
|
||||
m := make([]byte, MaxMsgSize) // This may start to hurt someday.
|
||||
m := d.NewBuffer()
|
||||
n, e := d.Read(m)
|
||||
if e != nil {
|
||||
continue
|
||||
|
@ -75,7 +78,7 @@ func ListenAndServeTCP(addr string, f func(*Conn, *Msg)) os.Error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ServeTCP(l, f)
|
||||
err = HandleTCP(l, f)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -88,6 +91,6 @@ func ListenAndServeUDP(addr string, f func(*Conn, *Msg)) os.Error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ServeUDP(l, f)
|
||||
err = HandleUDP(l, f)
|
||||
return err
|
||||
}
|
||||
|
|
9
xfr.go
9
xfr.go
|
@ -39,7 +39,7 @@ func (d *Conn) axfrRead(q *Msg, m chan Xfr) {
|
|||
first := true
|
||||
in := new(Msg)
|
||||
for {
|
||||
inb := make([]byte, MaxMsgSize)
|
||||
inb := d.NewBuffer()
|
||||
n, err := d.Read(inb)
|
||||
if err != nil {
|
||||
m <- Xfr{true, nil, err}
|
||||
|
@ -128,12 +128,7 @@ func (d *Conn) ixfrRead(q *Msg, m chan Xfr) {
|
|||
first := true
|
||||
in := new(Msg)
|
||||
for {
|
||||
var inb []byte
|
||||
if d.TCP != nil {
|
||||
inb = make([]byte, MaxMsgSize)
|
||||
} else {
|
||||
inb = make([]byte, DefaultMsgSize)
|
||||
}
|
||||
inb := d.NewBuffer()
|
||||
n, err := d.Read(inb)
|
||||
if err != nil {
|
||||
m <- Xfr{true, nil, err}
|
||||
|
|
Loading…
Reference in New Issue