mirror of
https://github.com/2dust/v2rayN.git
synced 2026-02-28 05:03:02 +00:00
Compare commits
8 commits
6143fdad90
...
eec565357a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eec565357a | ||
|
|
7128852ddb | ||
|
|
ed1275e29f | ||
|
|
0cf07e925f | ||
|
|
49e487886d | ||
|
|
ad07f281c7 | ||
|
|
f98f517368 | ||
|
|
7931058342 |
20 changed files with 207 additions and 126 deletions
6
.github/workflows/build-linux.yml
vendored
6
.github/workflows/build-linux.yml
vendored
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o "$OutputPathArm64"
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
uses: actions/upload-artifact@v7.0.0
|
||||
with:
|
||||
name: v2rayN-linux
|
||||
path: |
|
||||
|
|
@ -169,7 +169,7 @@ jobs:
|
|||
fetch-depth: '0'
|
||||
|
||||
- name: Restore build artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: v2rayN-linux
|
||||
path: ${{ github.workspace }}/v2rayN/Release
|
||||
|
|
@ -190,7 +190,7 @@ jobs:
|
|||
ls -R "$GITHUB_WORKSPACE/dist/rpm" || true
|
||||
|
||||
- name: Upload RPM artifacts
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
uses: actions/upload-artifact@v7.0.0
|
||||
with:
|
||||
name: v2rayN-rpm
|
||||
path: dist/rpm/**/*.rpm
|
||||
|
|
|
|||
2
.github/workflows/build-osx.yml
vendored
2
.github/workflows/build-osx.yml
vendored
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
uses: actions/upload-artifact@v7.0.0
|
||||
with:
|
||||
name: v2rayN-macos
|
||||
path: |
|
||||
|
|
|
|||
2
.github/workflows/build-windows-desktop.yml
vendored
2
.github/workflows/build-windows-desktop.yml
vendored
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 -p:SelfContained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
uses: actions/upload-artifact@v7.0.0
|
||||
with:
|
||||
name: v2rayN-windows-desktop
|
||||
path: |
|
||||
|
|
|
|||
2
.github/workflows/build-windows.yml
vendored
2
.github/workflows/build-windows.yml
vendored
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 -p:SelfContained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
uses: actions/upload-artifact@v7.0.0
|
||||
with:
|
||||
name: v2rayN-windows
|
||||
path: |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>7.18.0</Version>
|
||||
<Version>7.19.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.12" />
|
||||
<PackageVersion Include="ReactiveUI.Avalonia" Version="11.3.8" />
|
||||
<PackageVersion Include="CliWrap" Version="3.10.0" />
|
||||
<PackageVersion Include="Downloader" Version="4.0.3" />
|
||||
<PackageVersion Include="Downloader" Version="4.1.1" />
|
||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" />
|
||||
<PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
|
||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.3.1.1" />
|
||||
|
|
|
|||
|
|
@ -629,12 +629,7 @@ public class Utils
|
|||
{
|
||||
try
|
||||
{
|
||||
List<IPEndPoint> lstIpEndPoints = new();
|
||||
List<TcpConnectionInformation> lstTcpConns = new();
|
||||
|
||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
|
||||
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
|
||||
var (lstIpEndPoints, lstTcpConns) = GetActiveNetworkInfo();
|
||||
|
||||
if (lstIpEndPoints?.FindIndex(it => it.Port == port) >= 0)
|
||||
{
|
||||
|
|
@ -676,6 +671,27 @@ public class Utils
|
|||
return 59090;
|
||||
}
|
||||
|
||||
public static (List<IPEndPoint> endpoints, List<TcpConnectionInformation> connections) GetActiveNetworkInfo()
|
||||
{
|
||||
var endpoints = new List<IPEndPoint>();
|
||||
var connections = new List<TcpConnectionInformation>();
|
||||
|
||||
try
|
||||
{
|
||||
var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
|
||||
|
||||
endpoints.AddRange(ipGlobalProperties.GetActiveTcpListeners());
|
||||
endpoints.AddRange(ipGlobalProperties.GetActiveUdpListeners());
|
||||
connections.AddRange(ipGlobalProperties.GetActiveTcpConnections());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
}
|
||||
|
||||
return (endpoints, connections);
|
||||
}
|
||||
|
||||
#endregion Speed Test
|
||||
|
||||
#region Miscellaneous
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public class Global
|
|||
public const string DirectTag = "direct";
|
||||
public const string BlockTag = "block";
|
||||
public const string DnsTag = "dns-module";
|
||||
public const string DirectDnsTag = "direct-dns";
|
||||
public const string BalancerTagSuffix = "-round";
|
||||
public const string StreamSecurity = "tls";
|
||||
public const string StreamSecurityReality = "reality";
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ public class DownloaderHelper
|
|||
|
||||
var downloadOpt = new DownloadConfiguration()
|
||||
{
|
||||
Timeout = timeout * 1000,
|
||||
BlockTimeout = timeout * 1000,
|
||||
MaxTryAgainOnFailure = 2,
|
||||
RequestConfiguration =
|
||||
{
|
||||
Headers = headers,
|
||||
UserAgent = userAgent,
|
||||
Timeout = timeout * 1000,
|
||||
ConnectTimeout = timeout * 1000,
|
||||
Proxy = webProxy
|
||||
}
|
||||
};
|
||||
|
|
@ -62,11 +62,11 @@ public class DownloaderHelper
|
|||
|
||||
var downloadOpt = new DownloadConfiguration()
|
||||
{
|
||||
Timeout = timeout * 1000,
|
||||
BlockTimeout = timeout * 1000,
|
||||
MaxTryAgainOnFailure = 2,
|
||||
RequestConfiguration =
|
||||
{
|
||||
Timeout= timeout * 1000,
|
||||
ConnectTimeout= timeout * 1000,
|
||||
Proxy = webProxy
|
||||
}
|
||||
};
|
||||
|
|
@ -139,11 +139,11 @@ public class DownloaderHelper
|
|||
|
||||
var downloadOpt = new DownloadConfiguration()
|
||||
{
|
||||
Timeout = timeout * 1000,
|
||||
BlockTimeout = timeout * 1000,
|
||||
MaxTryAgainOnFailure = 2,
|
||||
RequestConfiguration =
|
||||
{
|
||||
Timeout= timeout * 1000,
|
||||
ConnectTimeout= timeout * 1000,
|
||||
Proxy = webProxy
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ public class CoreManager
|
|||
{
|
||||
context = context with
|
||||
{
|
||||
TunProtectSsPort = preContext.TunProtectSsPort, ProxyRelaySsPort = preContext.ProxyRelaySsPort,
|
||||
TunProtectSsPort = preContext.TunProtectSsPort,
|
||||
ProxyRelaySsPort = preContext.ProxyRelaySsPort,
|
||||
};
|
||||
}
|
||||
var result = await CoreConfigHandler.GenerateClientConfig(context, fileName);
|
||||
|
|
|
|||
|
|
@ -257,6 +257,7 @@ public class Server4Sbox : BaseServer4Sbox
|
|||
|
||||
// Deprecated in sing-box 1.12.0 , kept for backward compatibility
|
||||
public string? address { get; set; }
|
||||
|
||||
public string? address_resolver { get; set; }
|
||||
public string? address_strategy { get; set; }
|
||||
public string? strategy { get; set; }
|
||||
|
|
|
|||
|
|
@ -220,12 +220,6 @@ public class DnsServer4Ray
|
|||
public List<string>? domains { get; set; }
|
||||
public bool? skipFallback { get; set; }
|
||||
public List<string>? expectedIPs { get; set; }
|
||||
public List<string>? unexpectedIPs { get; set; }
|
||||
public string? clientIp { get; set; }
|
||||
public string? queryStrategy { get; set; }
|
||||
public int? timeoutMs { get; set; }
|
||||
public bool? disableCache { get; set; }
|
||||
public bool? finalQuery { get; set; }
|
||||
public string? tag { get; set; }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,18 +137,8 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
|||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
List<IPEndPoint> lstIpEndPoints = new();
|
||||
List<TcpConnectionInformation> lstTcpConns = new();
|
||||
try
|
||||
{
|
||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
|
||||
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
}
|
||||
|
||||
var (lstIpEndPoints, lstTcpConns) = Utils.GetActiveNetworkInfo();
|
||||
|
||||
GenLog();
|
||||
GenMinimizedDns();
|
||||
|
|
|
|||
|
|
@ -26,11 +26,15 @@ public partial class CoreConfigSingboxService
|
|||
{
|
||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||
|
||||
useDirectDns = rules?.LastOrDefault() is { } lastRule &&
|
||||
lastRule.OutboundTag == Global.DirectTag &&
|
||||
(lastRule.Port == "0-65535" ||
|
||||
lastRule.Network == "tcp,udp" ||
|
||||
lastRule.Ip?.Contains("0.0.0.0/0") == true);
|
||||
if (rules?.LastOrDefault() is { } lastRule && lastRule.OutboundTag == Global.DirectTag)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
_coreConfig.dns.final = useDirectDns ? Global.SingboxDirectDNSTag : Global.SingboxRemoteDNSTag;
|
||||
var simpleDnsItem = context.SimpleDnsItem;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ public partial class CoreConfigSingboxService
|
|||
{
|
||||
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
|
||||
}
|
||||
var proxyTags = proxyOutboundList.Where(n => n.tag.StartsWith(Global.ProxyTag)).Select(n => n.tag).ToList();
|
||||
if (proxyTags.Count > 1)
|
||||
if (withSelector)
|
||||
{
|
||||
proxyOutboundList.InsertRange(0, BuildSelectorOutbounds(proxyTags, baseTagName));
|
||||
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;
|
||||
}
|
||||
|
|
@ -43,6 +46,7 @@ public partial class CoreConfigSingboxService
|
|||
case EConfigType.PolicyGroup:
|
||||
proxyOutboundList = BuildOutboundsList(baseTagName);
|
||||
break;
|
||||
|
||||
case EConfigType.ProxyChain:
|
||||
proxyOutboundList = BuildChainOutboundsList(baseTagName);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
|||
|
||||
GenStatistic();
|
||||
|
||||
var finalRule = BuildFinalRule();
|
||||
if (!string.IsNullOrEmpty(finalRule?.balancerTag))
|
||||
{
|
||||
_coreConfig.routing.rules.Add(finalRule);
|
||||
}
|
||||
|
||||
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
||||
ret.Success = true;
|
||||
ret.Data = ApplyFullConfigTemplate();
|
||||
|
|
@ -94,18 +100,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
|||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||
return ret;
|
||||
}
|
||||
List<IPEndPoint> lstIpEndPoints = new();
|
||||
List<TcpConnectionInformation> lstTcpConns = new();
|
||||
try
|
||||
{
|
||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
|
||||
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
}
|
||||
|
||||
var (lstIpEndPoints, lstTcpConns) = Utils.GetActiveNetworkInfo();
|
||||
|
||||
GenLog();
|
||||
_coreConfig.inbounds.Clear();
|
||||
|
|
@ -244,6 +240,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()
|
||||
|
|
@ -254,6 +251,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);
|
||||
|
|
|
|||
|
|
@ -70,18 +70,36 @@ 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 directDnsTags = dnsItem.servers
|
||||
.Select(server =>
|
||||
{
|
||||
var tagNode = (server as JsonObject)?["tag"];
|
||||
return tagNode is JsonValue value && value.TryGetValue<string>(out var tag) ? tag : null;
|
||||
})
|
||||
.Where(tag => tag is not null && tag.StartsWith(Global.DirectDnsTag, StringComparison.Ordinal))
|
||||
.Select(tag => tag!)
|
||||
.ToList();
|
||||
if (directDnsTags.Count > 0)
|
||||
{
|
||||
// DNS routing
|
||||
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 = directDnsTags,
|
||||
outboundTag = Global.DirectTag,
|
||||
});
|
||||
}
|
||||
|
||||
var finalRule = BuildFinalRule();
|
||||
dnsItem.tag = Global.DnsTag;
|
||||
_coreConfig.routing.rules.Add(new()
|
||||
{
|
||||
type = "field",
|
||||
inboundTag = [Global.DnsTag],
|
||||
outboundTag = finalRule.outboundTag,
|
||||
balancerTag = finalRule.balancerTag,
|
||||
});
|
||||
|
||||
_coreConfig.dns = dnsItem;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -93,45 +111,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,35 +231,102 @@ 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
var directDnsTagIndex = 1;
|
||||
|
||||
AddDnsServers(remoteDNSAddress, proxyDomainList);
|
||||
AddDnsServers(directDNSAddress, directDomainList);
|
||||
AddDnsServers(directDNSAddress, directDomainList, true);
|
||||
AddDnsServers(remoteDNSAddress, proxyGeositeList);
|
||||
AddDnsServers(directDNSAddress, directGeositeList);
|
||||
AddDnsServers(directDNSAddress, expectedDomainList, expectedIPs);
|
||||
AddDnsServers(directDNSAddress, directGeositeList, true);
|
||||
AddDnsServers(directDNSAddress, expectedDomainList, true, expectedIPs);
|
||||
if (dnsServerDomains.Count > 0)
|
||||
{
|
||||
AddDnsServers(bootstrapDNSAddress, dnsServerDomains);
|
||||
}
|
||||
|
||||
var useDirectDns = rules?.LastOrDefault() is { } lastRule
|
||||
&& lastRule.OutboundTag == Global.DirectTag
|
||||
&& (lastRule.Port == "0-65535"
|
||||
|| lastRule.Network == "tcp,udp"
|
||||
|| lastRule.Ip?.Contains("0.0.0.0/0") == true);
|
||||
var useDirectDns = false;
|
||||
|
||||
var defaultDnsServers = useDirectDns ? directDNSAddress : remoteDNSAddress;
|
||||
dnsItem.servers.AddRange(defaultDnsServers);
|
||||
if (rules?.LastOrDefault() is { } lastRule && lastRule.OutboundTag == Global.DirectTag)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!useDirectDns)
|
||||
{
|
||||
dnsItem.servers.AddRange(remoteDNSAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dns in directDNSAddress)
|
||||
{
|
||||
var dnsServer = CreateDnsServer(dns, []);
|
||||
dnsServer.tag = $"{Global.DirectDnsTag}-{directDnsTagIndex++}";
|
||||
dnsServer.skipFallback = false;
|
||||
dnsItem.servers.Add(JsonUtils.SerializeToNode(dnsServer,
|
||||
new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }));
|
||||
}
|
||||
}
|
||||
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 DnsServer4Ray 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 dnsServer;
|
||||
}
|
||||
|
||||
void AddDnsServers(List<string> dnsAddresses, List<string> domains, bool isDirectDns = false, List<string>? expectedIPs = null)
|
||||
{
|
||||
if (domains.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var dnsAddress in dnsAddresses)
|
||||
{
|
||||
var dnsServer = CreateDnsServer(dnsAddress, domains, expectedIPs);
|
||||
if (isDirectDns)
|
||||
{
|
||||
dnsServer.tag = $"{Global.DirectDnsTag}-{directDnsTagIndex++}";
|
||||
}
|
||||
var dnsServerNode = JsonUtils.SerializeToNode(dnsServer,
|
||||
new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull });
|
||||
dnsItem.servers.Add(dnsServerNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillDnsHosts(Dns4Ray dnsItem)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public partial class CoreConfigV2rayService
|
|||
case EConfigType.PolicyGroup:
|
||||
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
|
||||
break;
|
||||
|
||||
case EConfigType.ProxyChain:
|
||||
proxyOutboundList.AddRange(BuildChainOutboundsList(baseTagName));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -181,4 +181,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue