Add remote address too

This commit is contained in:
Miek Gieben 2012-05-05 17:37:33 +02:00
parent d36ee08216
commit c96d86da1f
6 changed files with 32 additions and 27 deletions

View File

@ -5,7 +5,6 @@ need to be fixed.
* Speed, we can always go faster. A simple reflect server now hits 35/45K qps
* go test; only works correct on my machine
* privatekey.Precompute() when signing?
## Examples to add

View File

@ -220,7 +220,11 @@ func ListenAndQuery(request chan *Request, handler QueryHandler) {
// Write returns the original question and the answer on the
// reply channel of the client.
func (w *reply) Write(m *Msg) error {
w.Client().ReplyChan <- &Exchange{Request: w.req, Reply: m, Rtt: w.rtt}
if w.conn == nil {
w.Client().ReplyChan <- &Exchange{Request: w.req, Reply: m, Rtt: w.rtt}
} else {
w.Client().ReplyChan <- &Exchange{Request: w.req, Reply: m, Rtt: w.rtt, RemoteAddr: w.conn.RemoteAddr()}
}
return nil
}
@ -258,12 +262,12 @@ func (c *Client) exchangeBuffer(inbuf []byte, a string, outbuf []byte) (n int, w
// Exchange performs an synchronous query. It sends the message m to the address
// contained in a and waits for an reply.
func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, addr net.Addr, err error) {
var n int
var w *reply
out, ok := m.Pack()
if !ok {
return nil, 0, ErrPack
return nil, 0, nil, ErrPack
}
var in []byte
switch c.Net {
@ -279,13 +283,13 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
in = make([]byte, size)
}
if n, w, err = c.exchangeBuffer(out, a, in); err != nil {
return nil, 0, err
return nil, 0, w.conn.RemoteAddr(), err
}
r = new(Msg)
if ok := r.Unpack(in[:n]); !ok {
return nil, w.rtt, ErrUnpack
return nil, w.rtt, w.conn.RemoteAddr(), ErrUnpack
}
return r, w.rtt, nil
return r, w.rtt, w.conn.RemoteAddr(), nil
}
// Dial connects to the address addr for the network set in c.Net

9
dns.go
View File

@ -117,10 +117,11 @@ type RR interface {
// Exchange is used in communicating with the resolver.
type Exchange struct {
Request *Msg // the question sent
Reply *Msg // the answer to the question that was sent
Rtt time.Duration // Round trip time
Error error // if something went wrong, this contains the error
Request *Msg // the question sent
Reply *Msg // the answer to the question that was sent
Rtt time.Duration // Round trip time
RemoteAddr net.Addr // Client address
Error error // if something went wrong, this contains the error
}
// DNS resource records.

View File

@ -1,4 +1,5 @@
package main
// Print the MX records of a domain
// (c) Miek Gieben - 2011
import (
@ -22,7 +23,7 @@ func main() {
m.MsgHdr.RecursionDesired = true
// Simple sync query, nothing fancy
r, _, err := c.Exchange(m, config.Servers[0] + ":" + config.Port)
r, _, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
if err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(1)

View File

@ -36,7 +36,7 @@ func main() {
short := flag.Bool("short", false, "abbreviate long DNSSEC records")
check := flag.Bool("check", false, "check internal DNSSEC consistency")
anchor := flag.String("anchor", "", "use the DNSKEY in this file for interal DNSSEC consistency")
tsig := flag.String("tsig", "", "request tsig with key: [hmac:]name:key")
tsig := flag.String("tsig", "", "request tsig with key: [hmac:]name:key")
port := flag.Int("port", 53, "port number to use")
aa := flag.Bool("aa", false, "set AA flag in query")
ad := flag.Bool("ad", false, "set AD flag in query")
@ -191,7 +191,7 @@ forever:
}
if r.Reply.MsgHdr.Truncated && *fallback {
if c.Net != "tcp" {
if ! *dnssec {
if !*dnssec {
fmt.Printf(";; Truncated, trying %d bytes bufsize\n", dns.DefaultMsgSize)
o := new(dns.RR_OPT)
o.Hdr.Name = "."
@ -222,7 +222,7 @@ forever:
}
fmt.Printf("%v", r.Reply)
fmt.Printf("\n;; Query time: %.3d µs\n", r.Rtt/1e3)
fmt.Printf("\n;; query time: %.3d µs, server: %s(%s)\n", r.Rtt/1e3, r.RemoteAddr, r.RemoteAddr.Network())
// Server maybe
}
i++
@ -270,7 +270,7 @@ func sectionCheck(set []dns.RR, server string, tcp bool) {
where = "disk"
}
if err := rr.(*dns.RR_RRSIG).Verify(key, rrset); err != nil {
fmt.Printf(";- Bogus signature, %s does not validate (DNSKEY %s/%d/%s) [%s]\n",
fmt.Printf(";- Bogus signature, %s does not validate (DNSKEY %s/%d/%s) [%s]\n",
shortSig(rr.(*dns.RR_RRSIG)), key.Header().Name, key.KeyTag(), where, err.Error())
} else {
fmt.Printf(";+ Secure signature, %s validates (DNSKEY %s/%d/%s)\n", shortSig(rr.(*dns.RR_RRSIG)), key.Header().Name, key.KeyTag(), where)
@ -341,7 +341,7 @@ func getKey(name string, keytag uint16, server string, tcp bool) *dns.RR_DNSKEY
m := new(dns.Msg)
m.SetQuestion(name, dns.TypeDNSKEY)
m.SetEdns0(4096, true)
r, _, err := c.Exchange(m, server)
r, _, _, err := c.Exchange(m, server)
if err != nil {
return nil
}

20
xfr.go
View File

@ -33,16 +33,16 @@ func (w *reply) axfrReceive() {
for {
in, err := w.Receive()
if err != nil {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, err}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), err}
return
}
if w.req.Id != in.Id {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrId}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrId}
return
}
if first {
if !checkXfrSOA(in, true) {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrXfrSoa}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrXfrSoa}
return
}
first = !first
@ -51,10 +51,10 @@ func (w *reply) axfrReceive() {
if !first {
w.tsigTimersOnly = true // Subsequent envelopes use this.
if checkXfrSOA(in, false) {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrXfrLast}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrXfrLast}
return
}
w.Client().ReplyChan <- &Exchange{Request: w.req, Reply: in}
w.Client().ReplyChan <- &Exchange{Request: w.req, Reply: in, Rtt: w.rtt, RemoteAddr: w.conn.RemoteAddr(), Error: nil}
}
}
panic("not reached")
@ -68,24 +68,24 @@ func (w *reply) ixfrReceive() {
for {
in, err := w.Receive()
if err != nil {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, err}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), err}
return
}
if w.req.Id != in.Id {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrId}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrId}
return
}
if first {
// A single SOA RR signals "no changes"
if len(in.Answer) == 1 && checkXfrSOA(in, true) {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrXfrLast}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrXfrLast}
return
}
// Check if the returned answer is ok
if !checkXfrSOA(in, true) {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrXfrSoa}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrXfrSoa}
return
}
// This serial is important
@ -99,7 +99,7 @@ func (w *reply) ixfrReceive() {
// If the last record in the IXFR contains the servers' SOA, we should quit
if v, ok := in.Answer[len(in.Answer)-1].(*RR_SOA); ok {
if v.Serial == serial {
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, ErrXfrLast}
w.Client().ReplyChan <- &Exchange{w.req, in, w.rtt, w.conn.RemoteAddr(), ErrXfrLast}
return
}
}