Save rtts for clients
This commit is contained in:
parent
52d391e251
commit
fc599d23fe
51
client.go
51
client.go
|
@ -13,10 +13,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check incoming TSIG message. TODO(mg)
|
// Incoming (documentation just as in os.Signal)
|
||||||
// Need a tsigstatus for that too? Don't know yet. TODO(mg)
|
|
||||||
|
|
||||||
// Incoming (just as in os.Signal)
|
|
||||||
type QueryHandler interface {
|
type QueryHandler interface {
|
||||||
QueryDNS(w RequestWriter, q *Msg)
|
QueryDNS(w RequestWriter, q *Msg)
|
||||||
}
|
}
|
||||||
|
@ -32,10 +29,12 @@ type RequestWriter interface {
|
||||||
Receive() (*Msg, error)
|
Receive() (*Msg, error)
|
||||||
// Close closes the connection with the server.
|
// Close closes the connection with the server.
|
||||||
Close() error
|
Close() error
|
||||||
// Dials calls the server
|
// Dials calls the server.
|
||||||
Dial() error
|
Dial() error
|
||||||
// TsigStatus return the TSIG validation status.
|
// TsigStatus returns the TSIG validation status.
|
||||||
TsigStatus() error
|
TsigStatus() error
|
||||||
|
// Rtt returns the duration of the request. The value is only valid after a Send()/Receive() sequence.
|
||||||
|
Rtt() time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// hijacked connections...?
|
// hijacked connections...?
|
||||||
|
@ -47,6 +46,8 @@ type reply struct {
|
||||||
tsigRequestMAC string
|
tsigRequestMAC string
|
||||||
tsigTimersOnly bool
|
tsigTimersOnly bool
|
||||||
tsigStatus error
|
tsigStatus error
|
||||||
|
rtt time.Duration
|
||||||
|
t time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Request is a incoming message from a Client.
|
// A Request is a incoming message from a Client.
|
||||||
|
@ -190,7 +191,6 @@ func (q *Query) Query() error {
|
||||||
if handler == nil {
|
if handler == nil {
|
||||||
handler = DefaultQueryMux
|
handler = DefaultQueryMux
|
||||||
}
|
}
|
||||||
//forever:
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case in := <-q.QueryChan:
|
case in := <-q.QueryChan:
|
||||||
|
@ -247,12 +247,14 @@ func (c *Client) ExchangeBuffer(inbuf []byte, a string, outbuf []byte) (n int, e
|
||||||
if c.Hijacked != nil {
|
if c.Hijacked != nil {
|
||||||
w.conn = c.Hijacked
|
w.conn = c.Hijacked
|
||||||
}
|
}
|
||||||
|
w.t = time.Now()
|
||||||
if n, err = w.writeClient(inbuf); err != nil {
|
if n, err = w.writeClient(inbuf); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if n, err = w.readClient(outbuf); err != nil {
|
if n, err = w.readClient(outbuf); err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
w.rtt = time.Since(w.t)
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,22 +299,6 @@ func (w *reply) Dial() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *reply) Close() (err error) {
|
|
||||||
return w.conn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *reply) Client() *Client {
|
|
||||||
return w.client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *reply) Request() *Msg {
|
|
||||||
return w.req
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *reply) TsigStatus() error {
|
|
||||||
return w.tsigStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *reply) Receive() (*Msg, error) {
|
func (w *reply) Receive() (*Msg, error) {
|
||||||
var p []byte
|
var p []byte
|
||||||
m := new(Msg)
|
m := new(Msg)
|
||||||
|
@ -323,13 +309,14 @@ func (w *reply) Receive() (*Msg, error) {
|
||||||
p = make([]byte, DefaultMsgSize)
|
p = make([]byte, DefaultMsgSize)
|
||||||
}
|
}
|
||||||
n, err := w.readClient(p)
|
n, err := w.readClient(p)
|
||||||
if err != nil {
|
if err != nil || n == 0 {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p = p[:n]
|
p = p[:n]
|
||||||
if ok := m.Unpack(p); !ok {
|
if ok := m.Unpack(p); !ok {
|
||||||
return nil, ErrUnpack
|
return nil, ErrUnpack
|
||||||
}
|
}
|
||||||
|
w.rtt = time.Since(w.t)
|
||||||
if m.IsTsig() {
|
if m.IsTsig() {
|
||||||
secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name
|
secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name
|
||||||
if _, ok := w.Client().TsigSecret[secret]; !ok {
|
if _, ok := w.Client().TsigSecret[secret]; !ok {
|
||||||
|
@ -430,6 +417,7 @@ func (w *reply) Send(m *Msg) (err error) {
|
||||||
return ErrPack
|
return ErrPack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
w.t = time.Now()
|
||||||
if _, err = w.writeClient(out); err != nil {
|
if _, err = w.writeClient(out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -505,3 +493,18 @@ func (w *reply) writeClient(p []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close implents the RequestWriter.Close method
|
||||||
|
func (w *reply) Close() (err error) { return w.conn.Close() }
|
||||||
|
|
||||||
|
// Client returns a pointer to the client
|
||||||
|
func (w *reply) Client() *Client { return w.client }
|
||||||
|
|
||||||
|
// Request returns the request contained in reply
|
||||||
|
func (w *reply) Request() *Msg { return w.req }
|
||||||
|
|
||||||
|
// TsigStatus implements the RequestWriter.TsigStatus method
|
||||||
|
func (w *reply) TsigStatus() error { return w.tsigStatus }
|
||||||
|
|
||||||
|
// Rtt implements the RequestWriter.Rtt method
|
||||||
|
func (w *reply) Rtt() time.Duration { return w.rtt }
|
||||||
|
|
|
@ -27,6 +27,8 @@ func q(w dns.RequestWriter, m *dns.Msg) {
|
||||||
if w.TsigStatus() != nil {
|
if w.TsigStatus() != nil {
|
||||||
fmt.Printf(";; Couldn't verify TSIG signature: %s\n", w.TsigStatus().Error())
|
fmt.Printf(";; Couldn't verify TSIG signature: %s\n", w.TsigStatus().Error())
|
||||||
}
|
}
|
||||||
|
// Save the Rtt in the message
|
||||||
|
r.Rtt = w.Rtt()
|
||||||
w.Write(r)
|
w.Write(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +224,8 @@ forever:
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%v", r.Reply)
|
fmt.Printf("%v", r.Reply)
|
||||||
|
fmt.Printf("\n;; Query time: %.3d µs\n", r.Reply.Rtt/1e3)
|
||||||
|
// Server maybe
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
if i == len(qname) {
|
if i == len(qname) {
|
||||||
|
|
13
msg.go
13
msg.go
|
@ -80,11 +80,12 @@ type MsgHdr struct {
|
||||||
// The layout of a DNS message.
|
// The layout of a DNS message.
|
||||||
type Msg struct {
|
type Msg struct {
|
||||||
MsgHdr
|
MsgHdr
|
||||||
Compress bool // If true, the message will be compressed when converted to wire format.
|
Compress bool // If true, the message will be compressed when converted to wire format.
|
||||||
Question []Question // Holds the RR(s) of the question section.
|
Rtt time.Duration // Round Trip Time, time it took between sending a reply and receiving the answer.
|
||||||
Answer []RR // Holds the RR(s) of the answer section.
|
Question []Question // Holds the RR(s) of the question section.
|
||||||
Ns []RR // Holds the RR(s) of the authority section.
|
Answer []RR // Holds the RR(s) of the answer section.
|
||||||
Extra []RR // Holds the RR(s) of the additional section.
|
Ns []RR // Holds the RR(s) of the authority section.
|
||||||
|
Extra []RR // Holds the RR(s) of the additional section.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map of strings for each RR wire type.
|
// Map of strings for each RR wire type.
|
||||||
|
@ -373,7 +374,7 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
switch val.Type().Field(i).Tag.Get("dns") {
|
switch val.Type().Field(i).Tag.Get("dns") {
|
||||||
default:
|
default:
|
||||||
println("dns: unknown tag packing slice", val.Type().Field(i).Tag.Get("dns"), '"', val.Type().Field(i).Tag , '"')
|
println("dns: unknown tag packing slice", val.Type().Field(i).Tag.Get("dns"), '"', val.Type().Field(i).Tag, '"')
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
case "domain-name":
|
case "domain-name":
|
||||||
for j := 0; j < val.Field(i).Len(); j++ {
|
for j := 0; j < val.Field(i).Len(); j++ {
|
||||||
|
|
|
@ -23,7 +23,7 @@ type Handler interface {
|
||||||
type ResponseWriter interface {
|
type ResponseWriter interface {
|
||||||
// RemoteAddr returns the net.Addr of the client that sent the current request.
|
// RemoteAddr returns the net.Addr of the client that sent the current request.
|
||||||
RemoteAddr() net.Addr
|
RemoteAddr() net.Addr
|
||||||
// Return the status of the Tsig (TsigNone, TsigVerified or TsigBad)
|
// TsigSttus returns the status of the Tsig (TsigNone, TsigVerified or TsigBad).
|
||||||
TsigStatus() error
|
TsigStatus() error
|
||||||
// Write writes a reply back to the client.
|
// Write writes a reply back to the client.
|
||||||
Write(*Msg) error
|
Write(*Msg) error
|
||||||
|
@ -403,6 +403,4 @@ func (w *response) Write(m *Msg) (err error) {
|
||||||
func (w *response) RemoteAddr() net.Addr { return w.conn.remoteAddr }
|
func (w *response) RemoteAddr() net.Addr { return w.conn.remoteAddr }
|
||||||
|
|
||||||
// TsigStatus implements the ResponseWriter.TsigStatus method
|
// TsigStatus implements the ResponseWriter.TsigStatus method
|
||||||
func (w *response) TsigStatus() error {
|
func (w *response) TsigStatus() error { return w.tsigStatus }
|
||||||
return w.tsigStatus
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue