-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
完整性要求
- 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
- 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。
- 我搜索了 issues, 没有发现已提出的类似问题。
- 问题在 Release 最新的版本上可以成功复现
描述
根据文档说明
https://xtls.github.io/config/dns.html#dns-%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B
没有命中 hosts,但命中了某(几)个 DNS 服务器中的 domains 域名列表,则按照命中的规则的优先级,依次使用该规则对应的 DNS 服务器进行查询。
这里的依次,究竟是什么次序?本来想当然以为是配置文件中dnsServerObject的次序,也就是代码片段中的idx。
但我昨天无意间发现他非常具有混沌性,dns配置不动,修改路由规则或者有时候重启会导致其解析顺序不一样。
debug了一下,发现是缺少排序逻辑。
修复建议:
sortClients()
应在272行根据idx整理clients,使其顺序跟配置文件中的顺序相符,以符合配置文件预期
func (s *DNS) sortClients(domain string) []*Client {
clients := make([]*Client, 0, len(s.clients))
clientUsed := make([]bool, len(s.clients))
clientNames := make([]string, 0, len(s.clients))
domainRules := []string{}
// Priority domain matching
hasMatch := false
for _, match := range s.domainMatcher.Match(domain) {
info := s.matcherInfos[match]
client := s.clients[info.clientIdx]
domainRule := client.domains[info.domainRuleIdx]
domainRules = append(domainRules, fmt.Sprintf("%s(DNS idx:%d)", domainRule, info.clientIdx))
if clientUsed[info.clientIdx] {
continue
}
clientUsed[info.clientIdx] = true
clients = append(clients, client)
clientNames = append(clientNames, client.Name())
hasMatch = true
}
// 272行:在这里加sort by idx asc
if !(s.disableFallback || s.disableFallbackIfMatch && hasMatch) {
// Default round-robin query
for idx, client := range s.clients {
if clientUsed[idx] || client.skipFallback {
continue
}
clientUsed[idx] = true
clients = append(clients, client)
clientNames = append(clientNames, client.Name())
}
}
重现方式
dig www.google.fr
客户端配置
{
"dns": {
"servers": [
{
// 这个IP将会走法国节点
"address": "208.67.222.222",
"port": 53,
"skipFallback": true,
"domains": ["domain:fr", "geosite:category-ai-chat-!cn", "geosite:disney", "geosite:netflix", "geosite:primevideo", "geosite:spotify"]
},
{
// 省略etc...
},
{
"address": "1.1.1.1",
"port": 53,
"skipFallback": true,
"domains": ["geosite:google", "geosite:google-cn"]
},
{
"address": "8.8.8.8",
"port": 53,
"skipFallback": true,
"domains": ["geosite:google", "geosite:google-cn"]
},
// 省略chinaDNS....
"8.8.8.8",
"1.1.1.1"
]
}
}
服务端配置
N/A
客户端日志
2025/03/19 20:45:57.559075 [Debug] app/dns: domain [www.google.fr ](http://www.google.fr/)matches following rules: [geosite:google(DNS idx:2) geosite:google(DNS idx:3) geosite:geolocation-!cn(DNS idx:6) domain:fr(DNS idx:0)]
2025/03/19 20:45:57.559176 [Debug] app/dns: domain [www.google.fr ](http://www.google.fr/)will use DNS in order: [UDP:1.1.1.1:53 UDP:8.8.8.8:53 UDP:1.1.1.1:53 UDP:208.67.222.222:53 UDP:8.8.8.8:53 UDP:8.8.8.8:53 UDP:1.1.1.1:53]
2025/03/19 20:45:57.559213 [Debug] app/dns: UDP:1.1.1.1:53 cache HIT [www.google.fr ](http://www.google.fr/)-> [172.217.25.163]
服务端日志
N/A
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working