plugin/forward: add HealthChecker interface (#1950)

* plugin/forward: add HealthChecker interface

Make the HealthChecker interface and morph the current DNS health
checker into that interface.

Remove all whole bunch of method on Forward that didn't make sense.

This is done in preparation of adding a DoH client to forward - which
requires a completely different healthcheck implementation (and more,
but lets start here)

Signed-off-by: Miek Gieben <miek@miek.nl>

* Use protocol

Signed-off-by: Miek Gieben <miek@miek.nl>

* Dial doesnt need to be method an Forward either

Signed-off-by: Miek Gieben <miek@miek.nl>

* Address comments

Address various comments on the PR.

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2018-07-09 15:14:55 +01:00
committed by GitHub
parent 4083852b70
commit a536833546
13 changed files with 77 additions and 76 deletions

View File

@@ -7,8 +7,6 @@ import (
"time"
"github.com/coredns/coredns/plugin/pkg/up"
"github.com/miekg/dns"
)
// Proxy defines an upstream host.
@@ -16,69 +14,46 @@ type Proxy struct {
avgRtt int64
fails uint32
addr string
client *dns.Client
addr string
// Connection caching
expire time.Duration
transport *transport
// health checking
probe *up.Probe
probe *up.Probe
health HealthChecker
}
// NewProxy returns a new proxy.
func NewProxy(addr string, tlsConfig *tls.Config) *Proxy {
func NewProxy(addr string, protocol int) *Proxy {
p := &Proxy{
addr: addr,
fails: 0,
probe: up.New(),
transport: newTransport(addr, tlsConfig),
transport: newTransport(addr),
avgRtt: int64(maxTimeout / 2),
}
p.client = dnsClient(tlsConfig)
p.health = NewHealthChecker(protocol)
runtime.SetFinalizer(p, (*Proxy).finalizer)
return p
}
// Addr returns the address to forward to.
func (p *Proxy) Addr() (addr string) { return p.addr }
// dnsClient returns a client used for health checking.
func dnsClient(tlsConfig *tls.Config) *dns.Client {
c := new(dns.Client)
c.Net = "udp"
// TODO(miek): this should be half of hcDuration?
c.ReadTimeout = 1 * time.Second
c.WriteTimeout = 1 * time.Second
if tlsConfig != nil {
c.Net = "tcp-tls"
c.TLSConfig = tlsConfig
}
return c
}
// SetTLSConfig sets the TLS config in the lower p.transport and in the healthchecking client.
func (p *Proxy) SetTLSConfig(cfg *tls.Config) {
p.transport.SetTLSConfig(cfg)
p.client = dnsClient(cfg)
p.health.SetTLSConfig(cfg)
}
// IsTLS returns true if proxy uses tls.
func (p *Proxy) IsTLS() bool { return p.transport.tlsConfig != nil }
// SetExpire sets the expire duration in the lower p.transport.
func (p *Proxy) SetExpire(expire time.Duration) { p.transport.SetExpire(expire) }
// Dial connects to the host in p with the configured transport.
func (p *Proxy) Dial(proto string) (*dns.Conn, bool, error) { return p.transport.Dial(proto) }
// Yield returns the connection to the pool.
func (p *Proxy) Yield(c *dns.Conn) { p.transport.Yield(c) }
// Healthcheck kicks of a round of health checks for this proxy.
func (p *Proxy) Healthcheck() { p.probe.Do(p.Check) }
func (p *Proxy) Healthcheck() {
p.probe.Do(func() error {
return p.health.Check(p)
})
}
// Down returns true if this proxy is down, i.e. has *more* fails than maxfails.
func (p *Proxy) Down(maxfails uint32) bool {
@@ -91,13 +66,8 @@ func (p *Proxy) Down(maxfails uint32) bool {
}
// close stops the health checking goroutine.
func (p *Proxy) close() {
p.probe.Stop()
}
func (p *Proxy) finalizer() {
p.transport.Stop()
}
func (p *Proxy) close() { p.probe.Stop() }
func (p *Proxy) finalizer() { p.transport.Stop() }
// start starts the proxy's healthchecking.
func (p *Proxy) start(duration time.Duration) {