Cleanup Client.exchange

Make Client's exchange function easier to read by moving timeout logic
into separate functions.

Start the timers closer to where they're used so that time from other
logic doesn't impact the deadlines.
This commit is contained in:
Michael Haro 2015-05-05 23:23:53 -07:00
parent c13058f493
commit 32448f39cd
1 changed files with 28 additions and 16 deletions

View File

@ -122,31 +122,39 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
return r, rtt, nil return r, rtt, nil
} }
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { func (c *Client) dialTimeout() time.Duration {
timeout := dnsTimeout
var co *Conn
if c.DialTimeout != 0 { if c.DialTimeout != 0 {
timeout = c.DialTimeout return c.DialTimeout
} }
return dnsTimeout
}
func (c *Client) readTimeout() time.Duration {
if c.ReadTimeout != 0 {
return c.ReadTimeout
}
return dnsTimeout
}
func (c *Client) writeTimeout() time.Duration {
if c.WriteTimeout != 0 {
return c.WriteTimeout
}
return dnsTimeout
}
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
var co *Conn
if c.Net == "" { if c.Net == "" {
co, err = DialTimeout("udp", a, timeout) co, err = DialTimeout("udp", a, c.dialTimeout())
} else { } else {
co, err = DialTimeout(c.Net, a, timeout) co, err = DialTimeout(c.Net, a, c.dialTimeout())
} }
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
timeout = dnsTimeout
if c.ReadTimeout != 0 {
timeout = c.ReadTimeout
}
co.SetReadDeadline(time.Now().Add(timeout))
timeout = dnsTimeout
if c.WriteTimeout != 0 {
timeout = c.WriteTimeout
}
co.SetWriteDeadline(time.Now().Add(timeout))
defer co.Close() defer co.Close()
opt := m.IsEdns0() opt := m.IsEdns0()
// If EDNS0 is used use that for size. // If EDNS0 is used use that for size.
if opt != nil && opt.UDPSize() >= MinMsgSize { if opt != nil && opt.UDPSize() >= MinMsgSize {
@ -156,6 +164,10 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
if opt == nil && c.UDPSize >= MinMsgSize { if opt == nil && c.UDPSize >= MinMsgSize {
co.UDPSize = c.UDPSize co.UDPSize = c.UDPSize
} }
co.SetReadDeadline(time.Now().Add(c.readTimeout()))
co.SetWriteDeadline(time.Now().Add(c.writeTimeout()))
co.TsigSecret = c.TsigSecret co.TsigSecret = c.TsigSecret
if err = co.WriteMsg(m); err != nil { if err = co.WriteMsg(m); err != nil {
return nil, 0, err return nil, 0, err