godns/main.go

192 lines
4.0 KiB
Go
Raw Normal View History

2013-07-23 11:10:38 +00:00
package main
import (
2020-01-25 17:43:02 +00:00
"flag"
"github.com/go-redis/redis/v7"
log "github.com/sirupsen/logrus"
2020-01-25 17:43:02 +00:00
"github.com/spf13/viper"
"io"
"meow.tf/joker/godns/api"
"meow.tf/joker/godns/cache"
"meow.tf/joker/godns/hosts"
"meow.tf/joker/godns/resolver"
2020-01-25 17:43:02 +00:00
"meow.tf/joker/godns/settings"
2013-07-23 11:10:38 +00:00
"os"
"os/signal"
2013-07-25 04:32:57 +00:00
"runtime"
2015-10-14 07:21:21 +00:00
"runtime/pprof"
2013-07-23 11:10:38 +00:00
"time"
)
2020-01-25 17:43:02 +00:00
const (
Version = "0.3.0"
)
2013-07-23 11:10:38 +00:00
var (
2020-01-25 17:43:02 +00:00
cfgFile string
2013-07-23 11:10:38 +00:00
)
2020-01-25 17:43:02 +00:00
func init() {
flag.StringVar(&cfgFile, "config", "/etc/godns/godns.conf", "")
}
2013-07-23 11:10:38 +00:00
2020-01-25 17:43:02 +00:00
func main() {
initLogger()
2013-07-23 11:10:38 +00:00
2020-01-25 17:43:02 +00:00
viper.SetConfigFile(cfgFile)
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err == nil {
log.WithField("file", viper.ConfigFileUsed()).Info("Using configuration from file")
2020-01-25 17:43:02 +00:00
}
2013-07-23 11:10:38 +00:00
server := &Server{
host: viper.GetString("server.host"),
networks: viper.GetStringSlice("server.nets"),
2013-07-23 11:10:38 +00:00
rTimeout: 5 * time.Second,
wTimeout: 5 * time.Second,
}
var resolverSettings resolver.Settings
/*
resolver.Settings{
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"),
}
*/
viper.UnmarshalKey("resolv", &resolverSettings)
var resolverCache, negCache cache.Cache
r := resolver.NewResolver(resolverSettings)
cacheDuration := viper.GetDuration("cache.expire")
backend := viper.GetString("cache.backend")
var redisConfig settings.RedisSettings
viper.UnmarshalKey("cache.redis", &redisConfig)
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.WithField("backend", backend).Fatalln("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.bolt.enable") {
providers = append(providers, hosts.NewBoltProvider(viper.GetString("hosts.bolt.file")))
}
if viper.GetBool("hosts.redis.enable") {
rc := redis.NewClient(&redis.Options{Addr: redisConfig.Addr(), DB: redisConfig.DB, Password: redisConfig.Password})
2013-07-23 11:10:38 +00:00
2021-04-15 04:00:36 +00:00
providers = append(providers, hosts.NewRedisProvider(rc, viper.GetString("hosts.redis.key")))
}
if viper.GetBool("api.enabled") {
go func() {
err := api.Start()
if err != nil {
log.WithError(err).Fatalln("Unable to bind API")
}
}()
}
h := hosts.NewHosts(providers)
server.Run(NewHandler(r, resolverCache, negCache, h))
2013-07-25 04:32:57 +00:00
log.Infof("joker dns %s (%s)", Version, runtime.Version())
if viper.GetBool("debug") {
2015-10-14 07:21:21 +00:00
go profileCPU()
go profileMEM()
}
2013-07-23 11:10:38 +00:00
sig := make(chan os.Signal)
signal.Notify(sig, os.Interrupt)
2020-01-25 17:43:02 +00:00
<- sig
2020-01-25 17:43:02 +00:00
log.Info("signal received, stopping")
2013-07-23 11:10:38 +00:00
}
2015-10-14 07:21:21 +00:00
func profileCPU() {
f, err := os.Create("godns.cprof")
if err != nil {
2020-01-25 17:43:02 +00:00
log.Error("%s", err)
2015-10-14 07:21:21 +00:00
return
}
pprof.StartCPUProfile(f)
2015-10-14 07:21:21 +00:00
time.AfterFunc(6*time.Minute, func() {
pprof.StopCPUProfile()
f.Close()
})
}
func profileMEM() {
f, err := os.Create("godns.mprof")
2020-01-25 17:43:02 +00:00
2015-10-14 07:21:21 +00:00
if err != nil {
2020-01-25 17:43:02 +00:00
log.Error("%s", err)
2015-10-14 07:21:21 +00:00
return
}
time.AfterFunc(5*time.Minute, func() {
pprof.WriteHeapProfile(f)
f.Close()
})
}
func initLogger() {
2020-01-25 17:43:02 +00:00
if viper.GetBool("log.stdout") {
// log.SetLogger("console", nil)
}
2020-01-25 17:43:02 +00:00
if file := viper.GetString("log.file"); file != "" {
f, err := os.Create(file)
if err != nil {
return
}
log.SetOutput(io.MultiWriter(f, log.StandardLogger().Out))
}
level, err := log.ParseLevel(viper.GetString("log.level"))
if err != nil {
return
2013-07-23 11:10:38 +00:00
}
log.SetLevel(level)
2013-07-25 04:32:57 +00:00
}