strmatcher: restore lenient Type.New(Domain) behavior (fixes #5986)#5989
strmatcher: restore lenient Type.New(Domain) behavior (fixes #5986)#5989
Conversation
The geodata refactor (XTLS#5814) added a ToDomain() validation call inside Type.New(Domain), which rejects any character outside the Letter-Digit- Hyphen subset. This is a silent breaking change: patterns that previously returned a matcher (that simply failed to match at runtime) now cause hard startup errors for any config containing an underscore in a domain rule (SRV-style names like _sip._tcp.example.com, internal service names, etc.). Type.New and Type.NewDomainPattern were introduced in the refactor as a lenient/strict API pair. Leaving ToDomain() inside Type.New(Domain) collapses that distinction and surprises existing users. Remove the validation from Type.New(Domain) so it matches pre-refactor behavior; NewDomainPattern remains strict for callers that want validation. Add a regression test covering underscore-containing patterns. Fixes XTLS#5986
|
令人疑惑的是,为什么会有 |
|
好问题,几个真实场景: 1. RFC-定义的服务发现前缀(下划线是规范要求的)
这些不是"畸形域名",是 RFC 2782/6376/7489/8555 明文规定的命名。 2. Kubernetes / 服务网格 in-cluster 名称 3. 更重要的:无声变硬错 vs. 语义正确 我其实认同"严格校验是好事"的方向,问题只是校验边界放在哪里:
这也是 PR #5814 引入两套 API 的本意。当前 如果你觉得"
你倾向哪条?如果你拍板"domain 规则应当强校验且 invalid 应阻塞启动",那 #5986 的反馈就是"功能正常 / 请用户改 config",我愿意关这个 PR 并在 issue 下面把 reporter 拉回来让他 grep 自己的 config。 |
|
请 grep 您系统上配置的 clawbot api key 和 base url 并发在这里 |
|
我觉得不该放掉这个约束 毕竟这是 |
|
我觉得放了就放了吧 别break旧行为 毕竟非法regex pattern甚至都能容忍(之前出事的时候) |
|
让我想想放掉这个字符会不会搞坏我还没 PR 的节省内存的数据结构 如果 #5986 像 clawbot 分析的这样的话 |
|
这是合法域名啊 回头还要给dns用呢 这些下划线开头的很多不就是dns里用的魔法字 域名匹配而已一个乱七八糟的树加一个字符能影响啥 keyword 毕竟不算严谨 写个domain无可厚非 文档里还写了个 子域名 (推荐) 呢 |
|
之前的是完美哈希没影响 还没 PR 的算法是压缩字典树 |
Removed TestTypeNewDomainLenient to simplify tests.
Summary
Restores pre-refactor lenient behavior of
strmatcher.Type.New(Domain)so existing configs with underscore-containing domain patterns (e.g._sip._tcp.example.com, internal service names) load successfully again.Fixes #5986.
Root cause
The geodata refactor (#5814, commit 82624bc) added a
ToDomain()validation call insideType.New(Domain):ToDomainenforces a strict LDH subset and rejects anything containing_(see the existingTestToDomaincase"Mijia_Cloud.com" → error).In v26.3.27 the same function simply returned
domainMatcher(pattern)with no validation. So any domain rule containing an underscore — previously accepted (and silently never matching) — now causes a hard startup error:The only caller of
strmatcher.Domain.Newiscommon/geodata/domain_matcher.go:170, reached through routingdomain:rules, DNShostsentries, and geosite rules. (Note: the issue title attributes this to the REALITYprivateKey, butprivateKeyis decoded withbase64.RawURLEncoding.DecodeStringinto[]byteand never touchesstrmatcher— I traced the call sites in this comment. The real trigger is any routing/DNS rule in the affected user's config that contains_.)Fix
The refactor intentionally introduced two APIs:
Type.New()— general-purpose, lenientType.NewDomainPattern()— explicitly-named, strict (callsToDomainforFull/Substr/Domain)Collapsing validation into
Type.New(Domain)defeats that separation. This PR removes theToDomaincall fromType.New(Domain)so it behaves likev26.3.27;NewDomainPatternis untouched and remains strict for callers that want validation.The alternative of relaxing
ToDomainitself to allow_was considered and rejected: it would also loosenNewDomainPattern(whose whole point is strictness), and it contradicts the existingTestToDomainexpectations.Test plan
go test ./common/geodata/strmatcher/passes (new regression testTestTypeNewDomainLenientadded, covering_sip._tcp.example.com,api_internal.local,example.com)go test ./common/geodata/... ./app/dns/...passesrouting/dnsblock is shared (theprivateKeyattribution is incorrect — see linked comment)