Redo settings a bit, move a lot of init logic to main.go
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
991ae3ecb5
commit
f726a5d5ae
|
@ -7,7 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRedisCache(c settings.RedisSettings, expire int32) *RedisCache {
|
func NewRedisCache(c settings.RedisSettings, expire time.Duration) *RedisCache {
|
||||||
rc := redis.NewClient(&redis.Options{Addr: c.Addr(), DB: c.DB, Password: c.Password})
|
rc := redis.NewClient(&redis.Options{Addr: c.Addr(), DB: c.DB, Password: c.Password})
|
||||||
|
|
||||||
return &RedisCache{
|
return &RedisCache{
|
||||||
|
@ -20,7 +20,7 @@ type RedisCache struct {
|
||||||
Cache
|
Cache
|
||||||
|
|
||||||
backend *redis.Client
|
backend *redis.Client
|
||||||
expire int32
|
expire time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RedisCache) Set(key string, msg *dns.Msg) error {
|
func (m *RedisCache) Set(key string, msg *dns.Msg) error {
|
||||||
|
@ -38,7 +38,7 @@ func (m *RedisCache) Set(key string, msg *dns.Msg) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = SerializerError{err}
|
err = SerializerError{err}
|
||||||
}
|
}
|
||||||
return m.backend.Set(key, val, time.Duration(m.expire) * time.Second).Err()
|
return m.backend.Set(key, val, m.expire).Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RedisCache) Get(key string) (*dns.Msg, error) {
|
func (m *RedisCache) Get(key string) (*dns.Msg, error) {
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
server=/adcdownload.apple.com/114.114.114.114
|
|
||||||
server=/appldnld.apple.com/114.114.114.114
|
|
||||||
server=/cdn-cn1.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn-cn2.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn-cn3.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn-cn4.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn1.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn2.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn3.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cdn4.apple-mapkit.com/114.114.114.114
|
|
||||||
server=/cds.apple.com/114.114.114.114
|
|
||||||
server=/cl1.apple.com/114.114.114.114
|
|
||||||
server=/cl2.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114
|
|
||||||
server=/cl2.apple.com.edgekey.net/114.114.114.114
|
|
||||||
server=/cl2.apple.com/114.114.114.114
|
|
||||||
server=/cl3.apple.com/114.114.114.114
|
|
||||||
server=/cl4.apple.com/114.114.114.114
|
|
||||||
server=/cl5.apple.com/114.114.114.114
|
|
||||||
server=/gsp11-cn.ls.apple.com/114.114.114.114
|
|
||||||
server=/gsp12-cn.ls.apple.com/114.114.114.114
|
|
||||||
server=/gsp13-cn.ls.apple.com/114.114.114.114
|
|
||||||
server=/gsp4-cn.ls.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114
|
|
||||||
server=/gsp4-cn.ls.apple.com.edgekey.net/114.114.114.114
|
|
||||||
server=/gsp4-cn.ls.apple.com/114.114.114.114
|
|
||||||
server=/gsp5-cn.ls.apple.com/114.114.114.114
|
|
||||||
server=/gspe19-cn.ls-apple.com.akadns.net/114.114.114.114
|
|
||||||
server=/gspe19-cn.ls.apple.com/114.114.114.114
|
|
||||||
server=/gspe21.ls.apple.com/114.114.114.114
|
|
||||||
server=/gspe21-ssl.ls.apple.com/114.114.114.114
|
|
||||||
server=/gspe35-ssl.ls.apple.com/114.114.114.114
|
|
||||||
server=/icloud.cdn-apple.com/114.114.114.114
|
|
||||||
server=/images.apple.com/114.114.114.114
|
|
||||||
server=/itunes-apple.com.akadns.net/114.114.114.114
|
|
||||||
server=/itunes.apple.com/114.114.114.114
|
|
||||||
server=/itunesconnect.apple.com/114.114.114.114
|
|
||||||
server=/mesu.apple.com/114.114.114.114
|
|
||||||
server=/mesu-china.apple.com.akadns.net/114.114.114.114
|
|
||||||
server=/phobos-apple.com.akadns.net/114.114.114.114
|
|
||||||
server=/phobos.apple.com/114.114.114.114
|
|
||||||
server=/store.apple.com/114.114.114.114
|
|
||||||
server=/store.storeimages.cdn-apple.com/114.114.114.114
|
|
||||||
server=/support.apple.com/114.114.114.114
|
|
||||||
server=/swcdn.apple.com/114.114.114.114
|
|
||||||
server=/swdist.apple.com/114.114.114.114
|
|
||||||
server=/www.apple.com/114.114.114.114
|
|
|
@ -1,58 +1,48 @@
|
||||||
#Toml config file
|
#Toml config file
|
||||||
|
debug = false
|
||||||
|
|
||||||
Title = "GODNS"
|
|
||||||
Version = "0.2.0"
|
|
||||||
Author = "kenshin, tystuyfzand"
|
|
||||||
|
|
||||||
Debug = false
|
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
nets = ["tcp:53", "udp:53"]
|
nets = ["tcp:53", "udp:53"]
|
||||||
|
|
||||||
[resolv]
|
[resolv]
|
||||||
# Domain-specific nameservers configuration, formatting keep compatible with Dnsmasq
|
file = ""
|
||||||
# Semicolon separate multiple files.
|
|
||||||
resolv-file = ""
|
|
||||||
timeout = 5 # 5 seconds
|
timeout = 5 # 5 seconds
|
||||||
# The concurrency interval request upstream recursive server
|
|
||||||
# Match the PR15, https://github.com/kenshinx/godns/pull/15
|
|
||||||
interval = 200 # 200 milliseconds
|
interval = 200 # 200 milliseconds
|
||||||
setedns0 = false #Support for larger UDP DNS responses
|
edns0 = false #Support for larger UDP DNS responses
|
||||||
server-list-file = "etc/serverlist.conf"
|
# Domain-specific nameservers configuration, formatting keep compatible with Dnsmasq
|
||||||
|
server-list = "etc/serverlist.conf"
|
||||||
[redis]
|
|
||||||
enable = true
|
|
||||||
host = "192.168.1.71"
|
|
||||||
port = 6379
|
|
||||||
db = 0
|
|
||||||
password =""
|
|
||||||
|
|
||||||
[memcache]
|
|
||||||
servers = ["127.0.0.1:11211"]
|
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
stdout = true
|
stdout = true
|
||||||
file = "./godns.log"
|
file = "./godns.log"
|
||||||
level = "DEBUG" #DEBUG | INFO |NOTICE | WARN | ERROR
|
level = "DEBUG" #DEBUG | INFO |NOTICE | WARN | ERROR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[cache]
|
[cache]
|
||||||
# backend option [memory|memcache|redis]
|
# backend option [memory|memcache|redis]
|
||||||
# redis backend not implemented yet
|
|
||||||
backend = "memory"
|
backend = "memory"
|
||||||
expire = 600 # 10 minutes
|
expire = 600 # 10 minutes
|
||||||
maxcount = 0 #If set zero. The Sum of cache itmes will be unlimit.
|
maxcount = 0 #If set zero. The Sum of cache itmes will be unlimit.
|
||||||
|
|
||||||
|
[cache.memcached]
|
||||||
|
servers = ["127.0.0.1:11211"]
|
||||||
|
|
||||||
|
# Redis cache backend config
|
||||||
|
[cache.redis]
|
||||||
|
host = "192.168.1.71"
|
||||||
|
port = 6379
|
||||||
|
db = 0
|
||||||
|
password =""
|
||||||
|
|
||||||
[hosts]
|
[hosts]
|
||||||
#If set false, will not query hosts file and redis hosts record
|
# File provider, supports inotify hot-reload
|
||||||
|
[hosts.file]
|
||||||
enable = true
|
enable = true
|
||||||
host-file = "/etc/hosts"
|
file = "/etc/hosts"
|
||||||
redis-enable = true
|
|
||||||
redis-key = "godns:hosts"
|
|
||||||
ttl = 600
|
ttl = 600
|
||||||
refresh-interval = 60 # 5 seconds
|
|
||||||
|
|
||||||
|
|
||||||
|
# Redis provider
|
||||||
|
[hosts.redis]
|
||||||
|
enable = true
|
||||||
|
key = "godns:hosts"
|
||||||
|
ttl = 600
|
|
@ -1,42 +0,0 @@
|
||||||
server=/265.com/114.114.114.114
|
|
||||||
server=/2mdn.net/114.114.114.114
|
|
||||||
server=/app-measurement.com/114.114.114.114
|
|
||||||
server=/beacons.gcp.gvt2.com/114.114.114.114
|
|
||||||
server=/beacons.gvt2.com/114.114.114.114
|
|
||||||
server=/beacons3.gvt2.com/114.114.114.114
|
|
||||||
server=/c.admob.com/114.114.114.114
|
|
||||||
server=/c.android.clients.google.com/114.114.114.114
|
|
||||||
server=/cache.pack.google.com/114.114.114.114
|
|
||||||
server=/clientservices.googleapis.com/114.114.114.114
|
|
||||||
server=/connectivitycheck.gstatic.com/114.114.114.114
|
|
||||||
server=/csi.gstatic.com/114.114.114.114
|
|
||||||
server=/dl.google.com/114.114.114.114
|
|
||||||
server=/doubleclick.net/114.114.114.114
|
|
||||||
server=/e.admob.com/114.114.114.114
|
|
||||||
server=/fonts.googleapis.com/114.114.114.114
|
|
||||||
server=/fonts.gstatic.com/114.114.114.114
|
|
||||||
server=/google-analytics.com/114.114.114.114
|
|
||||||
server=/googleadservices.com/114.114.114.114
|
|
||||||
server=/googleanalytics.com/114.114.114.114
|
|
||||||
server=/googlesyndication.com/114.114.114.114
|
|
||||||
server=/googletagmanager.com/114.114.114.114
|
|
||||||
server=/googletagservices.com/114.114.114.114
|
|
||||||
server=/imasdk.googleapis.com/114.114.114.114
|
|
||||||
server=/kh.google.com/114.114.114.114
|
|
||||||
server=/khm.google.com/114.114.114.114
|
|
||||||
server=/khm.googleapis.com/114.114.114.114
|
|
||||||
server=/khm0.google.com/114.114.114.114
|
|
||||||
server=/khm0.googleapis.com/114.114.114.114
|
|
||||||
server=/khm1.google.com/114.114.114.114
|
|
||||||
server=/khm1.googleapis.com/114.114.114.114
|
|
||||||
server=/khm2.google.com/114.114.114.114
|
|
||||||
server=/khm2.googleapis.com/114.114.114.114
|
|
||||||
server=/khm3.google.com/114.114.114.114
|
|
||||||
server=/khm3.googleapis.com/114.114.114.114
|
|
||||||
server=/khmdb.google.com/114.114.114.114
|
|
||||||
server=/khmdb.googleapis.com/114.114.114.114
|
|
||||||
server=/media.admob.com/114.114.114.114
|
|
||||||
server=/mediavisor.doubleclick.com/114.114.114.114
|
|
||||||
server=/redirector.gvt1.com/114.114.114.114
|
|
||||||
server=/toolbarqueries.google.com/114.114.114.114
|
|
||||||
server=/update.googleapis.com/114.114.114.114
|
|
59
handler.go
59
handler.go
|
@ -3,16 +3,14 @@ package main
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/miekg/dns"
|
||||||
"meow.tf/joker/godns/cache"
|
"meow.tf/joker/godns/cache"
|
||||||
"meow.tf/joker/godns/hosts"
|
"meow.tf/joker/godns/hosts"
|
||||||
"meow.tf/joker/godns/log"
|
"meow.tf/joker/godns/log"
|
||||||
"meow.tf/joker/godns/resolver"
|
"meow.tf/joker/godns/resolver"
|
||||||
"meow.tf/joker/godns/settings"
|
|
||||||
"meow.tf/joker/godns/utils"
|
"meow.tf/joker/godns/utils"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -21,54 +19,17 @@ const (
|
||||||
_IP6Query = 6
|
_IP6Query = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
type GODNSHandler struct {
|
type Handler struct {
|
||||||
resolver *resolver.Resolver
|
resolver *resolver.Resolver
|
||||||
cache, negCache cache.Cache
|
cache, negCache cache.Cache
|
||||||
hosts hosts.Hosts
|
hosts hosts.Hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler() *GODNSHandler {
|
func NewHandler(r *resolver.Resolver, resolverCache, negCache cache.Cache, h hosts.Hosts) *Handler {
|
||||||
|
return &Handler{r, resolverCache, negCache, h}
|
||||||
var (
|
|
||||||
cacheConfig settings.CacheSettings
|
|
||||||
r *resolver.Resolver
|
|
||||||
resolverCache, negCache cache.Cache
|
|
||||||
)
|
|
||||||
|
|
||||||
r = resolver.NewResolver(settings.Resolver())
|
|
||||||
|
|
||||||
cacheConfig = settings.Cache()
|
|
||||||
switch cacheConfig.Backend {
|
|
||||||
case "memory":
|
|
||||||
cacheDuration := time.Duration(cacheConfig.Expire) * time.Second
|
|
||||||
|
|
||||||
negCache = cache.NewMemoryCache(cacheDuration/2, cacheConfig.Maxcount)
|
|
||||||
resolverCache = cache.NewMemoryCache(time.Duration(cacheConfig.Expire)*time.Second, cacheConfig.Maxcount)
|
|
||||||
case "memcache":
|
|
||||||
resolverCache = cache.NewMemcachedCache(
|
|
||||||
settings.Memcache().Servers,
|
|
||||||
int32(cacheConfig.Expire))
|
|
||||||
negCache = cache.NewMemcachedCache(
|
|
||||||
settings.Memcache().Servers,
|
|
||||||
int32(cacheConfig.Expire/2))
|
|
||||||
case "redis":
|
|
||||||
resolverCache = cache.NewRedisCache(
|
|
||||||
settings.Redis(),
|
|
||||||
int32(cacheConfig.Expire))
|
|
||||||
negCache = cache.NewRedisCache(
|
|
||||||
settings.Redis(),
|
|
||||||
int32(cacheConfig.Expire/2))
|
|
||||||
default:
|
|
||||||
log.Error("Invalid cache backend %s", cacheConfig.Backend)
|
|
||||||
panic("Invalid cache backend")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h := hosts.NewHosts(settings.Hosts(), settings.Redis())
|
func (h *Handler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
|
||||||
|
|
||||||
return &GODNSHandler{r, resolverCache, negCache, h}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
|
|
||||||
q := req.Question[0]
|
q := req.Question[0]
|
||||||
question := resolver.Question{Name: utils.UnFqdn(q.Name), Type: dns.TypeToString[q.Qtype], Class: dns.ClassToString[q.Qclass]}
|
question := resolver.Question{Name: utils.UnFqdn(q.Name), Type: dns.TypeToString[q.Qtype], Class: dns.ClassToString[q.Qclass]}
|
||||||
|
|
||||||
|
@ -84,7 +45,7 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
|
||||||
|
|
||||||
// Query hosts
|
// Query hosts
|
||||||
if h.hosts != nil && IPQuery > 0 {
|
if h.hosts != nil && IPQuery > 0 {
|
||||||
if ips, ok := h.hosts.Get(question.Name, IPQuery); ok {
|
if ips, ttl, ok := h.hosts.Get(question.Name, IPQuery); ok {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetReply(req)
|
m.SetReply(req)
|
||||||
|
|
||||||
|
@ -94,7 +55,7 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
|
||||||
Name: q.Name,
|
Name: q.Name,
|
||||||
Rrtype: dns.TypeA,
|
Rrtype: dns.TypeA,
|
||||||
Class: dns.ClassINET,
|
Class: dns.ClassINET,
|
||||||
Ttl: h.hosts.TTL(),
|
Ttl: uint32(ttl / time.Second),
|
||||||
}
|
}
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
m.Answer = append(m.Answer, &dns.A{Hdr: hdr, A: ip})
|
m.Answer = append(m.Answer, &dns.A{Hdr: hdr, A: ip})
|
||||||
|
@ -104,7 +65,7 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
|
||||||
Name: q.Name,
|
Name: q.Name,
|
||||||
Rrtype: dns.TypeAAAA,
|
Rrtype: dns.TypeAAAA,
|
||||||
Class: dns.ClassINET,
|
Class: dns.ClassINET,
|
||||||
Ttl: h.hosts.TTL(),
|
Ttl: uint32(ttl / time.Second),
|
||||||
}
|
}
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
m.Answer = append(m.Answer, &dns.AAAA{Hdr: hdr, AAAA: ip})
|
m.Answer = append(m.Answer, &dns.AAAA{Hdr: hdr, AAAA: ip})
|
||||||
|
@ -165,13 +126,13 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *GODNSHandler) Bind(net string) func(w dns.ResponseWriter, req *dns.Msg) {
|
func (h *Handler) Bind(net string) func(w dns.ResponseWriter, req *dns.Msg) {
|
||||||
return func(w dns.ResponseWriter, req *dns.Msg) {
|
return func(w dns.ResponseWriter, req *dns.Msg) {
|
||||||
h.do(net, w, req)
|
h.do(net, w, req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *GODNSHandler) isIPQuery(q dns.Question) int {
|
func (h *Handler) isIPQuery(q dns.Question) int {
|
||||||
if q.Qclass != dns.ClassINET {
|
if q.Qclass != dns.ClassINET {
|
||||||
return notIPQuery
|
return notIPQuery
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
package hosts
|
package hosts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"meow.tf/joker/godns/log"
|
|
||||||
"meow.tf/joker/godns/settings"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hoisie/redis"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -15,70 +11,38 @@ const (
|
||||||
_IP6Query = 6
|
_IP6Query = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
zeroDuration = time.Duration(0)
|
||||||
|
)
|
||||||
|
|
||||||
type Hosts interface {
|
type Hosts interface {
|
||||||
Get(domain string, family int) ([]net.IP, bool)
|
Get(domain string, family int) ([]net.IP, time.Duration, bool)
|
||||||
TTL() uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderList struct {
|
type ProviderList struct {
|
||||||
settings settings.HostsSettings
|
providers []Provider
|
||||||
providers []HostProvider
|
|
||||||
refreshInterval time.Duration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type HostProvider interface {
|
type Provider interface {
|
||||||
Get(domain string) ([]string, bool)
|
Get(domain string) ([]string, time.Duration, bool)
|
||||||
Refresh()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHosts(hs settings.HostsSettings, rs settings.RedisSettings) Hosts {
|
func NewHosts(providers []Provider) Hosts {
|
||||||
providers := []HostProvider{
|
return &ProviderList{providers}
|
||||||
NewFileProvider(hs.HostsFile),
|
|
||||||
}
|
|
||||||
|
|
||||||
if hs.RedisEnable {
|
|
||||||
log.Info("Redis is enabled: %s", rs.Addr())
|
|
||||||
|
|
||||||
rc := &redis.Client{Addr: rs.Addr(), Db: rs.DB, Password: rs.Password}
|
|
||||||
|
|
||||||
providers = append(providers, NewRedisProvider(rc, hs.RedisKey))
|
|
||||||
}
|
|
||||||
|
|
||||||
h := &ProviderList{hs, providers, time.Second * time.Duration(hs.RefreshInterval)}
|
|
||||||
|
|
||||||
if h.refreshInterval > 0 {
|
|
||||||
h.refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *ProviderList) refresh() {
|
|
||||||
ticker := time.NewTicker(h.refreshInterval)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
// Force a refresh every refreshInterval
|
|
||||||
for _, provider := range h.providers {
|
|
||||||
provider.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
<-ticker.C
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Match local /etc/hosts file first, remote redis records second
|
Match local /etc/hosts file first, remote redis records second
|
||||||
*/
|
*/
|
||||||
func (h *ProviderList) Get(domain string, family int) ([]net.IP, bool) {
|
func (h *ProviderList) Get(domain string, family int) ([]net.IP, time.Duration, bool) {
|
||||||
var sips []string
|
var sips []string
|
||||||
var ok bool
|
var ok bool
|
||||||
var ip net.IP
|
var ip net.IP
|
||||||
var ips []net.IP
|
var ips []net.IP
|
||||||
|
var ttl time.Duration
|
||||||
|
|
||||||
for _, provider := range h.providers {
|
for _, provider := range h.providers {
|
||||||
sips, ok = provider.Get(domain)
|
sips, ttl, ok = provider.Get(domain)
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
break
|
break
|
||||||
|
@ -86,7 +50,7 @@ func (h *ProviderList) Get(domain string, family int) ([]net.IP, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if sips == nil {
|
if sips == nil {
|
||||||
return nil, false
|
return nil, zeroDuration, false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sip := range sips {
|
for _, sip := range sips {
|
||||||
|
@ -103,9 +67,5 @@ func (h *ProviderList) Get(domain string, family int) ([]net.IP, bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ips, ips != nil
|
return ips, ttl, ips != nil
|
||||||
}
|
|
||||||
|
|
||||||
func (h *ProviderList) TTL() uint32 {
|
|
||||||
return h.settings.TTL
|
|
||||||
}
|
}
|
|
@ -10,20 +10,23 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FileHosts struct {
|
type FileHosts struct {
|
||||||
HostProvider
|
Provider
|
||||||
|
|
||||||
file string
|
file string
|
||||||
hosts map[string]string
|
hosts map[string]string
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
ttl time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileProvider(file string) HostProvider {
|
func NewFileProvider(file string, ttl time.Duration) Provider {
|
||||||
fp := &FileHosts{
|
fp := &FileHosts{
|
||||||
file: file,
|
file: file,
|
||||||
hosts: make(map[string]string),
|
hosts: make(map[string]string),
|
||||||
|
ttl: ttl,
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
@ -46,7 +49,7 @@ func NewFileProvider(file string) HostProvider {
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileHosts) Get(domain string) ([]string, bool) {
|
func (f *FileHosts) Get(domain string) ([]string, time.Duration, bool) {
|
||||||
log.Debug("Checking file provider for %s", domain)
|
log.Debug("Checking file provider for %s", domain)
|
||||||
|
|
||||||
f.mu.RLock()
|
f.mu.RLock()
|
||||||
|
@ -54,24 +57,24 @@ func (f *FileHosts) Get(domain string) ([]string, bool) {
|
||||||
domain = strings.ToLower(domain)
|
domain = strings.ToLower(domain)
|
||||||
|
|
||||||
if ip, ok := f.hosts[domain]; ok {
|
if ip, ok := f.hosts[domain]; ok {
|
||||||
return strings.Split(ip, ","), true
|
return strings.Split(ip, ","), f.ttl, true
|
||||||
}
|
}
|
||||||
|
|
||||||
if idx := strings.Index(domain, "."); idx != -1 {
|
if idx := strings.Index(domain, "."); idx != -1 {
|
||||||
wildcard := "*." + domain[strings.Index(domain, ".") + 1:]
|
wildcard := "*." + domain[strings.Index(domain, ".") + 1:]
|
||||||
|
|
||||||
if ip, ok := f.hosts[wildcard]; ok {
|
if ip, ok := f.hosts[wildcard]; ok {
|
||||||
return strings.Split(ip, ","), true
|
return strings.Split(ip, ","), f.ttl, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for host, ip := range f.hosts {
|
for host, ip := range f.hosts {
|
||||||
if glob.Glob(host, domain) {
|
if glob.Glob(host, domain) {
|
||||||
return strings.Split(ip, ","), true
|
return strings.Split(ip, ","), f.ttl, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false
|
return nil, time.Duration(0), false
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -1,83 +1,39 @@
|
||||||
package hosts
|
package hosts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hoisie/redis"
|
"github.com/go-redis/redis/v7"
|
||||||
"github.com/ryanuber/go-glob"
|
"github.com/ryanuber/go-glob"
|
||||||
"meow.tf/joker/godns/log"
|
"meow.tf/joker/godns/log"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RedisHosts struct {
|
type RedisHosts struct {
|
||||||
HostProvider
|
Provider
|
||||||
|
|
||||||
redis *redis.Client
|
redis *redis.Client
|
||||||
key string
|
key string
|
||||||
hosts map[string]string
|
hosts map[string]string
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
ttl time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRedisProvider(rc *redis.Client, key string) HostProvider {
|
func NewRedisProvider(rc *redis.Client, key string, ttl time.Duration) Provider {
|
||||||
rh := &RedisHosts{
|
rh := &RedisHosts{
|
||||||
redis: rc,
|
redis: rc,
|
||||||
key: key,
|
key: key,
|
||||||
hosts: make(map[string]string),
|
hosts: make(map[string]string),
|
||||||
|
ttl: ttl,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force an initial refresh
|
// Force an initial refresh
|
||||||
rh.Refresh()
|
rh.Refresh()
|
||||||
|
|
||||||
// Use pubsub to listen for key update events
|
|
||||||
go func() {
|
|
||||||
keyspaceEvent := "__keyspace@0__:" + key
|
|
||||||
|
|
||||||
sub := make(chan string, 3)
|
|
||||||
sub <- keyspaceEvent
|
|
||||||
sub <- "godns:update"
|
|
||||||
sub <- "godns:update_record"
|
|
||||||
messages := make(chan redis.Message, 0)
|
|
||||||
go rc.Subscribe(sub, nil, nil, nil, messages)
|
|
||||||
|
|
||||||
for {
|
|
||||||
msg := <-messages
|
|
||||||
|
|
||||||
if msg.Channel == "godns:update" {
|
|
||||||
log.Debug("Refreshing redis records due to update")
|
|
||||||
rh.Refresh()
|
|
||||||
} else if msg.Channel == "godns:update_record" {
|
|
||||||
recordName := string(msg.Message)
|
|
||||||
|
|
||||||
b, err := rc.Hget(key, recordName)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Record %s does not exist, but was updated", recordName)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Record %s was updated to %s", recordName, string(b))
|
|
||||||
|
|
||||||
rh.mu.Lock()
|
|
||||||
rh.hosts[recordName] = string(b)
|
|
||||||
rh.mu.Unlock()
|
|
||||||
} else if msg.Channel == "godns:remove_record" {
|
|
||||||
log.Debug("Record %s was removed", msg.Message)
|
|
||||||
|
|
||||||
recordName := string(msg.Message)
|
|
||||||
|
|
||||||
rh.mu.Lock()
|
|
||||||
delete(rh.hosts, recordName)
|
|
||||||
rh.mu.Unlock()
|
|
||||||
} else if msg.Channel == keyspaceEvent {
|
|
||||||
log.Debug("Refreshing redis records due to update")
|
|
||||||
rh.Refresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return rh
|
return rh
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisHosts) Get(domain string) ([]string, bool) {
|
func (r *RedisHosts) Get(domain string) ([]string, time.Duration, bool) {
|
||||||
log.Debug("Checking redis provider for %s", domain)
|
log.Debug("Checking redis provider for %s", domain)
|
||||||
|
|
||||||
r.mu.RLock()
|
r.mu.RLock()
|
||||||
|
@ -86,37 +42,39 @@ func (r *RedisHosts) Get(domain string) ([]string, bool) {
|
||||||
domain = strings.ToLower(domain)
|
domain = strings.ToLower(domain)
|
||||||
|
|
||||||
if ip, ok := r.hosts[domain]; ok {
|
if ip, ok := r.hosts[domain]; ok {
|
||||||
return strings.Split(ip, ","), true
|
return strings.Split(ip, ","), r.ttl, true
|
||||||
}
|
}
|
||||||
|
|
||||||
if idx := strings.Index(domain, "."); idx != -1 {
|
if idx := strings.Index(domain, "."); idx != -1 {
|
||||||
wildcard := "*." + domain[strings.Index(domain, ".")+1:]
|
wildcard := "*." + domain[strings.Index(domain, ".")+1:]
|
||||||
|
|
||||||
if ip, ok := r.hosts[wildcard]; ok {
|
if ip, ok := r.hosts[wildcard]; ok {
|
||||||
return strings.Split(ip, ","), true
|
return strings.Split(ip, ","), r.ttl, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for host, ip := range r.hosts {
|
for host, ip := range r.hosts {
|
||||||
if glob.Glob(host, domain) {
|
if glob.Glob(host, domain) {
|
||||||
return strings.Split(ip, ","), true
|
return strings.Split(ip, ","), r.ttl, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false
|
return nil, time.Duration(0), false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisHosts) Set(domain, ip string) (bool, error) {
|
func (r *RedisHosts) Set(domain, ip string) (bool, error) {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
return r.redis.Hset(r.key, strings.ToLower(domain), []byte(ip))
|
return r.redis.HSet(r.key, strings.ToLower(domain), []byte(ip)).Result()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisHosts) Refresh() {
|
func (r *RedisHosts) Refresh() {
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
r.clear()
|
r.clear()
|
||||||
err := r.redis.Hgetall(r.key, r.hosts)
|
|
||||||
|
var err error
|
||||||
|
r.hosts, err = r.redis.HGetAll(r.key).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Update hosts records from redis failed %s", err)
|
log.Warn("Update hosts records from redis failed %s", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
80
main.go
80
main.go
|
@ -3,8 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-redis/redis/v7"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"meow.tf/joker/godns/cache"
|
||||||
|
"meow.tf/joker/godns/hosts"
|
||||||
"meow.tf/joker/godns/log"
|
"meow.tf/joker/godns/log"
|
||||||
|
"meow.tf/joker/godns/resolver"
|
||||||
"meow.tf/joker/godns/settings"
|
"meow.tf/joker/godns/settings"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -36,29 +40,79 @@ func main() {
|
||||||
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||||
}
|
}
|
||||||
|
|
||||||
serverSettings := settings.Server()
|
|
||||||
|
|
||||||
server := &Server{
|
server := &Server{
|
||||||
host: serverSettings.Host,
|
host: viper.GetString("server.host"),
|
||||||
port: serverSettings.Port,
|
networks: viper.GetStringSlice("server.nets"),
|
||||||
rTimeout: 5 * time.Second,
|
rTimeout: 5 * time.Second,
|
||||||
wTimeout: 5 * time.Second,
|
wTimeout: 5 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
server.Run()
|
var resolverCache, negCache cache.Cache
|
||||||
|
r := resolver.NewResolver(settings.ResolvSettings{
|
||||||
|
Timeout: viper.GetInt("resolv.timeout"),
|
||||||
|
Interval: viper.GetInt("resolv.interval"),
|
||||||
|
SetEDNS0: viper.GetBool("resolv.edns0"),
|
||||||
|
ServerListFile: viper.GetStringSlice("resolv.server-list"),
|
||||||
|
ResolvFile: viper.GetString("resolv.file"),
|
||||||
|
})
|
||||||
|
|
||||||
log.Info("godns %s (%s) start", Version, runtime.Version())
|
cacheDuration := viper.GetDuration("cache.expire")
|
||||||
|
|
||||||
if settings.Debug() {
|
redisConfig := settings.RedisSettings{
|
||||||
|
Host: viper.GetString("cache.redis.host"),
|
||||||
|
Port: viper.GetInt("cache.redis.port"),
|
||||||
|
DB: viper.GetInt("cache.redis.db"),
|
||||||
|
Password: viper.GetString("cache.redis.password"),
|
||||||
|
}
|
||||||
|
|
||||||
|
backend := viper.GetString("cache.backend")
|
||||||
|
|
||||||
|
switch backend {
|
||||||
|
case "memory":
|
||||||
|
cacheMaxCount := viper.GetInt("cache.memory.maxCount")
|
||||||
|
|
||||||
|
negCache = cache.NewMemoryCache(cacheDuration/2, cacheMaxCount)
|
||||||
|
resolverCache = cache.NewMemoryCache(cacheDuration, cacheMaxCount)
|
||||||
|
case "memcached":
|
||||||
|
servers := viper.GetStringSlice("cache.memcached.servers")
|
||||||
|
|
||||||
|
resolverCache = cache.NewMemcachedCache(servers, int32(cacheDuration.Seconds()))
|
||||||
|
negCache = cache.NewMemcachedCache(servers, int32(cacheDuration.Seconds()/2))
|
||||||
|
case "redis":
|
||||||
|
resolverCache = cache.NewRedisCache(redisConfig, cacheDuration)
|
||||||
|
negCache = cache.NewRedisCache(redisConfig, cacheDuration/2)
|
||||||
|
default:
|
||||||
|
log.Error("Invalid cache backend %s", backend)
|
||||||
|
panic("Invalid cache backend")
|
||||||
|
}
|
||||||
|
|
||||||
|
providers := make([]hosts.Provider, 0)
|
||||||
|
|
||||||
|
if viper.GetBool("hosts.file.enable") {
|
||||||
|
providers = append(providers, hosts.NewFileProvider(viper.GetString("hosts.file.file"), viper.GetDuration("hosts.file.ttl")))
|
||||||
|
}
|
||||||
|
|
||||||
|
if viper.GetBool("hosts.redis.enable") {
|
||||||
|
rc := redis.NewClient(&redis.Options{Addr: redisConfig.Addr(), DB: redisConfig.DB, Password: redisConfig.Password})
|
||||||
|
|
||||||
|
providers = append(providers, hosts.NewRedisProvider(rc, viper.GetString("hosts.redis.key"), viper.GetDuration("hosts.redis.ttl")))
|
||||||
|
}
|
||||||
|
|
||||||
|
h := hosts.NewHosts(providers)
|
||||||
|
|
||||||
|
server.Run(NewHandler(r, resolverCache, negCache, h))
|
||||||
|
|
||||||
|
log.Info("godns %s (%s)", Version, runtime.Version())
|
||||||
|
|
||||||
|
if viper.GetBool("debug") {
|
||||||
go profileCPU()
|
go profileCPU()
|
||||||
go profileMEM()
|
go profileMEM()
|
||||||
}
|
}
|
||||||
|
|
||||||
sig := make(chan os.Signal)
|
sig := make(chan os.Signal)
|
||||||
signal.Notify(sig, os.Interrupt)
|
signal.Notify(sig, os.Interrupt)
|
||||||
|
|
||||||
|
|
||||||
<- sig
|
<- sig
|
||||||
|
|
||||||
log.Info("signal received, stopping")
|
log.Info("signal received, stopping")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +147,6 @@ func profileMEM() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initLogger() {
|
func initLogger() {
|
||||||
logSettings := settings.Log()
|
|
||||||
|
|
||||||
if viper.GetBool("log.stdout") {
|
if viper.GetBool("log.stdout") {
|
||||||
log.SetLogger("console", nil)
|
log.SetLogger("console", nil)
|
||||||
}
|
}
|
||||||
|
@ -103,9 +155,5 @@ func initLogger() {
|
||||||
log.SetLogger("file", map[string]interface{}{"file": file})
|
log.SetLogger("file", map[string]interface{}{"file": file})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetLevel(logSettings.LogLevel())
|
log.SetLevel(settings.LogLevelFor(viper.GetString("log.level")))
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,10 +68,6 @@ func NewResolver(c settings.ResolvSettings) *Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.DOHServer) > 0 {
|
|
||||||
r.servers = append([]string{c.DOHServer}, r.servers...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,8 +137,7 @@ func (r *Resolver) parseServerListFile(buf *os.File) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) ReadServerListFile(path string) {
|
func (r *Resolver) ReadServerListFile(files []string) {
|
||||||
files := strings.Split(path, ";")
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
buf, err := os.Open(file)
|
buf, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
11
server.go
11
server.go
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/viper"
|
|
||||||
"meow.tf/joker/godns/log"
|
"meow.tf/joker/godns/log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -11,21 +10,17 @@ import (
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
host string
|
host string
|
||||||
port int
|
networks []string
|
||||||
rTimeout time.Duration
|
rTimeout time.Duration
|
||||||
wTimeout time.Duration
|
wTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Run() {
|
func (s *Server) Run(handler *Handler) {
|
||||||
handler := NewHandler()
|
|
||||||
|
|
||||||
nets := viper.GetStringSlice("networks")
|
|
||||||
|
|
||||||
var addr string
|
var addr string
|
||||||
var split []string
|
var split []string
|
||||||
|
|
||||||
// Defaults: tcp, udp
|
// Defaults: tcp, udp
|
||||||
for _, net := range nets {
|
for _, net := range s.networks {
|
||||||
split = strings.Split(net, ":")
|
split = strings.Split(net, ":")
|
||||||
|
|
||||||
net = split[0]
|
net = split[0]
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
package settings
|
package settings
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"meow.tf/joker/godns/log"
|
"meow.tf/joker/godns/log"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
"github.com/caarlos0/env"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
settings Settings
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var LogLevelMap = map[string]int{
|
var LogLevelMap = map[string]int{
|
||||||
|
@ -24,7 +14,6 @@ var LogLevelMap = map[string]int{
|
||||||
}
|
}
|
||||||
|
|
||||||
type HostsSettings struct {
|
type HostsSettings struct {
|
||||||
Enable bool `toml:"enable" env:"HOSTS_ENABLE"`
|
|
||||||
HostsFile string `toml:"host-file" env:"HOSTS_FILE"`
|
HostsFile string `toml:"host-file" env:"HOSTS_FILE"`
|
||||||
RedisEnable bool `toml:"redis-enable" env:"REDIS_HOSTS_ENABLE"`
|
RedisEnable bool `toml:"redis-enable" env:"REDIS_HOSTS_ENABLE"`
|
||||||
RedisKey string `toml:"redis-key" env:"REDIS_HOSTS_KEY"`
|
RedisKey string `toml:"redis-key" env:"REDIS_HOSTS_KEY"`
|
||||||
|
@ -48,9 +37,8 @@ type ResolvSettings struct {
|
||||||
Timeout int `toml:"timeout" env:"RESOLV_TIMEOUT"`
|
Timeout int `toml:"timeout" env:"RESOLV_TIMEOUT"`
|
||||||
Interval int `toml:"interval" env:"RESOLV_INTERVAL"`
|
Interval int `toml:"interval" env:"RESOLV_INTERVAL"`
|
||||||
SetEDNS0 bool `toml:"setedns0" env:"RESOLV_EDNS0"`
|
SetEDNS0 bool `toml:"setedns0" env:"RESOLV_EDNS0"`
|
||||||
ServerListFile string `toml:"server-list-file" env:"SERVER_LIST_FILE"`
|
ServerListFile []string `toml:"server-list-file" env:"SERVER_LIST_FILE"`
|
||||||
ResolvFile string `toml:"resolv-file" env:"RESOLV_FILE"`
|
ResolvFile string `toml:"resolv-file" env:"RESOLV_FILE"`
|
||||||
DOHServer string `toml:"dns-over-https" env:"DNS_HTTPS_SERVER"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSServerSettings struct {
|
type DNSServerSettings struct {
|
||||||
|
@ -79,10 +67,10 @@ type LogSettings struct {
|
||||||
Level string `toml:"level" env:"LOG_LEVEL"`
|
Level string `toml:"level" env:"LOG_LEVEL"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls LogSettings) LogLevel() int {
|
func LogLevelFor(level string) int {
|
||||||
l, ok := LogLevelMap[ls.Level]
|
l, ok := LogLevelMap[level]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("Config error: invalid log level: " + ls.Level)
|
panic("Config error: invalid log level: " + level)
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -92,55 +80,3 @@ type CacheSettings struct {
|
||||||
Expire int `toml:"expire" env:"CACHE_EXPIRE"`
|
Expire int `toml:"expire" env:"CACHE_EXPIRE"`
|
||||||
Maxcount int `toml:"maxcount" env:"CACHE_MAX_COUNT"`
|
Maxcount int `toml:"maxcount" env:"CACHE_MAX_COUNT"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
var configFile string
|
|
||||||
|
|
||||||
flag.StringVar(&configFile, "c", "/etc/godns.conf", "Look for godns toml-formatting config file in this directory")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if _, err := toml.DecodeFile(configFile, &settings); err != nil {
|
|
||||||
fmt.Printf("%s is not a valid toml config file\n", configFile)
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
env.Parse(&settings.ResolvConfig)
|
|
||||||
env.Parse(&settings.Redis)
|
|
||||||
env.Parse(&settings.Memcache)
|
|
||||||
env.Parse(&settings.Log)
|
|
||||||
env.Parse(&settings.Cache)
|
|
||||||
env.Parse(&settings.Hosts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Resolver() ResolvSettings {
|
|
||||||
return settings.ResolvConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func Cache() CacheSettings {
|
|
||||||
return settings.Cache
|
|
||||||
}
|
|
||||||
|
|
||||||
func Server() DNSServerSettings {
|
|
||||||
return settings.Server
|
|
||||||
}
|
|
||||||
|
|
||||||
func Hosts() HostsSettings {
|
|
||||||
return settings.Hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
func Redis() RedisSettings {
|
|
||||||
return settings.Redis
|
|
||||||
}
|
|
||||||
|
|
||||||
func Memcache() MemcacheSettings {
|
|
||||||
return settings.Memcache
|
|
||||||
}
|
|
||||||
|
|
||||||
func Debug() bool {
|
|
||||||
return settings.Debug
|
|
||||||
}
|
|
||||||
|
|
||||||
func Log() LogSettings {
|
|
||||||
return settings.Log
|
|
||||||
}
|
|
Loading…
Reference in New Issue