mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-11 06:54:58 +03:00
Support sing-box 1.14 (#9736)
* Support sing-box 1.14 * Unified format * Support parallel dns * Add `optimistic DNS caching` support * Try fix serial multi DNS * Add HttpClient support
This commit is contained in:
@@ -17,36 +17,11 @@ public partial class CoreConfigSingboxService
|
||||
GenDnsRules();
|
||||
|
||||
_coreConfig.dns ??= new Dns4Sbox();
|
||||
_coreConfig.dns.independent_cache = true;
|
||||
_coreConfig.dns.optimistic = context.SimpleDnsItem.ServeStale == true ? true : null;
|
||||
|
||||
// final dns
|
||||
var routing = context.RoutingItem;
|
||||
var useDirectDns = false;
|
||||
if (routing != null)
|
||||
{
|
||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||
|
||||
if (rules?.LastOrDefault() is { OutboundTag: Global.DirectTag } lastRule)
|
||||
{
|
||||
var noDomain = lastRule.Domain == null || lastRule.Domain.Count == 0;
|
||||
var noProcess = lastRule.Process == null || lastRule.Process.Count == 0;
|
||||
var isAnyIp = lastRule.Ip == null || lastRule.Ip.Count == 0 || lastRule.Ip.Contains("0.0.0.0/0");
|
||||
var isAnyPort = string.IsNullOrEmpty(lastRule.Port) || lastRule.Port == "0-65535";
|
||||
var isAnyNetwork = string.IsNullOrEmpty(lastRule.Network) || lastRule.Network == "tcp,udp";
|
||||
useDirectDns = noDomain && noProcess && isAnyIp && isAnyPort && isAnyNetwork;
|
||||
}
|
||||
}
|
||||
var useDirectDns = UseDirectDns();
|
||||
_coreConfig.dns.final = useDirectDns ? Global.SingboxDirectDNSTag : Global.SingboxRemoteDNSTag;
|
||||
var simpleDnsItem = context.SimpleDnsItem;
|
||||
if ((!useDirectDns) && simpleDnsItem.FakeIP == true && simpleDnsItem.GlobalFakeIp == false)
|
||||
{
|
||||
_coreConfig.dns.rules.Add(new()
|
||||
{
|
||||
server = Global.SingboxFakeDNSTag,
|
||||
query_type = new List<int> { 1, 28 }, // A and AAAA
|
||||
rewrite_ttl = 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -59,14 +34,24 @@ public partial class CoreConfigSingboxService
|
||||
var simpleDnsItem = context.SimpleDnsItem;
|
||||
var finalDns = GenBootstrapDns();
|
||||
|
||||
var directDns = ParseDnsAddress(simpleDnsItem.DirectDNS ?? Global.DomainDirectDNSAddress.First());
|
||||
directDns.tag = Global.SingboxDirectDNSTag;
|
||||
directDns.domain_resolver = Global.SingboxLocalDNSTag;
|
||||
var directDnsList = ParseDnsAddresses(simpleDnsItem.DirectDNS ?? Global.DomainDirectDNSAddress.First());
|
||||
for (var i = 0; i < directDnsList.Count; i++)
|
||||
{
|
||||
var directDns = directDnsList[i];
|
||||
var tag = string.Format(Global.SingboxDirectDNSTagTemplate, i + 1);
|
||||
directDns.tag = tag;
|
||||
directDns.domain_resolver = Global.SingboxLocalDNSTag;
|
||||
}
|
||||
|
||||
var remoteDns = ParseDnsAddress(simpleDnsItem.RemoteDNS ?? Global.DomainRemoteDNSAddress.First());
|
||||
remoteDns.tag = Global.SingboxRemoteDNSTag;
|
||||
remoteDns.detour = Global.ProxyTag;
|
||||
remoteDns.domain_resolver = Global.SingboxLocalDNSTag;
|
||||
var remoteDnsList = ParseDnsAddresses(simpleDnsItem.RemoteDNS ?? Global.DomainRemoteDNSAddress.First());
|
||||
for (var i = 0; i < remoteDnsList.Count; i++)
|
||||
{
|
||||
var remoteDns = remoteDnsList[i];
|
||||
var tag = string.Format(Global.SingboxRemoteDNSTagTemplate, i + 1);
|
||||
remoteDns.tag = tag;
|
||||
remoteDns.detour = Global.ProxyTag;
|
||||
remoteDns.domain_resolver = Global.SingboxLocalDNSTag;
|
||||
}
|
||||
|
||||
var hostsDns = new Server4Sbox
|
||||
{
|
||||
@@ -118,26 +103,28 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
finalDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||
}
|
||||
if (remoteDns.server == host.Key)
|
||||
{
|
||||
remoteDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||
}
|
||||
if (directDns.server == host.Key)
|
||||
foreach (var directDns in directDnsList.Where(directDns => directDns.server == host.Key))
|
||||
{
|
||||
directDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||
}
|
||||
foreach (var remoteDns in remoteDnsList.Where(remoteDns => remoteDns.server == host.Key))
|
||||
{
|
||||
remoteDns.domain_resolver = Global.SingboxHostsDNSTag;
|
||||
}
|
||||
}
|
||||
|
||||
_coreConfig.dns ??= new Dns4Sbox();
|
||||
_coreConfig.dns.servers ??= [];
|
||||
_coreConfig.dns.servers.Add(remoteDns);
|
||||
_coreConfig.dns.servers.Add(directDns);
|
||||
_coreConfig.dns.servers.AddRange(remoteDnsList);
|
||||
_coreConfig.dns.servers.AddRange(directDnsList);
|
||||
_coreConfig.dns.servers.Add(hostsDns);
|
||||
|
||||
// fake ip
|
||||
if (simpleDnsItem.FakeIP == true)
|
||||
{
|
||||
var fakeipRange = simpleDnsItem.FakeIPRange.IsNullOrEmpty() ? Global.FakeIPRanges.First() : simpleDnsItem.FakeIPRange;
|
||||
var fakeipRange = simpleDnsItem.FakeIPRange.IsNullOrEmpty()
|
||||
? Global.FakeIPRanges.First()
|
||||
: simpleDnsItem.FakeIPRange;
|
||||
var fakeip = new Server4Sbox
|
||||
{
|
||||
tag = Global.SingboxFakeDNSTag,
|
||||
@@ -164,33 +151,33 @@ public partial class CoreConfigSingboxService
|
||||
_coreConfig.dns ??= new Dns4Sbox();
|
||||
_coreConfig.dns.rules ??= [];
|
||||
|
||||
_coreConfig.dns.rules.Add(new() { ip_accept_any = true, server = Global.SingboxHostsDNSTag });
|
||||
_coreConfig.dns.rules.Add(new()
|
||||
{
|
||||
preferred_by = Global.SingboxHostsDNSTag,
|
||||
server = Global.SingboxHostsDNSTag,
|
||||
});
|
||||
|
||||
if (context.ProtectDomainList.Count > 0)
|
||||
{
|
||||
_coreConfig.dns.rules.Add(new()
|
||||
{
|
||||
server = Global.SingboxDirectDNSTag,
|
||||
strategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4ProxyDial),
|
||||
domain = context.ProtectDomainList.ToList(),
|
||||
});
|
||||
}
|
||||
|
||||
_coreConfig.dns.rules.AddRange(new[]
|
||||
{
|
||||
_coreConfig.dns.rules.AddRange([
|
||||
new Rule4Sbox
|
||||
{
|
||||
server = Global.SingboxRemoteDNSTag,
|
||||
strategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4Proxy),
|
||||
clash_mode = nameof(ERuleMode.Global)
|
||||
clash_mode = nameof(ERuleMode.Global),
|
||||
},
|
||||
new Rule4Sbox
|
||||
{
|
||||
server = Global.SingboxDirectDNSTag,
|
||||
strategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4Freedom),
|
||||
clash_mode = nameof(ERuleMode.Direct)
|
||||
}
|
||||
});
|
||||
clash_mode = nameof(ERuleMode.Direct),
|
||||
},
|
||||
]);
|
||||
|
||||
foreach (var kvp in Utils.ParseHostsToDictionary(simpleDnsItem.Hosts))
|
||||
{
|
||||
@@ -199,7 +186,7 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var rule = new Rule4Sbox()
|
||||
var rule = new Rule4Sbox
|
||||
{
|
||||
query_type = [1, 5, 28], // A, CNAME and AAAA
|
||||
action = "predefined",
|
||||
@@ -262,13 +249,14 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
query_type = [64, 65],
|
||||
action = "predefined",
|
||||
rcode = "NOERROR"
|
||||
rcode = "NOERROR",
|
||||
});
|
||||
}
|
||||
|
||||
if (simpleDnsItem.FakeIP == true && simpleDnsItem.GlobalFakeIp != false)
|
||||
{
|
||||
var fakeipFilterRule = JsonUtils.Deserialize<Rule4Sbox>(EmbedUtils.GetEmbedText(Global.SingboxFakeIPFilterFileName));
|
||||
var fakeipFilterRule =
|
||||
JsonUtils.Deserialize<Rule4Sbox>(EmbedUtils.GetEmbedText(Global.SingboxFakeIPFilterFileName));
|
||||
fakeipFilterRule.invert = true;
|
||||
var rule4Fake = new Rule4Sbox
|
||||
{
|
||||
@@ -305,6 +293,11 @@ public partial class CoreConfigSingboxService
|
||||
return;
|
||||
}
|
||||
|
||||
var directDnsList = _coreConfig.dns.servers
|
||||
.Where(s => s.tag?.StartsWith(Global.SingboxDirectDNSTagPrefix) == true).ToList();
|
||||
var remoteDnsList = _coreConfig.dns.servers
|
||||
.Where(s => s.tag?.StartsWith(Global.SingboxRemoteDNSTagPrefix) == true).ToList();
|
||||
|
||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||
var expectedIPCidr = new HashSet<string>();
|
||||
var expectedIPsRegions = new HashSet<string>();
|
||||
@@ -312,8 +305,7 @@ public partial class CoreConfigSingboxService
|
||||
|
||||
if (!string.IsNullOrEmpty(simpleDnsItem?.DirectExpectedIPs))
|
||||
{
|
||||
var ipItems = simpleDnsItem.DirectExpectedIPs
|
||||
.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
var ipItems = (Utils.String2List(simpleDnsItem.DirectExpectedIPs) ?? [])
|
||||
.Select(s => s.Trim())
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.ToHashSet();
|
||||
@@ -359,35 +351,60 @@ public partial class CoreConfigSingboxService
|
||||
|
||||
if (item.OutboundTag == Global.DirectTag)
|
||||
{
|
||||
rule.server = Global.SingboxDirectDNSTag;
|
||||
rule.strategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4Freedom);
|
||||
Rule4Sbox? rule4ExpectedIPs = null;
|
||||
|
||||
if (expectedIPsRegions.Count > 0 && rule.geosite?.Count > 0 && !regionName.IsNullOrEmpty())
|
||||
{
|
||||
var regionGeosite = rule.geosite.Where(g => g.EndsWith($"-{regionName}", StringComparison.OrdinalIgnoreCase)
|
||||
|| g.EndsWith($"@{regionName}", StringComparison.OrdinalIgnoreCase)
|
||||
|| g == regionName).ToList();
|
||||
var regionGeosite = rule.geosite.Where(g =>
|
||||
g.EndsWith($"-{regionName}", StringComparison.OrdinalIgnoreCase)
|
||||
|| g.EndsWith($"@{regionName}", StringComparison.OrdinalIgnoreCase)
|
||||
|| g == regionName).ToList();
|
||||
if (regionGeosite.Count > 0)
|
||||
{
|
||||
rule.geosite.RemoveAll(regionGeosite.Contains);
|
||||
var rule4ExpectedIPs = JsonUtils.DeepCopy(rule);
|
||||
rule4ExpectedIPs = JsonUtils.DeepCopy(rule);
|
||||
rule4ExpectedIPs.geosite = regionGeosite;
|
||||
}
|
||||
}
|
||||
|
||||
if (rule.geosite?.Count > 0 || rule.domain?.Count > 0)
|
||||
{
|
||||
AddRules(rule, item, directDnsList);
|
||||
}
|
||||
|
||||
if (rule4ExpectedIPs is not null)
|
||||
{
|
||||
var expectedRuleList = BuildMultiRules(rule4ExpectedIPs, item, directDnsList);
|
||||
foreach (var expectedRule in
|
||||
expectedRuleList.Where(expectedRule => expectedRule.action == "respond"))
|
||||
{
|
||||
if (expectedIPsRegions.Count > 0)
|
||||
{
|
||||
rule4ExpectedIPs.geoip = expectedIPsRegions.ToList();
|
||||
expectedRule.geoip = expectedIPsRegions.ToList();
|
||||
}
|
||||
if (expectedIPCidr.Count > 0)
|
||||
{
|
||||
rule4ExpectedIPs.ip_cidr = expectedIPCidr.ToList();
|
||||
expectedRule.ip_cidr = expectedIPCidr.ToList();
|
||||
}
|
||||
_coreConfig.dns.rules.Add(rule4ExpectedIPs);
|
||||
}
|
||||
_coreConfig.dns.rules.AddRange(expectedRuleList);
|
||||
var fallbackRemoteRuleList = BuildMultiRules(rule4ExpectedIPs, item, remoteDnsList);
|
||||
if (expectedRuleList.LastOrDefault()?.race == true)
|
||||
{
|
||||
foreach (var fallbackRemoteRule in fallbackRemoteRuleList.Where(fallbackRemoteRule =>
|
||||
fallbackRemoteRule.action == "evaluate"))
|
||||
{
|
||||
fallbackRemoteRule.speculative = true;
|
||||
}
|
||||
}
|
||||
_coreConfig.dns.rules.AddRange(fallbackRemoteRuleList);
|
||||
}
|
||||
}
|
||||
else if (item.OutboundTag == Global.BlockTag)
|
||||
{
|
||||
rule.action = "predefined";
|
||||
rule.rcode = "NXDOMAIN";
|
||||
_coreConfig.dns.rules.Add(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -395,15 +412,104 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
var rule4Fake = JsonUtils.DeepCopy(rule);
|
||||
rule4Fake.server = Global.SingboxFakeDNSTag;
|
||||
rule4Fake.query_type = new List<int> { 1, 28 }; // A and AAAA
|
||||
rule4Fake.query_type = new List<int>
|
||||
{
|
||||
1,
|
||||
28,
|
||||
}; // A and AAAA
|
||||
rule4Fake.rewrite_ttl = 1;
|
||||
_coreConfig.dns.rules.Add(rule4Fake);
|
||||
}
|
||||
rule.server = Global.SingboxRemoteDNSTag;
|
||||
rule.strategy = Utils.DomainStrategy4Sbox(simpleDnsItem.Strategy4Proxy);
|
||||
AddRules(rule, item, remoteDnsList);
|
||||
}
|
||||
}
|
||||
var useDirectDns = UseDirectDns();
|
||||
if ((!useDirectDns) && simpleDnsItem.FakeIP == true && simpleDnsItem.GlobalFakeIp == false)
|
||||
{
|
||||
_coreConfig.dns.rules.Add(new()
|
||||
{
|
||||
server = Global.SingboxFakeDNSTag,
|
||||
query_type =
|
||||
[
|
||||
1,
|
||||
28,
|
||||
], // A and AAAA
|
||||
rewrite_ttl = 1,
|
||||
});
|
||||
}
|
||||
var tempRuleItem = new RulesItem
|
||||
{
|
||||
Id = $"final-{Utils.GetGuid(false)}",
|
||||
Enabled = true,
|
||||
};
|
||||
AddRules(new(), tempRuleItem, useDirectDns ? directDnsList : remoteDnsList);
|
||||
return;
|
||||
|
||||
_coreConfig.dns.rules.Add(rule);
|
||||
static List<Rule4Sbox> BuildParallelRules(Rule4Sbox rule, RulesItem item, List<Server4Sbox> dnsList)
|
||||
{
|
||||
var evaluateRuleList = new List<Rule4Sbox>();
|
||||
var racingMatchingRuleList = new List<Rule4Sbox>();
|
||||
foreach (var dnsServer in dnsList)
|
||||
{
|
||||
var dnsServerTag = dnsServer.tag;
|
||||
var evaluateRule = JsonUtils.DeepCopy(rule);
|
||||
evaluateRule.action = "evaluate";
|
||||
// Maybe rule index is better than id? Not sure, but id is unique, so use id for now.
|
||||
var evaluateTag = $"{dnsServerTag}-{item.Id}";
|
||||
evaluateRule.tag = evaluateTag;
|
||||
evaluateRule.server = dnsServerTag;
|
||||
evaluateRuleList.Add(evaluateRule);
|
||||
var racingMatchingRule = new Rule4Sbox
|
||||
{
|
||||
match_response = evaluateTag,
|
||||
race = true,
|
||||
action = "respond",
|
||||
};
|
||||
racingMatchingRuleList.Add(racingMatchingRule);
|
||||
}
|
||||
return [.. evaluateRuleList, .. racingMatchingRuleList];
|
||||
}
|
||||
|
||||
static List<Rule4Sbox> BuildSerialRules(Rule4Sbox rule, RulesItem item, List<Server4Sbox> dnsList)
|
||||
{
|
||||
var ruleList = new List<Rule4Sbox>();
|
||||
foreach (var dnsServer in dnsList)
|
||||
{
|
||||
var dnsServerTag = dnsServer.tag;
|
||||
var evaluateRule = JsonUtils.DeepCopy(rule);
|
||||
evaluateRule.action = "evaluate";
|
||||
// Maybe rule index is better than id? Not sure, but id is unique, so use id for now.
|
||||
var evaluateTag = $"{dnsServerTag}-{item.Id}";
|
||||
evaluateRule.tag = evaluateTag;
|
||||
evaluateRule.server = dnsServerTag;
|
||||
ruleList.Add(evaluateRule);
|
||||
var racingMatchingRule = new Rule4Sbox
|
||||
{
|
||||
match_response = evaluateTag,
|
||||
action = "respond",
|
||||
};
|
||||
ruleList.Add(racingMatchingRule);
|
||||
}
|
||||
return ruleList;
|
||||
}
|
||||
|
||||
List<Rule4Sbox> BuildMultiRules(Rule4Sbox rule, RulesItem item, List<Server4Sbox> dnsList)
|
||||
{
|
||||
return simpleDnsItem.ParallelQuery == true ? BuildParallelRules(rule, item, dnsList) : BuildSerialRules(rule, item, dnsList);
|
||||
}
|
||||
|
||||
void AddRules(Rule4Sbox rule, RulesItem item, List<Server4Sbox> dnsList)
|
||||
{
|
||||
if (dnsList.Count == 1)
|
||||
{
|
||||
rule.server = dnsList.First().tag;
|
||||
_coreConfig.dns.rules.Add(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ruleList = BuildMultiRules(rule, item, dnsList);
|
||||
_coreConfig.dns.rules.AddRange(ruleList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,11 +538,15 @@ public partial class CoreConfigSingboxService
|
||||
var strDNS = string.Empty;
|
||||
if (context.IsTunEnabled)
|
||||
{
|
||||
strDNS = string.IsNullOrEmpty(item?.TunDNS) ? EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS;
|
||||
strDNS = string.IsNullOrEmpty(item?.TunDNS)
|
||||
? EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName)
|
||||
: item?.TunDNS;
|
||||
}
|
||||
else
|
||||
{
|
||||
strDNS = string.IsNullOrEmpty(item?.NormalDNS) ? EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS;
|
||||
strDNS = string.IsNullOrEmpty(item?.NormalDNS)
|
||||
? EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName)
|
||||
: item?.NormalDNS;
|
||||
}
|
||||
|
||||
var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS);
|
||||
@@ -464,15 +574,18 @@ public partial class CoreConfigSingboxService
|
||||
dns4Sbox.rules.Insert(0, new()
|
||||
{
|
||||
server = tag,
|
||||
clash_mode = nameof(ERuleMode.Direct)
|
||||
clash_mode = nameof(ERuleMode.Direct),
|
||||
});
|
||||
dns4Sbox.rules.Insert(0, new()
|
||||
{
|
||||
server = dns4Sbox.servers.Where(t => t.detour == Global.ProxyTag).Select(t => t.tag).FirstOrDefault() ?? "remote",
|
||||
clash_mode = nameof(ERuleMode.Global)
|
||||
server = dns4Sbox.servers.Where(t => t.detour == Global.ProxyTag).Select(t => t.tag).FirstOrDefault() ??
|
||||
"remote",
|
||||
clash_mode = nameof(ERuleMode.Global),
|
||||
});
|
||||
|
||||
var finalDnsAddress = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress) ? Global.DomainPureIPDNSAddress.FirstOrDefault() : dnsItem?.DomainDNSAddress;
|
||||
var finalDnsAddress = string.IsNullOrEmpty(dnsItem?.DomainDNSAddress)
|
||||
? Global.DomainPureIPDNSAddress.FirstOrDefault()
|
||||
: dnsItem?.DomainDNSAddress;
|
||||
|
||||
var localDnsServer = ParseDnsAddress(finalDnsAddress);
|
||||
localDnsServer.tag = tag;
|
||||
@@ -500,9 +613,21 @@ public partial class CoreConfigSingboxService
|
||||
};
|
||||
}
|
||||
|
||||
private static List<Server4Sbox> ParseDnsAddresses(string addresses)
|
||||
{
|
||||
var servers = new List<Server4Sbox>();
|
||||
var addressList = Utils.String2List(addresses)?.ToList();
|
||||
if (addressList is not { Count: > 0 })
|
||||
{
|
||||
return servers;
|
||||
}
|
||||
servers.AddRange(addressList.Select(ParseDnsAddress).Where(s => s != null));
|
||||
return servers;
|
||||
}
|
||||
|
||||
private static Server4Sbox? ParseDnsAddress(string address)
|
||||
{
|
||||
var addressFirst = address?.Split(address.Contains(',') ? ',' : ';').FirstOrDefault()?.Trim();
|
||||
var addressFirst = Utils.String2List(address)?.FirstOrDefault()?.Trim();
|
||||
if (string.IsNullOrEmpty(addressFirst))
|
||||
{
|
||||
return null;
|
||||
@@ -547,10 +672,33 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
server.server_port = port;
|
||||
}
|
||||
if ((server.type == "https" || server.type == "h3") && !string.IsNullOrEmpty(path) && path != "/")
|
||||
if (server.type is "https" or "h3" && !string.IsNullOrEmpty(path) && path != "/")
|
||||
{
|
||||
server.path = path;
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
private bool UseDirectDns()
|
||||
{
|
||||
var routing = context.RoutingItem;
|
||||
var useDirectDns = false;
|
||||
if (routing == null)
|
||||
{
|
||||
return useDirectDns;
|
||||
}
|
||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||
|
||||
if (rules?.LastOrDefault() is not { OutboundTag: Global.DirectTag } lastRule)
|
||||
{
|
||||
return useDirectDns;
|
||||
}
|
||||
var noDomain = lastRule.Domain == null || lastRule.Domain.Count == 0;
|
||||
var noProcess = lastRule.Process == null || lastRule.Process.Count == 0;
|
||||
var isAnyIp = lastRule.Ip == null || lastRule.Ip.Count == 0 || lastRule.Ip.Contains("0.0.0.0/0");
|
||||
var isAnyPort = string.IsNullOrEmpty(lastRule.Port) || lastRule.Port == "0-65535";
|
||||
var isAnyNetwork = string.IsNullOrEmpty(lastRule.Network) || lastRule.Network == "tcp,udp";
|
||||
useDirectDns = noDomain && noProcess && isAnyIp && isAnyPort && isAnyNetwork;
|
||||
return useDirectDns;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ public partial class CoreConfigSingboxService
|
||||
var resolveRule = new Rule4Sbox
|
||||
{
|
||||
action = "resolve",
|
||||
strategy = domainStrategy
|
||||
strategy = domainStrategy,
|
||||
};
|
||||
if (_config.RoutingBasicItem.DomainStrategy == Global.IPOnDemand)
|
||||
{
|
||||
|
||||
@@ -79,6 +79,7 @@ public partial class CoreConfigSingboxService
|
||||
|
||||
//Add ruleset srs
|
||||
_coreConfig.route.rule_set = [];
|
||||
var containRemoteRuleset = false;
|
||||
foreach (var item in new HashSet<string>(ruleSets))
|
||||
{
|
||||
if (item.IsNullOrEmpty())
|
||||
@@ -94,11 +95,13 @@ public partial class CoreConfigSingboxService
|
||||
type = "local",
|
||||
format = "binary",
|
||||
tag = item,
|
||||
path = pathSrs
|
||||
path = pathSrs,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
containRemoteRuleset = true;
|
||||
|
||||
var srsUrl = string.IsNullOrEmpty(_config.ConstItem.SrsSourceUrl)
|
||||
? Global.SingboxRulesetUrl
|
||||
: _config.ConstItem.SrsSourceUrl;
|
||||
@@ -109,11 +112,21 @@ public partial class CoreConfigSingboxService
|
||||
format = "binary",
|
||||
tag = item,
|
||||
url = string.Format(srsUrl, item.StartsWith(geosite) ? geosite : geoip, item),
|
||||
download_detour = Global.ProxyTag
|
||||
http_client = Global.SingboxSrsDownloadHttpClientTag,
|
||||
};
|
||||
}
|
||||
}
|
||||
_coreConfig.route.rule_set.Add(customRuleset);
|
||||
}
|
||||
|
||||
if (containRemoteRuleset)
|
||||
{
|
||||
_coreConfig.http_clients ??= [];
|
||||
_coreConfig.http_clients.Add(new()
|
||||
{
|
||||
tag = Global.SingboxSrsDownloadHttpClientTag,
|
||||
detour = Global.ProxyTag,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user