Fix cache TTL extraction, add TCP idle timeout, close upstreams on shutdown

- extractTTL: use 0 as initial value and take actual minimum TTL from
  answer records. Previously hardcoded 300 would cap higher TTLs.
- TCP handler: add 90s read deadline to prevent idle connections from
  blocking goroutines indefinitely.
- Server.Close: close upstream groups to release connection pool resources.
This commit is contained in:
NeoMody
2026-04-02 05:42:20 +08:00
parent 1fed32a4fe
commit ec9cdb2784
2 changed files with 12 additions and 2 deletions

8
cache/cache.go vendored
View File

@@ -145,12 +145,16 @@ func (c *Cache) Set(domain string, qtype uint16, msg *dns.Msg) {
}
func (c *Cache) extractTTL(msg *dns.Msg) time.Duration {
var minTTL uint32 = 300
var minTTL uint32
for _, rr := range msg.Answer {
if t := rr.Header().Ttl; t > 0 && t < minTTL {
t := rr.Header().Ttl
if t > 0 && (minTTL == 0 || t < minTTL) {
minTTL = t
}
}
if minTTL == 0 {
minTTL = 300
}
return time.Duration(minTTL) * time.Second
}

View File

@@ -21,6 +21,7 @@ type Server struct {
resolver *resolver.Resolver
cache *cache.Cache
revCache *cache.ReverseCache
groups map[string]*upstream.Group
udpConn net.PacketConn
tcpLn net.Listener
logger Logger
@@ -171,6 +172,7 @@ func New(config *Config, opts ...Option) (*Server, error) {
})
s.cache = dnsCache
s.revCache = revCache
s.groups = groups
return s, nil
}
@@ -259,6 +261,9 @@ func (s *Server) Close() error {
if s.revCache != nil {
s.revCache.Close()
}
for _, g := range s.groups {
g.Close()
}
return nil
}
@@ -310,6 +315,7 @@ func (s *Server) handleTCP(conn net.Conn) {
defer conn.Close()
dnsConn := &dns.Conn{Conn: conn}
for {
conn.SetReadDeadline(time.Now().Add(90 * time.Second))
msg, err := dnsConn.ReadMsg()
if err != nil {
return