diff options
Diffstat (limited to 'plugin/forward/connect.go')
-rw-r--r-- | plugin/forward/connect.go | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/plugin/forward/connect.go b/plugin/forward/connect.go index 6f9897550..13631ca89 100644 --- a/plugin/forward/connect.go +++ b/plugin/forward/connect.go @@ -7,6 +7,7 @@ package forward import ( "io" "strconv" + "sync/atomic" "time" "github.com/coredns/coredns/request" @@ -15,6 +16,19 @@ import ( "golang.org/x/net/context" ) +func (p *Proxy) readTimeout() time.Duration { + rtt := time.Duration(atomic.LoadInt64(&p.avgRtt)) + if rtt < timeout/2 { + return 2 * rtt + } + return timeout +} + +func (p *Proxy) updateRtt(newRtt time.Duration) { + rtt := time.Duration(atomic.LoadInt64(&p.avgRtt)) + atomic.AddInt64(&p.avgRtt, int64((newRtt-rtt)/rttCount)) +} + func (p *Proxy) connect(ctx context.Context, state request.Request, forceTCP, metric bool) (*dns.Msg, error) { start := time.Now() @@ -35,6 +49,7 @@ func (p *Proxy) connect(ctx context.Context, state request.Request, forceTCP, me } conn.SetWriteDeadline(time.Now().Add(timeout)) + reqTime := time.Now() if err := conn.WriteMsg(state.Req); err != nil { conn.Close() // not giving it back if err == io.EOF && cached { @@ -43,9 +58,10 @@ func (p *Proxy) connect(ctx context.Context, state request.Request, forceTCP, me return nil, err } - conn.SetReadDeadline(time.Now().Add(timeout)) + conn.SetReadDeadline(time.Now().Add(p.readTimeout())) ret, err := conn.ReadMsg() if err != nil { + p.updateRtt(timeout) conn.Close() // not giving it back if err == io.EOF && cached { return nil, errCachedClosed @@ -53,6 +69,8 @@ func (p *Proxy) connect(ctx context.Context, state request.Request, forceTCP, me return nil, err } + p.updateRtt(time.Since(reqTime)) + p.Yield(conn) if metric { @@ -68,3 +86,5 @@ func (p *Proxy) connect(ctx context.Context, state request.Request, forceTCP, me return ret, nil } + +const rttCount = 4 |