summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorradhitya <alif@radhitya.org>2026-06-14 17:17:56 +0700
committerradhitya <alif@radhitya.org>2026-06-14 17:17:56 +0700
commitd173554892339e5211020c60d6af610840eef7ed (patch)
tree295ce37851532e6180b47c63ed34146a01adc12c /main.go
parent4e6a897a0b55ee533c05f89fa38dbe0704f2798d (diff)
config, rebranding, fix cache
Diffstat (limited to 'main.go')
-rw-r--r--main.go111
1 files changed, 69 insertions, 42 deletions
diff --git a/main.go b/main.go
index 96c51cb..afb41c2 100644
--- a/main.go
+++ b/main.go
@@ -7,28 +7,47 @@ import (
"os/signal"
"path/filepath"
"syscall"
-
- "sdns/internal/blocklist"
- "sdns/internal/cache"
- "sdns/internal/resolver"
- "sdns/internal/server"
+ "fmt"
+ "linum/internal/blocklist"
+ "linum/internal/cache"
+ "linum/internal/config"
+ "linum/internal/resolver"
+ "linum/internal/server"
)
func main() {
- logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
- Level: slog.LevelInfo,
- }))
- slog.SetDefault(logger)
+ flags := config.ParseFlags()
- r := resolver.New()
+ cfg := config.Default()
+ if _, err := os.Stat(flags.Config); err == nil {
+ fileCfg, err := config.LoadFile(flags.Config)
+ if err != nil {
+ slog.Error("invalid config file", "err", err)
+ os.Exit(1)
+ }
+ cfg = config.Merge(cfg, fileCfg)
+ }
+ cfg = flags.Apply(cfg)
- dbPath := os.Getenv("SDNS_CACHE_DB")
- if dbPath != "" {
- logger.Info("cache using sqlite", "path", dbPath)
- } else {
- logger.Info("cache using in-memory")
+ if err := cfg.Validate(); err != nil {
+ slog.Error("config validation failed", "err", err)
+ os.Exit(1)
}
- c, err := cache.NewCache(100000, dbPath)
+
+ var lvl slog.Level
+ _ = lvl.UnmarshalText([]byte(cfg.Log.Level))
+ logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: lvl}))
+ slog.SetDefault(logger)
+
+ fmt.Println("linum - simple dns recursive")
+ fmt.Printf("github.com/radhityax/linum\n\n")
+
+ logger.Info("config loaded", "file", flags.Config)
+
+ r := resolver.New(
+ resolver.WithTimeout(2 * 1000 * 1000 * 1000),)
+
+ c, err := cache.NewCache(cfg.Cache.MaxEntries, cfg.Cache.DBPath)
if err != nil {
logger.Error("create cache failed", "err", err)
os.Exit(1)
@@ -36,49 +55,57 @@ func main() {
defer c.Stop()
var bl *blocklist.Blocklist
- matches, _ := filepath.Glob("etc/blocklist/*.txt")
- if len(matches) > 0 {
- bl = blocklist.New(blocklist.ResponseZeroIP)
- for _, f := range matches {
- if err := bl.LoadFile(f); err != nil {
- logger.Error("load blocklist failed", "file", f, "err", err)
- os.Exit(1)
+ if len(cfg.Blocklist.Files) > 0 || len(cfg.Blocklist.URLs) > 0 {
+ resp := blocklist.ResponseZeroIP
+ if cfg.Blocklist.Response == "nxdomain" {
+ resp = blocklist.ResponseNXDOMAIN
+ }
+ bl = blocklist.New(resp)
+
+ for _, pattern := range cfg.Blocklist.Files {
+ matches, err := filepath.Glob(pattern)
+ if err != nil {
+ logger.Warn("invalid blocklist glob", "pattern", pattern, "err", err)
+ continue
+ }
+ for _, f := range matches {
+ if err := bl.LoadFile(f); err != nil {
+ logger.Error("load blocklist failed", "file", f, "err", err)
+ os.Exit(1)
+ }
+ logger.Info("blocklist loaded", "file", f, "rules", bl.TotalRules)
+ }
+ }
+ for _, u := range cfg.Blocklist.URLs {
+ if err := bl.LoadURL(u); err != nil {
+ logger.Warn("load blocklist url failed", "url", u, "err", err)
+ continue
}
- logger.Info("blocklist loaded", "file", f, "rules", bl.TotalRules)
+ logger.Info("blocklist url loaded", "url", u)
}
} else {
- logger.Info("no blocklist files in etc/blocklist/, ad-blocking disabled")
- }
- udp := os.Getenv("SDNS_LISTEN_UDP")
- if udp == "" {
- udp = ":5353"
- }
-
- tcp := os.Getenv("SDNS_LISTEN_TCP")
- if tcp == "" {
- tcp = ":5353"
- }
-
- doh := os.Getenv("SDNS_LISTEN_DOH")
- if doh == "" {
- doh = ":8443"
+ logger.Info("no blocklist configured, ad-blocking disabled")
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
- srv, err := server.New(udp, tcp, doh, logger, r, c, bl)
+ srv, err := server.New(cfg.Server.ListenUDP, cfg.Server.ListenTCP, cfg.Server.ListenDOH, logger, r, c, bl)
if err != nil {
logger.Error("create server failed", "err", err)
os.Exit(1)
}
defer srv.Close()
- logger.Info("sdns starting", "udp", udp, "tcp", tcp, "doh", doh)
+ logger.Info("linum starting",
+ "udp", cfg.Server.ListenUDP,
+ "tcp", cfg.Server.ListenTCP,
+ "doh", cfg.Server.ListenDOH,
+ )
if err := srv.Run(ctx); err != nil && err != context.Canceled {
logger.Error("server stopped with error", "err", err)
os.Exit(1)
}
- logger.Info("sdns stopped cleanly")
+ logger.Info("linum stopped cleanly")
}