feat(blacklist): 支持 hosts 风格黑名单文件并优化热重载机制

- 支持解析 hosts 风格的黑名单文件,可识别以 IP 开头的行,并将后续字段作为域名处理
- 增加对行首及行内注释的支持(支持 `//`、`#`、`;` 符号)
- 使用 atomic.Pointer 管理黑名单匹配器,提升并发安全性
- 优化黑名单热重载逻辑,使用 time.Ticker 替代 time.After 提高稳定性
- 更新相关依赖引用路径,调整 sync 包导入位置
This commit is contained in:
2025-10-17 10:46:48 +08:00
parent 224f575e68
commit 1ab273e2a8
4 changed files with 52 additions and 31 deletions

11
main.go
View File

@@ -13,6 +13,7 @@ import (
"os/signal"
"strings"
"sync"
"sync/atomic"
"syscall"
"time"
@@ -564,7 +565,7 @@ func handleDNS(
maxParallel int,
stripECSBeforeForward bool,
allowTCPFallback bool,
bl *suffixMatcher,
blPtr *atomic.Pointer[suffixMatcher],
blRcode int,
) dns.HandlerFunc {
return func(w dns.ResponseWriter, r *dns.Msg) {
@@ -581,7 +582,7 @@ func handleDNS(
}
// 黑名单拦截:命中则不查上游,直接返回
if rule, ok := bl.match(q.Name); ok {
if rule, ok := blPtr.Load().match(q.Name); ok {
nameCanon := dns.CanonicalName(q.Name)
log.Printf("[blacklist] HIT %s rule=%s (no upstream query)", nameCanon, rule)
up := makeBlockedUpstream(blRcode, rule)
@@ -697,7 +698,7 @@ func main() {
startCacheCleaner(ctx)
// 加载黑名单规则
bl, blRcode := initBlacklist(ctx, *blacklistStr, *blacklistFile, *blacklistRcodeFlag)
blPtr, blRcode := initBlacklist(ctx, *blacklistStr, *blacklistFile, *blacklistRcodeFlag)
mux := dns.NewServeMux()
mux.HandleFunc(".", handleDNS(
@@ -707,7 +708,7 @@ func main() {
*maxParallel,
*stripECSFlag,
*allowTCPFallback,
bl,
blPtr,
blRcode,
))
@@ -733,7 +734,7 @@ func main() {
log.Printf(" upstreams=%v | cache_max_ttl=%s | cache_size=%d | timeout=%s | max_parallel=%d | strip_ecs=%v | tcp_fallback=%v | read_timeout=%s | write_timeout=%s | blacklist_rules=%d | blacklist_rcode=%s",
upstreams, cacheTTLFlag.String(), *cacheSizeFlag, timeoutFlag.String(), *maxParallel, *stripECSFlag, *allowTCPFallback,
readTimeoutFlag.String(), writeTimeoutFlag.String(),
len(bl.rules), strings.ToUpper(*blacklistRcodeFlag))
len(blPtr.Load().rules), strings.ToUpper(*blacklistRcodeFlag))
errCh <- srv.ListenAndServe()
}()