mirror of
https://github.com/folbricht/routedns.git
synced 2026-01-12 20:50:02 -06:00
* Add metric tracking * Clean up metrics structures. * Add available route metric to router.
48 lines
1.1 KiB
Go
48 lines
1.1 KiB
Go
package rdns
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
// RoundRobin is a group of resolvers that will receive equal amounts of queries.
|
|
// Failed queries are not retried.
|
|
type RoundRobin struct {
|
|
id string
|
|
resolvers []Resolver
|
|
mu sync.Mutex
|
|
current int
|
|
metrics *RouterMetrics
|
|
}
|
|
|
|
var _ Resolver = &RoundRobin{}
|
|
|
|
// NewRoundRobin returns a new instance of a round-robin resolver group.
|
|
func NewRoundRobin(id string, resolvers ...Resolver) *RoundRobin {
|
|
return &RoundRobin{
|
|
id: id,
|
|
resolvers: resolvers,
|
|
metrics: NewRouterMetrics(id, len(resolvers)),
|
|
}
|
|
}
|
|
|
|
// Resolve a DNS query using a round-robin resolver group.
|
|
func (r *RoundRobin) Resolve(q *dns.Msg, ci ClientInfo) (*dns.Msg, error) {
|
|
r.mu.Lock()
|
|
resolver := r.resolvers[r.current]
|
|
r.current = (r.current + 1) % len(r.resolvers)
|
|
r.mu.Unlock()
|
|
logger(r.id, q, ci).WithField("resolver", resolver).Debug("forwarding query to resolver")
|
|
r.metrics.route.Add(resolver.String(), 1)
|
|
msg, err := resolver.Resolve(q, ci)
|
|
if err != nil {
|
|
r.metrics.failure.Add(resolver.String(), 1)
|
|
}
|
|
return msg, err
|
|
}
|
|
|
|
func (r *RoundRobin) String() string {
|
|
return r.id
|
|
}
|