diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs index 1375d760..fa089140 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxDnsService.cs @@ -134,24 +134,20 @@ public partial class CoreConfigSingboxService } // ech - if (node?.StreamSecurity == Global.StreamSecurity - && node?.EchConfigList?.Contains("://") == true) + var (_, dnsServer) = ParseEchParam(node?.EchConfigList); + if (dnsServer is not null) { - // example.com+https://1.1.1.1/dns-query - var idx = node.EchConfigList.IndexOf('+'); - var echDnsServer = idx > 0 ? node.EchConfigList[(idx + 1)..] : node.EchConfigList; - var echDnsObject = ParseDnsAddress(echDnsServer); - echDnsObject.tag = Global.SingboxEchDNSTag; - if (echDnsObject.server is not null - && hostsDns.predefined.ContainsKey(echDnsObject.server)) + dnsServer.tag = Global.SingboxEchDNSTag; + if (dnsServer.server is not null + && hostsDns.predefined.ContainsKey(dnsServer.server)) { - echDnsObject.domain_resolver = Global.SingboxHostsDNSTag; + dnsServer.domain_resolver = Global.SingboxHostsDNSTag; } else { - echDnsObject.domain_resolver = Global.SingboxLocalDNSTag; + dnsServer.domain_resolver = Global.SingboxLocalDNSTag; } - singboxConfig.dns.servers.Add(echDnsObject); + singboxConfig.dns.servers.Add(dnsServer); } else if (node?.ConfigType.IsGroupType() == true) { @@ -195,16 +191,15 @@ public partial class CoreConfigSingboxService } }); - if (node?.StreamSecurity == Global.StreamSecurity - && node?.EchConfigList?.Contains("://") == true) + var (ech, _) = ParseEchParam(node?.EchConfigList); + if (ech is not null) { - var idx = node.EchConfigList.IndexOf('+'); - List queryServerNames = [(idx > 0 ? node.EchConfigList[..idx] : node.Sni)]; + var echDomain = ech.query_server_name ?? node?.Sni; singboxConfig.dns.rules.Add(new() { query_type = new List { 64, 65 }, server = Global.SingboxEchDNSTag, - domain = queryServerNames, + domain = echDomain is not null ? new List { echDomain } : null, }); } else if (node?.ConfigType.IsGroupType() == true) diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index 9d11af7f..e2c0d502 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -334,24 +334,9 @@ public partial class CoreConfigSingboxService }; tls.insecure = false; } - - if (!node.EchConfigList.IsNullOrEmpty()) + var (ech, _) = ParseEchParam(node.EchConfigList); + if (ech is not null) { - var ech = new Ech4Sbox() - { - enabled = true, - }; - if (node.EchConfigList.Contains("://")) - { - var idx = node.EchConfigList.IndexOf('+'); - ech.query_server_name = idx > 0 ? node.EchConfigList[..idx] : null; - } - else - { - ech.config = [$"-----BEGIN ECH CONFIGS-----\n" + - $"{node.EchConfigList}\n" + - $"-----END ECH CONFIGS-----"]; - } tls.ech = ech; } outbound.tls = tls; @@ -924,4 +909,31 @@ public partial class CoreConfigSingboxService } return await Task.FromResult(0); } + + private (Ech4Sbox? ech, Server4Sbox? dnsServer) ParseEchParam(string? echConfig) + { + if (echConfig.IsNullOrEmpty()) + { + return (null, null); + } + if (!echConfig.Contains("://")) + { + return (new Ech4Sbox() + { + enabled = true, + config = [$"-----BEGIN ECH CONFIGS-----\n" + + $"{echConfig}\n" + + $"-----END ECH CONFIGS-----"], + }, null); + } + var idx = echConfig.IndexOf('+'); + // NOTE: query_server_name, since sing-box 1.13.0 + //var queryServerName = idx > 0 ? echConfig[..idx] : null; + var echDnsServer = idx > 0 ? echConfig[(idx + 1)..] : echConfig; + return (new Ech4Sbox() + { + enabled = true, + query_server_name = null, + }, ParseDnsAddress(echDnsServer)); + } }