From b61d0e68ed004b2e14db3e877465b19672a54c6b Mon Sep 17 00:00:00 2001 From: zengql Date: Mon, 1 Sep 2025 09:42:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0DNS=20fallback?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B9=B6=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=85=A2=E9=97=AE=E9=A2=98=20(#1062)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增DNS回退服务器配置界面和多语言支持 - 修复DNS配置合并逻辑,确保fallback始终为空数组 - 解决订阅fallback配置导致的双重DNS查询性能问题 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude --- src/main/config/controledMihomo.ts | 11 +++++- src/main/utils/template.ts | 14 +++++-- src/renderer/src/locales/en-US.json | 9 +++++ src/renderer/src/locales/fa-IR.json | 9 +++++ src/renderer/src/locales/ru-RU.json | 9 +++++ src/renderer/src/locales/zh-CN.json | 9 +++++ src/renderer/src/pages/dns.tsx | 59 +++++++++++++++++++++++++++-- 7 files changed, 112 insertions(+), 8 deletions(-) diff --git a/src/main/config/controledMihomo.ts b/src/main/config/controledMihomo.ts index 038d9b9..ecc29de 100644 --- a/src/main/config/controledMihomo.ts +++ b/src/main/config/controledMihomo.ts @@ -12,6 +12,9 @@ export async function getControledMihomoConfig(force = false): Promise): controledMihomoConfig = deepMerge(controledMihomoConfig, patch) // 从不接管状态恢复 - if (controlDns && controledMihomoConfig.dns?.ipv6 === undefined) { - controledMihomoConfig.dns = defaultControledMihomoConfig.dns + if (controlDns) { + // 确保DNS配置包含所有必要的默认字段,特别是新增的fallback等 + controledMihomoConfig.dns = deepMerge( + defaultControledMihomoConfig.dns || {}, + controledMihomoConfig.dns || {} + ) } if (controlSniff && !controledMihomoConfig.sniffer) { controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer diff --git a/src/main/utils/template.ts b/src/main/utils/template.ts index 4f375c9..8812505 100644 --- a/src/main/utils/template.ts +++ b/src/main/utils/template.ts @@ -86,10 +86,18 @@ export const defaultControledMihomoConfig: Partial = { 'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'], 'use-hosts': false, 'use-system-hosts': false, + 'respect-rules': false, 'default-nameserver': ['tls://223.5.5.5'], - nameserver: ['https://120.53.53.53/dns-query', 'https://223.5.5.5/dns-query'], - 'proxy-server-nameserver': ['https://120.53.53.53/dns-query', 'https://223.5.5.5/dns-query'], - 'direct-nameserver': [] + nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'], + 'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'], + 'direct-nameserver': [], + fallback: [], + 'fallback-filter': { + geoip: true, + 'geoip-code': 'CN', + ipcidr: ['240.0.0.0/4', '0.0.0.0/32'], + domain: ['+.google.com', '+.facebook.com', '+.youtube.com'] + } }, sniffer: { enable: true, diff --git a/src/renderer/src/locales/en-US.json b/src/renderer/src/locales/en-US.json index 124a13b..71310b2 100644 --- a/src/renderer/src/locales/en-US.json +++ b/src/renderer/src/locales/en-US.json @@ -350,6 +350,15 @@ "dns.nameserverPlaceholder": "Example: tls://dns.alidns.com", "dns.directNameserver": "Direct Resolution Server", "dns.directNameserverPlaceholder": "Example: tls://dns.alidns.com", + "dns.fallback": "Fallback Servers", + "dns.fallbackPlaceholder": "Example: https://dns.alidns.com/dns-query", + "dns.fallbackFilter.title": "Fallback Filter Settings", + "dns.fallbackFilter.geoip": "GeoIP Filter", + "dns.fallbackFilter.geoipCode": "GeoIP Country Code", + "dns.fallbackFilter.ipcidr": "Fallback IP CIDR", + "dns.fallbackFilter.ipcidrPlaceholder": "Example: 240.0.0.0/4", + "dns.fallbackFilter.domain": "Fallback Domains", + "dns.fallbackFilter.domainPlaceholder": "Example: +.google.com", "dns.nameserverPolicy.title": "Override DNS Policy", "dns.nameserverPolicy.list": "DNS Policy List", "dns.nameserverPolicy.domainPlaceholder": "Domain", diff --git a/src/renderer/src/locales/fa-IR.json b/src/renderer/src/locales/fa-IR.json index 39ce800..057fcbd 100644 --- a/src/renderer/src/locales/fa-IR.json +++ b/src/renderer/src/locales/fa-IR.json @@ -344,6 +344,15 @@ "dns.nameserverPlaceholder": "مثال: tls://dns.alidns.com", "dns.directNameserver": "سرور حل نام مستقیم", "dns.directNameserverPlaceholder": "مثال: tls://dns.alidns.com", + "dns.fallback": "سرورهای پشتیبان", + "dns.fallbackPlaceholder": "مثال: https://dns.alidns.com/dns-query", + "dns.fallbackFilter.title": "تنظیمات فیلتر پشتیبان", + "dns.fallbackFilter.geoip": "فیلتر GeoIP", + "dns.fallbackFilter.geoipCode": "کد کشور GeoIP", + "dns.fallbackFilter.ipcidr": "CIDR آی‌پی پشتیبان", + "dns.fallbackFilter.ipcidrPlaceholder": "مثال: 240.0.0.0/4", + "dns.fallbackFilter.domain": "دامنه‌های پشتیبان", + "dns.fallbackFilter.domainPlaceholder": "مثال: +.google.com", "dns.nameserverPolicy.title": "سیاست جایگزینی DNS", "dns.nameserverPolicy.list": "لیست سیاست DNS", "dns.nameserverPolicy.domainPlaceholder": "دامنه", diff --git a/src/renderer/src/locales/ru-RU.json b/src/renderer/src/locales/ru-RU.json index dee2ab3..ce27fb8 100644 --- a/src/renderer/src/locales/ru-RU.json +++ b/src/renderer/src/locales/ru-RU.json @@ -344,6 +344,15 @@ "dns.nameserverPlaceholder": "Пример: tls://dns.alidns.com", "dns.directNameserver": "Сервер прямого разрешения", "dns.directNameserverPlaceholder": "Пример: tls://dns.alidns.com", + "dns.fallback": "Резервные серверы", + "dns.fallbackPlaceholder": "Пример: https://dns.alidns.com/dns-query", + "dns.fallbackFilter.title": "Настройки резервного фильтра", + "dns.fallbackFilter.geoip": "GeoIP фильтр", + "dns.fallbackFilter.geoipCode": "GeoIP код страны", + "dns.fallbackFilter.ipcidr": "Резервные IP CIDR", + "dns.fallbackFilter.ipcidrPlaceholder": "Пример: 240.0.0.0/4", + "dns.fallbackFilter.domain": "Резервные домены", + "dns.fallbackFilter.domainPlaceholder": "Пример: +.google.com", "dns.nameserverPolicy.title": "Переопределение политики DNS", "dns.nameserverPolicy.list": "Список политик DNS", "dns.nameserverPolicy.domainPlaceholder": "Домен", diff --git a/src/renderer/src/locales/zh-CN.json b/src/renderer/src/locales/zh-CN.json index 78c6381..7e42388 100644 --- a/src/renderer/src/locales/zh-CN.json +++ b/src/renderer/src/locales/zh-CN.json @@ -359,6 +359,15 @@ "dns.customHosts.list": "Hosts 列表", "dns.customHosts.domainPlaceholder": "域名", "dns.customHosts.valuePlaceholder": "域名或 IP", + "dns.fallback": "回退服务器", + "dns.fallbackPlaceholder": "例:https://dns.alidns.com/dns-query", + "dns.fallbackFilter.title": "回退过滤设置", + "dns.fallbackFilter.geoip": "GeoIP 过滤", + "dns.fallbackFilter.geoipCode": "GeoIP 国家代码", + "dns.fallbackFilter.ipcidr": "回退 IP CIDR", + "dns.fallbackFilter.ipcidrPlaceholder": "例:240.0.0.0/4", + "dns.fallbackFilter.domain": "回退域名", + "dns.fallbackFilter.domainPlaceholder": "例:+.google.com", "dns.saveOnly": "仅保存", "profiles.title": "订阅管理", "profiles.updateAll": "更新全部订阅", diff --git a/src/renderer/src/pages/dns.tsx b/src/renderer/src/pages/dns.tsx index 9d5c8cc..9a93793 100644 --- a/src/renderer/src/pages/dns.tsx +++ b/src/renderer/src/pages/dns.tsx @@ -37,7 +37,14 @@ const DNS: React.FC = () => { 'https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query' ], - 'direct-nameserver': directNameserver = [] + 'direct-nameserver': directNameserver = [], + fallback = [], + 'fallback-filter': fallbackFilter = { + geoip: true, + 'geoip-code': 'CN', + ipcidr: ['240.0.0.0/4', '0.0.0.0/32'], + domain: ['+.google.com', '+.facebook.com', '+.youtube.com'] + } } = dns || {} const [changed, setChanged] = useState(false) const [values, originSetValues] = useState({ @@ -53,6 +60,11 @@ const DNS: React.FC = () => { nameserver, proxyServerNameserver, directNameserver, + fallback, + fallbackGeoip: fallbackFilter?.geoip || true, + fallbackGeoipCode: fallbackFilter?.['geoip-code'] || 'CN', + fallbackIpcidr: fallbackFilter?.ipcidr || ['240.0.0.0/4', '0.0.0.0/32'], + fallbackDomain: fallbackFilter?.domain || ['+.google.com', '+.facebook.com', '+.youtube.com'], useNameserverPolicy, nameserverPolicy: Object.entries(nameserverPolicy || {}).map(([domain, value]) => ({ domain, @@ -160,8 +172,13 @@ const DNS: React.FC = () => { nameserver: values.nameserver, 'proxy-server-nameserver': values.proxyServerNameserver, 'direct-nameserver': values.directNameserver, - fallback: undefined, - 'fallback-filter': undefined + fallback: values.fallback, + 'fallback-filter': { + geoip: values.fallbackGeoip, + 'geoip-code': values.fallbackGeoipCode, + ipcidr: values.fallbackIpcidr, + domain: values.fallbackDomain + } } if (values.useNameserverPolicy) { dnsConfig['nameserver-policy'] = Object.fromEntries( @@ -388,6 +405,42 @@ const DNS: React.FC = () => { ))} )} + +
+

{t('dns.fallback')}

+ {renderListInputs('fallback', t('dns.fallbackPlaceholder'))} +
+ + + + { + setValues({ ...values, fallbackGeoip: v }) + }} + /> + + + { + setValues({ ...values, fallbackGeoipCode: v }) + }} + /> + +
+

{t('dns.fallbackFilter.ipcidr')}

+ {renderListInputs('fallbackIpcidr', t('dns.fallbackFilter.ipcidrPlaceholder'))} +
+ +
+

{t('dns.fallbackFilter.domain')}

+ {renderListInputs('fallbackDomain', t('dns.fallbackFilter.domainPlaceholder'))} +
)