mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 18:23:13 -04:00 
			
		
		
		
	* 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>
		
			
				
	
	
		
			83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package forward
 | |
| 
 | |
| import (
 | |
| 	"crypto/tls"
 | |
| 	"runtime"
 | |
| 	"sync/atomic"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/coredns/coredns/plugin/pkg/up"
 | |
| )
 | |
| 
 | |
| // Proxy defines an upstream host.
 | |
| type Proxy struct {
 | |
| 	avgRtt int64
 | |
| 	fails  uint32
 | |
| 
 | |
| 	addr string
 | |
| 
 | |
| 	// Connection caching
 | |
| 	expire    time.Duration
 | |
| 	transport *transport
 | |
| 
 | |
| 	// health checking
 | |
| 	probe  *up.Probe
 | |
| 	health HealthChecker
 | |
| }
 | |
| 
 | |
| // NewProxy returns a new proxy.
 | |
| func NewProxy(addr string, protocol int) *Proxy {
 | |
| 	p := &Proxy{
 | |
| 		addr:      addr,
 | |
| 		fails:     0,
 | |
| 		probe:     up.New(),
 | |
| 		transport: newTransport(addr),
 | |
| 		avgRtt:    int64(maxTimeout / 2),
 | |
| 	}
 | |
| 	p.health = NewHealthChecker(protocol)
 | |
| 	runtime.SetFinalizer(p, (*Proxy).finalizer)
 | |
| 	return p
 | |
| }
 | |
| 
 | |
| // 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.health.SetTLSConfig(cfg)
 | |
| }
 | |
| 
 | |
| // SetExpire sets the expire duration in the lower p.transport.
 | |
| func (p *Proxy) SetExpire(expire time.Duration) { p.transport.SetExpire(expire) }
 | |
| 
 | |
| // Healthcheck kicks of a round of health checks for this proxy.
 | |
| 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 {
 | |
| 	if maxfails == 0 {
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	fails := atomic.LoadUint32(&p.fails)
 | |
| 	return fails > maxfails
 | |
| }
 | |
| 
 | |
| // close stops the health checking goroutine.
 | |
| 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) {
 | |
| 	p.probe.Start(duration)
 | |
| 	p.transport.Start()
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	maxTimeout = 2 * time.Second
 | |
| 	minTimeout = 200 * time.Millisecond
 | |
| 	hcInterval = 500 * time.Millisecond
 | |
| )
 |