mirror of
https://github.com/coredns/coredns.git
synced 2025-10-27 16:24:19 -04:00
plugin/forward: make Yield not block (#3336)
* plugin/forward: may Yield not block Yield may block when we're super busy with creating (and looking) for connection. Set a small timeout on Yield, to skip putting the connection back in the queue. Use persistentConn troughout the socket handling code to be more consistent. Signed-off-by: Miek Gieben <miek@miek.nl> Dont do Signed-off-by: Miek Gieben <miek@miek.nl> * Set used in Yield This gives one central place where we update used in the persistConns Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
@@ -44,17 +44,17 @@ func (t *Transport) updateDialTimeout(newDialTime time.Duration) {
|
||||
}
|
||||
|
||||
// Dial dials the address configured in transport, potentially reusing a connection or creating a new one.
|
||||
func (t *Transport) Dial(proto string) (*dns.Conn, bool, error) {
|
||||
func (t *Transport) Dial(proto string) (*persistConn, bool, error) {
|
||||
// If tls has been configured; use it.
|
||||
if t.tlsConfig != nil {
|
||||
proto = "tcp-tls"
|
||||
}
|
||||
|
||||
t.dial <- proto
|
||||
c := <-t.ret
|
||||
pc := <-t.ret
|
||||
|
||||
if c != nil {
|
||||
return c, true, nil
|
||||
if pc != nil {
|
||||
return pc, true, nil
|
||||
}
|
||||
|
||||
reqTime := time.Now()
|
||||
@@ -62,11 +62,11 @@ func (t *Transport) Dial(proto string) (*dns.Conn, bool, error) {
|
||||
if proto == "tcp-tls" {
|
||||
conn, err := dns.DialTimeoutWithTLS("tcp", t.addr, t.tlsConfig, timeout)
|
||||
t.updateDialTimeout(time.Since(reqTime))
|
||||
return conn, false, err
|
||||
return &persistConn{c: conn}, false, err
|
||||
}
|
||||
conn, err := dns.DialTimeout(proto, t.addr, timeout)
|
||||
t.updateDialTimeout(time.Since(reqTime))
|
||||
return conn, false, err
|
||||
return &persistConn{c: conn}, false, err
|
||||
}
|
||||
|
||||
// Connect selects an upstream, sends the request and waits for a response.
|
||||
@@ -83,20 +83,20 @@ func (p *Proxy) Connect(ctx context.Context, state request.Request, opts options
|
||||
proto = state.Proto()
|
||||
}
|
||||
|
||||
conn, cached, err := p.transport.Dial(proto)
|
||||
pc, cached, err := p.transport.Dial(proto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set buffer size correctly for this client.
|
||||
conn.UDPSize = uint16(state.Size())
|
||||
if conn.UDPSize < 512 {
|
||||
conn.UDPSize = 512
|
||||
pc.c.UDPSize = uint16(state.Size())
|
||||
if pc.c.UDPSize < 512 {
|
||||
pc.c.UDPSize = 512
|
||||
}
|
||||
|
||||
conn.SetWriteDeadline(time.Now().Add(maxTimeout))
|
||||
if err := conn.WriteMsg(state.Req); err != nil {
|
||||
conn.Close() // not giving it back
|
||||
pc.c.SetWriteDeadline(time.Now().Add(maxTimeout))
|
||||
if err := pc.c.WriteMsg(state.Req); err != nil {
|
||||
pc.c.Close() // not giving it back
|
||||
if err == io.EOF && cached {
|
||||
return nil, ErrCachedClosed
|
||||
}
|
||||
@@ -104,11 +104,11 @@ func (p *Proxy) Connect(ctx context.Context, state request.Request, opts options
|
||||
}
|
||||
|
||||
var ret *dns.Msg
|
||||
conn.SetReadDeadline(time.Now().Add(readTimeout))
|
||||
pc.c.SetReadDeadline(time.Now().Add(readTimeout))
|
||||
for {
|
||||
ret, err = conn.ReadMsg()
|
||||
ret, err = pc.c.ReadMsg()
|
||||
if err != nil {
|
||||
conn.Close() // not giving it back
|
||||
pc.c.Close() // not giving it back
|
||||
if err == io.EOF && cached {
|
||||
return nil, ErrCachedClosed
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func (p *Proxy) Connect(ctx context.Context, state request.Request, opts options
|
||||
}
|
||||
}
|
||||
|
||||
p.transport.Yield(conn)
|
||||
p.transport.Yield(pc)
|
||||
|
||||
rc, ok := dns.RcodeToString[ret.Rcode]
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user