Compare commits

..

4 commits

Author SHA1 Message Date
DHR60
c1ab0ecf59
Merge 1ef2471fa2 into aea7078e95 2026-02-24 12:08:15 +00:00
DHR60
1ef2471fa2 Node test with sub chain 2026-02-24 20:07:48 +08:00
DHR60
aea7078e95
Add IP cert support (#8833) 2026-02-24 19:58:23 +08:00
DHR60
9c82df5b49
Refactor core config gen (#8768)
* Refactor core config gen

* Update tag naming

* Support sing-box 1.11 DNS

* Fix

* Optimize ProfileItem acquisition speed

* Fix

* Fix
2026-02-24 19:48:59 +08:00
6 changed files with 30 additions and 38 deletions

View file

@ -215,7 +215,7 @@ public class CertPemManager
using var client = new TcpClient(); using var client = new TcpClient();
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token); await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); await using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
var sslOptions = new SslClientAuthenticationOptions var sslOptions = new SslClientAuthenticationOptions
{ {
@ -262,7 +262,7 @@ public class CertPemManager
using var client = new TcpClient(); using var client = new TcpClient();
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token); await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); await using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
var sslOptions = new SslClientAuthenticationOptions var sslOptions = new SslClientAuthenticationOptions
{ {
@ -280,11 +280,7 @@ public class CertPemManager
var chain = new X509Chain(); var chain = new X509Chain();
chain.Build(certChain); chain.Build(certChain);
foreach (var element in chain.ChainElements) pemList.AddRange(chain.ChainElements.Select(element => ExportCertToPem(element.Certificate)));
{
var pem = ExportCertToPem(element.Certificate);
pemList.Add(pem);
}
return (pemList, null); return (pemList, null);
} }

View file

@ -23,7 +23,7 @@ public partial class CoreConfigSingboxService
} }
// Process outbounds // Process outbounds
var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : new JsonArray(); var customOutboundsNode = fullConfigTemplateNode["outbounds"] is JsonArray outbounds ? outbounds : [];
foreach (var outbound in _coreConfig.outbounds) foreach (var outbound in _coreConfig.outbounds)
{ {
if (outbound.type.ToLower() is "direct" or "block") if (outbound.type.ToLower() is "direct" or "block")
@ -44,7 +44,7 @@ public partial class CoreConfigSingboxService
// Process endpoints // Process endpoints
if (_coreConfig.endpoints != null && _coreConfig.endpoints.Count > 0) if (_coreConfig.endpoints != null && _coreConfig.endpoints.Count > 0)
{ {
var customEndpointsNode = fullConfigTemplateNode["endpoints"] is JsonArray endpoints ? endpoints : new JsonArray(); var customEndpointsNode = fullConfigTemplateNode["endpoints"] is JsonArray endpoints ? endpoints : [];
foreach (var endpoint in _coreConfig.endpoints) foreach (var endpoint in _coreConfig.endpoints)
{ {
if (endpoint.detour.IsNullOrEmpty() && !fullConfigTemplate.ProxyDetour.IsNullOrEmpty()) if (endpoint.detour.IsNullOrEmpty() && !fullConfigTemplate.ProxyDetour.IsNullOrEmpty())

View file

@ -433,15 +433,17 @@ public partial class CoreConfigSingboxService
{ {
GenDnsProtectCustom(); GenDnsProtectCustom();
var localDnsServer = _coreConfig.dns?.servers?.FirstOrDefault(s => s.tag == Global.SingboxLocalDNSTag); _coreConfig.dns?.servers?.RemoveAll(s => s.tag == Global.SingboxLocalDNSTag);
if (localDnsServer == null)
{
return;
}
localDnsServer.type = null;
localDnsServer.server = null;
var dnsItem = context.RawDnsItem; var dnsItem = context.RawDnsItem;
localDnsServer.address = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dnsItem?.DomainDNSAddress; var localDnsServer = new Server4Sbox()
{
address = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress)
? Global.DomainPureIPDNSAddress.FirstOrDefault()
: dnsItem?.DomainDNSAddress,
tag = Global.SingboxLocalDNSTag,
detour = Global.DirectTag,
};
_coreConfig.dns?.servers?.Add(localDnsServer);
} }
private Rule4Sbox BuildProtectDomainRule() private Rule4Sbox BuildProtectDomainRule()

View file

@ -19,18 +19,22 @@ public partial class CoreConfigV2rayService
// Handle balancer and rules modifications (for multiple load scenarios) // Handle balancer and rules modifications (for multiple load scenarios)
if (_coreConfig.routing?.balancers?.Count > 0) if (_coreConfig.routing?.balancers?.Count > 0)
{ {
var balancer = _coreConfig.routing.balancers.First(); var balancer =
_coreConfig.routing.balancers.FirstOrDefault(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix, null);
// Modify existing rules in custom config // Modify existing rules in custom config
var rulesNode = fullConfigTemplateNode["routing"]?["rules"]; if (balancer != null)
if (rulesNode != null)
{ {
foreach (var rule in rulesNode.AsArray()) var rulesNode = fullConfigTemplateNode["routing"]?["rules"];
if (rulesNode != null)
{ {
if (rule["outboundTag"]?.GetValue<string>() == Global.ProxyTag) foreach (var rule in rulesNode.AsArray())
{ {
rule.AsObject().Remove("outboundTag"); if (rule["outboundTag"]?.GetValue<string>() == Global.ProxyTag)
rule["balancerTag"] = balancer.tag; {
rule.AsObject().Remove("outboundTag");
rule["balancerTag"] = balancer.tag;
}
} }
} }
} }
@ -97,8 +101,8 @@ public partial class CoreConfigV2rayService
continue; continue;
} }
} }
else if ((!fullConfigTemplate.ProxyDetour.IsNullOrEmpty()) else if (!fullConfigTemplate.ProxyDetour.IsNullOrEmpty()
&& ((outbound.streamSettings?.sockopt?.dialerProxy.IsNullOrEmpty() ?? true) == true)) && (outbound.streamSettings?.sockopt?.dialerProxy.IsNullOrEmpty() ?? true))
{ {
var outboundAddress = outbound.settings?.servers?.FirstOrDefault()?.address var outboundAddress = outbound.settings?.servers?.FirstOrDefault()?.address
?? outbound.settings?.vnext?.FirstOrDefault()?.address ?? outbound.settings?.vnext?.FirstOrDefault()?.address

View file

@ -39,9 +39,9 @@ public partial class CoreConfigV2rayService
.ToList() ?? []; .ToList() ?? [];
if (balancerTagList.Count > 0) if (balancerTagList.Count > 0)
{ {
foreach (var rulesItem in _coreConfig.routing.rules.Where(r => balancerTagList.Contains(r.outboundTag))) foreach (var rulesItem in _coreConfig.routing.rules.Where(r => balancerTagList.Contains(r.outboundTag + Global.BalancerTagSuffix)))
{ {
rulesItem.balancerTag = rulesItem.outboundTag; rulesItem.balancerTag = rulesItem.outboundTag + Global.BalancerTagSuffix;
rulesItem.outboundTag = null; rulesItem.outboundTag = null;
} }
} }

View file

@ -247,11 +247,6 @@ public class AddServerViewModel : MyReactiveObject
{ {
serverName = SelectedSource.Address; serverName = SelectedSource.Address;
} }
if (!Utils.IsDomain(serverName))
{
UpdateCertTip(ResUI.ServerNameMustBeValidDomain);
return;
}
if (SelectedSource.Port > 0) if (SelectedSource.Port > 0)
{ {
domain += $":{SelectedSource.Port}"; domain += $":{SelectedSource.Port}";
@ -277,11 +272,6 @@ public class AddServerViewModel : MyReactiveObject
{ {
serverName = SelectedSource.Address; serverName = SelectedSource.Address;
} }
if (!Utils.IsDomain(serverName))
{
UpdateCertTip(ResUI.ServerNameMustBeValidDomain);
return;
}
if (SelectedSource.Port > 0) if (SelectedSource.Port > 0)
{ {
domain += $":{SelectedSource.Port}"; domain += $":{SelectedSource.Port}";