godns/hosts.go

94 lines
1.5 KiB
Go
Raw Permalink Normal View History

2013-07-26 04:06:16 +00:00
package main
import (
2015-02-03 12:32:18 +00:00
"net"
"time"
2015-02-03 12:32:18 +00:00
"github.com/hoisie/redis"
2019-09-26 04:43:17 +00:00
)
2013-07-26 04:06:16 +00:00
2013-07-26 10:54:19 +00:00
type Hosts struct {
2019-09-26 04:43:17 +00:00
providers []HostProvider
refreshInterval time.Duration
2013-07-26 04:06:16 +00:00
}
2018-07-01 03:08:29 +00:00
type HostProvider interface {
Get(domain string) ([]string, bool)
Refresh()
}
2013-07-26 10:54:19 +00:00
func NewHosts(hs HostsSettings, rs RedisSettings) Hosts {
2018-07-01 03:08:29 +00:00
providers := []HostProvider{
NewFileProvider(hs.HostsFile),
}
2015-02-03 15:03:47 +00:00
if hs.RedisEnable {
2018-08-05 04:05:47 +00:00
logger.Info("Redis is enabled: %s", rs.Addr())
2015-02-11 10:01:05 +00:00
rc := &redis.Client{Addr: rs.Addr(), Db: rs.DB, Password: rs.Password}
2018-07-01 03:08:29 +00:00
providers = append(providers, NewRedisProvider(rc, hs.RedisKey))
2015-02-03 15:03:47 +00:00
}
2013-07-26 10:54:19 +00:00
2018-08-05 04:22:37 +00:00
h := Hosts{providers, time.Second * time.Duration(hs.RefreshInterval)}
2018-08-05 08:48:26 +00:00
if h.refreshInterval > 0 {
h.refresh()
}
2018-08-05 04:22:37 +00:00
return h
2018-07-01 03:08:29 +00:00
}
2013-07-26 10:54:19 +00:00
2018-07-01 03:08:29 +00:00
func (h *Hosts) refresh() {
ticker := time.NewTicker(h.refreshInterval)
go func() {
for {
// Force a refresh every refreshInterval
for _, provider := range h.providers {
provider.Refresh()
}
<-ticker.C
}
}()
2013-07-26 10:54:19 +00:00
}
/*
2015-10-14 04:41:08 +00:00
Match local /etc/hosts file first, remote redis records second
2013-07-26 10:54:19 +00:00
*/
2015-10-14 17:08:25 +00:00
func (h *Hosts) Get(domain string, family int) ([]net.IP, bool) {
var sips []string
2018-07-01 03:08:29 +00:00
var ok bool
2015-10-14 17:08:25 +00:00
var ip net.IP
var ips []net.IP
2015-02-12 06:54:02 +00:00
2018-07-01 03:08:29 +00:00
for _, provider := range h.providers {
sips, ok = provider.Get(domain)
if ok {
break
2015-02-12 06:54:02 +00:00
}
2013-07-26 10:54:19 +00:00
}
2015-02-03 12:32:18 +00:00
2015-10-14 17:08:25 +00:00
if sips == nil {
2015-02-12 06:54:02 +00:00
return nil, false
2013-07-26 10:54:19 +00:00
}
2015-10-14 17:08:25 +00:00
for _, sip := range sips {
switch family {
case _IP4Query:
ip = net.ParseIP(sip).To4()
case _IP6Query:
ip = net.ParseIP(sip).To16()
default:
continue
}
if ip != nil {
ips = append(ips, ip)
}
2015-02-12 06:54:02 +00:00
}
2015-10-14 17:08:25 +00:00
2018-07-01 03:08:29 +00:00
return ips, ips != nil
}