From 81661cc8deaacbff3497f0c9ef2625e98257ef76 Mon Sep 17 00:00:00 2001 From: radhitya Date: Sun, 21 Jun 2026 13:11:55 +0700 Subject: dot, readme --- internal/config/config.go | 18 ++++++++++++++++++ internal/server/server.go | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 7 deletions(-) (limited to 'internal') diff --git a/internal/config/config.go b/internal/config/config.go index b2c88ee..42af236 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -15,14 +15,20 @@ type Config struct { Admin AdminConfig `toml:"admin"` ACL ACLConfig `toml:"acl"` Log LogConfig `toml:"log"` + TLS TLSConfig `toml:"tls"` } type ServerConfig struct { ListenUDP string `toml:"listen_udp"` ListenTCP string `toml:"listen_tcp"` ListenDOH string `toml:"listen_doh"` + ListenDoT string `toml:"listen_dot"` } +type TLSConfig struct { + Cert string `toml:"cert"` + Key string `toml:"key"` +} type CacheConfig struct { MaxEntries int `toml:"max_entries"` DBPath string `toml:"db_path"` @@ -164,6 +170,15 @@ func Merge(dst, src Config) Config { if src.Admin.Listen != "" { dst.Admin.Listen = src.Admin.Listen } + if src.Server.ListenDoT != "" { + dst.Server.ListenDoT = src.Server.ListenDoT + } + if src.TLS.Cert != "" { + dst.TLS.Cert = src.TLS.Cert + } + if src.TLS.Key != "" { + dst.TLS.Key = src.TLS.Key + } return dst } @@ -202,5 +217,8 @@ func (c Config) Validate() error { if c.Resolver.Mode == "forward" && len(c.Resolver.Forwarders) == 0 { return fmt.Errorf("resolver mode=forward requires at least one forwarder") } + if c.Server.ListenDoT != "" && (c.TLS.Cert == "" || c.TLS.Key == "") { + return fmt.Errorf("listen_dot requires tls.cert and tls.key") + } return nil } diff --git a/internal/server/server.go b/internal/server/server.go index a90e5ac..74add95 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -2,6 +2,7 @@ package server import ( "context" + "crypto/tls" "fmt" "log/slog" "net" @@ -30,12 +31,13 @@ type Server struct { admin *Admin aclNets []*net.IPNet rateLimiter *rateLimiter + dot *dns.Server - mu sync.RWMutex - upUDP bool - upTCP bool - upDoH bool - + mu sync.RWMutex + upUDP bool + upTCP bool + upDoH bool + upDoT bool cancel context.CancelFunc } @@ -45,10 +47,12 @@ func (s *Server) Ready() bool { wantUDP := s.cfg.ListenUDP != "" wantTCP := s.cfg.ListenTCP != "" wantDoH := s.cfg.ListenDOH != "" - return (!wantUDP || s.upUDP) && (!wantTCP || s.upTCP) && (!wantDoH || s.upDoH) + wantDoT := s.cfg.ListenDoT != "" + return (!wantUDP || s.upUDP) && (!wantTCP || s.upTCP) && (!wantDoH || s.upDoH) && + (!wantDoT || s.upDoT) } -func New(udpAddr, tcpAddr, dohAddr string, logger *slog.Logger, r *resolver.Resolver, c *cache.Cache, bl *blocklist.Blocklist, cfg config.Config) (*Server, error) { +func New(udpAddr, tcpAddr, dohAddr, dotAddr string, tlsCfg *tls.Config, logger *slog.Logger, r *resolver.Resolver, c *cache.Cache, bl *blocklist.Blocklist, cfg config.Config) (*Server, error) { baseCtx, cancel := context.WithCancel(context.Background()) s := &Server{ logger: logger, @@ -94,6 +98,16 @@ func New(udpAddr, tcpAddr, dohAddr string, logger *slog.Logger, r *resolver.Reso } } + if dotAddr != "" && tlsCfg != nil { + + s.dot = &dns.Server{ + Addr: dotAddr, + Net: "tcp", + Handler: mux, + TLSConfig: tlsCfg, + ReadTimeout: 5 * time.Second, + } + } if dohAddr != "" { dohMux := http.NewServeMux() dohMux.HandleFunc("/dns-query", s.dohHandler) @@ -122,6 +136,9 @@ func (s *Server) Run(ctx context.Context) error { if s.doh != nil { s.upDoH = true } + if s.dot != nil { + s.upDoT = true + } s.mu.Unlock() if s.admin != nil { @@ -149,6 +166,12 @@ func (s *Server) Run(ctx context.Context) error { errCh <- s.doh.ListenAndServe() }() } + if s.dot != nil { + go func() { + s.logger.Info("dot listener active", "addr", s.dot.Addr) + errCh <- s.dot.ListenAndServe() + }() + } select { case <-ctx.Done(): @@ -180,6 +203,9 @@ func (s *Server) Close() error { if s.tcp != nil { s.tcp.Shutdown(context.Background()) } + if s.dot != nil { + s.dot.Shutdown(context.Background()) + } if s.doh != nil { s.doh.Close() } -- cgit v1.2.3