Fix routing

This commit is contained in:
DHR60 2026-02-25 10:18:47 +08:00
parent 7b31bcdd9f
commit 8b47a90c07
4 changed files with 96 additions and 63 deletions

View file

@ -20,11 +20,14 @@ public partial class CoreConfigSingboxService
{
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
}
if (withSelector)
{
var proxyTags = proxyOutboundList.Where(n => n.tag.StartsWith(Global.ProxyTag)).Select(n => n.tag).ToList();
if (proxyTags.Count > 1)
{
proxyOutboundList.InsertRange(0, BuildSelectorOutbounds(proxyTags, baseTagName));
}
}
return proxyOutboundList;
}

View file

@ -239,6 +239,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
GenLog();
GenOutbounds();
_coreConfig.routing.domainStrategy = Global.AsIs;
_coreConfig.routing.rules.Clear();
_coreConfig.inbounds.Clear();
_coreConfig.inbounds.Add(new()
@ -249,6 +250,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
protocol = EInboundProtocol.mixed.ToString(),
});
_coreConfig.routing.rules.Add(BuildFinalRule());
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Success = true;
ret.Data = JsonUtils.Serialize(_coreConfig);

View file

@ -70,17 +70,16 @@ public partial class CoreConfigV2rayService
dnsItem.serveStale = simpleDnsItem?.ServeStale is true ? true : null;
dnsItem.enableParallelQuery = simpleDnsItem?.ParallelQuery is true ? true : null;
if (_coreConfig.routing.domainStrategy == Global.IPIfNonMatch)
{
// DNS routing
var finalRule = BuildFinalRule();
dnsItem.tag = Global.DnsTag;
_coreConfig.routing.rules.Add(new RulesItem4Ray
_coreConfig.routing.rules.Add(new()
{
type = "field",
inboundTag = new List<string> { Global.DnsTag },
outboundTag = Global.ProxyTag,
inboundTag = [Global.DnsTag],
outboundTag = finalRule.outboundTag,
balancerTag = finalRule.balancerTag
});
}
_coreConfig.dns = dnsItem;
}
@ -93,45 +92,6 @@ public partial class CoreConfigV2rayService
private void FillDnsServers(Dns4Ray dnsItem)
{
var simpleDNSItem = context.SimpleDnsItem;
static List<string> ParseDnsAddresses(string? dnsInput, string defaultAddress)
{
var addresses = dnsInput?.Split(dnsInput.Contains(',') ? ',' : ';')
.Select(addr => addr.Trim())
.Where(addr => !string.IsNullOrEmpty(addr))
.Select(addr => addr.StartsWith("dhcp", StringComparison.OrdinalIgnoreCase) ? "localhost" : addr)
.Distinct()
.ToList() ?? new List<string> { defaultAddress };
return addresses.Count > 0 ? addresses : new List<string> { defaultAddress };
}
static object? CreateDnsServer(string dnsAddress, List<string> domains, List<string>? expectedIPs = null)
{
var (domain, scheme, port, path) = Utils.ParseUrl(dnsAddress);
var domainFinal = dnsAddress;
int? portFinal = null;
if (scheme.IsNullOrEmpty() || scheme.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
{
domainFinal = domain;
portFinal = port > 0 ? port : null;
}
else if (scheme.StartsWith("tcp", StringComparison.OrdinalIgnoreCase))
{
domainFinal = scheme + "://" + domain;
portFinal = port > 0 ? port : null;
}
var dnsServer = new DnsServer4Ray
{
address = domainFinal,
port = portFinal,
skipFallback = true,
domains = domains.Count > 0 ? domains : null,
expectedIPs = expectedIPs?.Count > 0 ? expectedIPs : null
};
return JsonUtils.SerializeToNode(dnsServer, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
});
}
var directDNSAddress = ParseDnsAddresses(simpleDNSItem?.DirectDNS, Global.DomainDirectDNSAddress.First());
var remoteDNSAddress = ParseDnsAddresses(simpleDNSItem?.RemoteDNS, Global.DomainRemoteDNSAddress.First());
@ -252,17 +212,6 @@ public partial class CoreConfigV2rayService
dnsItem.servers ??= [];
void AddDnsServers(List<string> dnsAddresses, List<string> domains, List<string>? expectedIPs = null)
{
if (domains.Count > 0)
{
foreach (var dnsAddress in dnsAddresses)
{
dnsItem.servers.Add(CreateDnsServer(dnsAddress, domains, expectedIPs));
}
}
}
AddDnsServers(remoteDNSAddress, proxyDomainList);
AddDnsServers(directDNSAddress, directDomainList);
AddDnsServers(remoteDNSAddress, proxyGeositeList);
@ -281,6 +230,59 @@ public partial class CoreConfigV2rayService
var defaultDnsServers = useDirectDns ? directDNSAddress : remoteDNSAddress;
dnsItem.servers.AddRange(defaultDnsServers);
return;
static List<string> ParseDnsAddresses(string? dnsInput, string defaultAddress)
{
var addresses = dnsInput?.Split(dnsInput.Contains(',') ? ',' : ';')
.Select(addr => addr.Trim())
.Where(addr => !string.IsNullOrEmpty(addr))
.Select(addr => addr.StartsWith("dhcp", StringComparison.OrdinalIgnoreCase) ? "localhost" : addr)
.Distinct()
.ToList() ?? [defaultAddress];
return addresses.Count > 0 ? addresses : new List<string> { defaultAddress };
}
static object? CreateDnsServer(string dnsAddress, List<string> domains, List<string>? expectedIPs = null)
{
var (domain, scheme, port, path) = Utils.ParseUrl(dnsAddress);
var domainFinal = dnsAddress;
int? portFinal = null;
if (scheme.IsNullOrEmpty() || scheme.StartsWith("udp", StringComparison.OrdinalIgnoreCase))
{
domainFinal = domain;
portFinal = port > 0 ? port : null;
}
else if (scheme.StartsWith("tcp", StringComparison.OrdinalIgnoreCase))
{
domainFinal = scheme + "://" + domain;
portFinal = port > 0 ? port : null;
}
var dnsServer = new DnsServer4Ray
{
address = domainFinal,
port = portFinal,
skipFallback = true,
domains = domains.Count > 0 ? domains : null,
expectedIPs = expectedIPs?.Count > 0 ? expectedIPs : null
};
return JsonUtils.SerializeToNode(dnsServer, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
});
}
void AddDnsServers(List<string> dnsAddresses, List<string> domains, List<string>? expectedIPs = null)
{
if (domains.Count <= 0)
{
return;
}
foreach (var dnsAddress in dnsAddresses)
{
dnsItem.servers.Add(CreateDnsServer(dnsAddress, domains, expectedIPs));
}
}
}
private void FillDnsHosts(Dns4Ray dnsItem)

View file

@ -45,6 +45,7 @@ public partial class CoreConfigV2rayService
rulesItem.outboundTag = null;
}
}
_coreConfig.routing.rules.Add(BuildFinalRule());
}
}
catch (Exception ex)
@ -181,4 +182,28 @@ public partial class CoreConfigV2rayService
return tag;
}
private RulesItem4Ray BuildFinalRule()
{
var finalRule = new RulesItem4Ray()
{
type = "field",
network = "tcp,udp",
outboundTag = Global.ProxyTag,
};
var balancer =
_coreConfig?.routing?.balancers?.FirstOrDefault(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix, null);
var domainStrategy = _coreConfig.routing?.domainStrategy ?? Global.AsIs;
if (balancer is not null)
{
finalRule.outboundTag = null;
finalRule.balancerTag = balancer.tag;
}
if (domainStrategy == Global.IPIfNonMatch)
{
finalRule.network = null;
finalRule.ip = ["0.0.0.0/0", "::/0"];
}
return finalRule;
}
}