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"
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o "$OutputPathArm64"
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v6.0.0
|
uses: actions/upload-artifact@v7.0.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-linux
|
name: v2rayN-linux
|
||||||
path: |
|
path: |
|
||||||
|
|
@ -169,7 +169,7 @@ jobs:
|
||||||
fetch-depth: '0'
|
fetch-depth: '0'
|
||||||
|
|
||||||
- name: Restore build artifacts
|
- name: Restore build artifacts
|
||||||
uses: actions/download-artifact@v7
|
uses: actions/download-artifact@v8
|
||||||
with:
|
with:
|
||||||
name: v2rayN-linux
|
name: v2rayN-linux
|
||||||
path: ${{ github.workspace }}/v2rayN/Release
|
path: ${{ github.workspace }}/v2rayN/Release
|
||||||
|
|
@ -190,7 +190,7 @@ jobs:
|
||||||
ls -R "$GITHUB_WORKSPACE/dist/rpm" || true
|
ls -R "$GITHUB_WORKSPACE/dist/rpm" || true
|
||||||
|
|
||||||
- name: Upload RPM artifacts
|
- name: Upload RPM artifacts
|
||||||
uses: actions/upload-artifact@v6.0.0
|
uses: actions/upload-artifact@v7.0.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-rpm
|
name: v2rayN-rpm
|
||||||
path: dist/rpm/**/*.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
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v6.0.0
|
uses: actions/upload-artifact@v7.0.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-macos
|
name: v2rayN-macos
|
||||||
path: |
|
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
|
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
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v6.0.0
|
uses: actions/upload-artifact@v7.0.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-windows-desktop
|
name: v2rayN-windows-desktop
|
||||||
path: |
|
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
|
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
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v6.0.0
|
uses: actions/upload-artifact@v7.0.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-windows
|
name: v2rayN-windows
|
||||||
path: |
|
path: |
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.18.0</Version>
|
<Version>7.19.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.12" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.12" />
|
||||||
<PackageVersion Include="ReactiveUI.Avalonia" Version="11.3.8" />
|
<PackageVersion Include="ReactiveUI.Avalonia" Version="11.3.8" />
|
||||||
<PackageVersion Include="CliWrap" Version="3.10.0" />
|
<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="H.NotifyIcon.Wpf" Version="2.4.1" />
|
||||||
<PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
|
<PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
|
||||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.3.1.1" />
|
<PackageVersion Include="MessageBox.Avalonia" Version="3.3.1.1" />
|
||||||
|
|
@ -29,4 +29,4 @@
|
||||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||||
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -629,12 +629,7 @@ public class Utils
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<IPEndPoint> lstIpEndPoints = new();
|
var (lstIpEndPoints, lstTcpConns) = GetActiveNetworkInfo();
|
||||||
List<TcpConnectionInformation> lstTcpConns = new();
|
|
||||||
|
|
||||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
|
||||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
|
|
||||||
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
|
|
||||||
|
|
||||||
if (lstIpEndPoints?.FindIndex(it => it.Port == port) >= 0)
|
if (lstIpEndPoints?.FindIndex(it => it.Port == port) >= 0)
|
||||||
{
|
{
|
||||||
|
|
@ -676,6 +671,27 @@ public class Utils
|
||||||
return 59090;
|
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
|
#endregion Speed Test
|
||||||
|
|
||||||
#region Miscellaneous
|
#region Miscellaneous
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ public class Global
|
||||||
public const string DirectTag = "direct";
|
public const string DirectTag = "direct";
|
||||||
public const string BlockTag = "block";
|
public const string BlockTag = "block";
|
||||||
public const string DnsTag = "dns-module";
|
public const string DnsTag = "dns-module";
|
||||||
|
public const string DirectDnsTag = "direct-dns";
|
||||||
public const string BalancerTagSuffix = "-round";
|
public const string BalancerTagSuffix = "-round";
|
||||||
public const string StreamSecurity = "tls";
|
public const string StreamSecurity = "tls";
|
||||||
public const string StreamSecurityReality = "reality";
|
public const string StreamSecurityReality = "reality";
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ public class DownloaderHelper
|
||||||
|
|
||||||
var downloadOpt = new DownloadConfiguration()
|
var downloadOpt = new DownloadConfiguration()
|
||||||
{
|
{
|
||||||
Timeout = timeout * 1000,
|
BlockTimeout = timeout * 1000,
|
||||||
MaxTryAgainOnFailure = 2,
|
MaxTryAgainOnFailure = 2,
|
||||||
RequestConfiguration =
|
RequestConfiguration =
|
||||||
{
|
{
|
||||||
Headers = headers,
|
Headers = headers,
|
||||||
UserAgent = userAgent,
|
UserAgent = userAgent,
|
||||||
Timeout = timeout * 1000,
|
ConnectTimeout = timeout * 1000,
|
||||||
Proxy = webProxy
|
Proxy = webProxy
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -62,11 +62,11 @@ public class DownloaderHelper
|
||||||
|
|
||||||
var downloadOpt = new DownloadConfiguration()
|
var downloadOpt = new DownloadConfiguration()
|
||||||
{
|
{
|
||||||
Timeout = timeout * 1000,
|
BlockTimeout = timeout * 1000,
|
||||||
MaxTryAgainOnFailure = 2,
|
MaxTryAgainOnFailure = 2,
|
||||||
RequestConfiguration =
|
RequestConfiguration =
|
||||||
{
|
{
|
||||||
Timeout= timeout * 1000,
|
ConnectTimeout= timeout * 1000,
|
||||||
Proxy = webProxy
|
Proxy = webProxy
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -139,11 +139,11 @@ public class DownloaderHelper
|
||||||
|
|
||||||
var downloadOpt = new DownloadConfiguration()
|
var downloadOpt = new DownloadConfiguration()
|
||||||
{
|
{
|
||||||
Timeout = timeout * 1000,
|
BlockTimeout = timeout * 1000,
|
||||||
MaxTryAgainOnFailure = 2,
|
MaxTryAgainOnFailure = 2,
|
||||||
RequestConfiguration =
|
RequestConfiguration =
|
||||||
{
|
{
|
||||||
Timeout= timeout * 1000,
|
ConnectTimeout= timeout * 1000,
|
||||||
Proxy = webProxy
|
Proxy = webProxy
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,8 @@ public class CoreManager
|
||||||
{
|
{
|
||||||
context = context with
|
context = context with
|
||||||
{
|
{
|
||||||
TunProtectSsPort = preContext.TunProtectSsPort, ProxyRelaySsPort = preContext.ProxyRelaySsPort,
|
TunProtectSsPort = preContext.TunProtectSsPort,
|
||||||
|
ProxyRelaySsPort = preContext.ProxyRelaySsPort,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var result = await CoreConfigHandler.GenerateClientConfig(context, fileName);
|
var result = await CoreConfigHandler.GenerateClientConfig(context, fileName);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public record CoreConfigContext
|
||||||
// TUN Compatibility
|
// TUN Compatibility
|
||||||
public bool IsTunEnabled { get; init; } = false;
|
public bool IsTunEnabled { get; init; } = false;
|
||||||
public HashSet<string> ProtectDomainList { get; init; } = new();
|
public HashSet<string> ProtectDomainList { get; init; } = new();
|
||||||
// -> tun inbound --(if routing proxy)--> relay outbound
|
// -> tun inbound --(if routing proxy)--> relay outbound
|
||||||
// -> proxy core (relay inbound --> proxy outbound --(dialerProxy)--> protect outbound)
|
// -> proxy core (relay inbound --> proxy outbound --(dialerProxy)--> protect outbound)
|
||||||
// -> protect inbound -> direct proxy outbound data -> internet
|
// -> protect inbound -> direct proxy outbound data -> internet
|
||||||
public int TunProtectSsPort { get; init; } = 0;
|
public int TunProtectSsPort { get; init; } = 0;
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,7 @@ public class Server4Sbox : BaseServer4Sbox
|
||||||
|
|
||||||
// Deprecated in sing-box 1.12.0 , kept for backward compatibility
|
// Deprecated in sing-box 1.12.0 , kept for backward compatibility
|
||||||
public string? address { get; set; }
|
public string? address { get; set; }
|
||||||
|
|
||||||
public string? address_resolver { get; set; }
|
public string? address_resolver { get; set; }
|
||||||
public string? address_strategy { get; set; }
|
public string? address_strategy { get; set; }
|
||||||
public string? strategy { get; set; }
|
public string? strategy { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -220,12 +220,6 @@ public class DnsServer4Ray
|
||||||
public List<string>? domains { get; set; }
|
public List<string>? domains { get; set; }
|
||||||
public bool? skipFallback { get; set; }
|
public bool? skipFallback { get; set; }
|
||||||
public List<string>? expectedIPs { 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; }
|
public string? tag { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,18 +137,8 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
List<IPEndPoint> lstIpEndPoints = new();
|
|
||||||
List<TcpConnectionInformation> lstTcpConns = new();
|
var (lstIpEndPoints, lstTcpConns) = Utils.GetActiveNetworkInfo();
|
||||||
try
|
|
||||||
{
|
|
||||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
|
||||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
|
|
||||||
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(_tag, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
GenLog();
|
GenLog();
|
||||||
GenMinimizedDns();
|
GenMinimizedDns();
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,15 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet) ?? [];
|
||||||
|
|
||||||
useDirectDns = rules?.LastOrDefault() is { } lastRule &&
|
if (rules?.LastOrDefault() is { } lastRule && lastRule.OutboundTag == Global.DirectTag)
|
||||||
lastRule.OutboundTag == Global.DirectTag &&
|
{
|
||||||
(lastRule.Port == "0-65535" ||
|
var noDomain = lastRule.Domain == null || lastRule.Domain.Count == 0;
|
||||||
lastRule.Network == "tcp,udp" ||
|
var noProcess = lastRule.Process == null || lastRule.Process.Count == 0;
|
||||||
lastRule.Ip?.Contains("0.0.0.0/0") == true);
|
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;
|
_coreConfig.dns.final = useDirectDns ? Global.SingboxDirectDNSTag : Global.SingboxRemoteDNSTag;
|
||||||
var simpleDnsItem = context.SimpleDnsItem;
|
var simpleDnsItem = context.SimpleDnsItem;
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,13 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
|
proxyOutboundList.AddRange(BuildGroupProxyOutbounds(baseTagName));
|
||||||
}
|
}
|
||||||
var proxyTags = proxyOutboundList.Where(n => n.tag.StartsWith(Global.ProxyTag)).Select(n => n.tag).ToList();
|
if (withSelector)
|
||||||
if (proxyTags.Count > 1)
|
|
||||||
{
|
{
|
||||||
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;
|
return proxyOutboundList;
|
||||||
}
|
}
|
||||||
|
|
@ -43,6 +46,7 @@ public partial class CoreConfigSingboxService
|
||||||
case EConfigType.PolicyGroup:
|
case EConfigType.PolicyGroup:
|
||||||
proxyOutboundList = BuildOutboundsList(baseTagName);
|
proxyOutboundList = BuildOutboundsList(baseTagName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.ProxyChain:
|
case EConfigType.ProxyChain:
|
||||||
proxyOutboundList = BuildChainOutboundsList(baseTagName);
|
proxyOutboundList = BuildChainOutboundsList(baseTagName);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,12 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
|
|
||||||
GenStatistic();
|
GenStatistic();
|
||||||
|
|
||||||
|
var finalRule = BuildFinalRule();
|
||||||
|
if (!string.IsNullOrEmpty(finalRule?.balancerTag))
|
||||||
|
{
|
||||||
|
_coreConfig.routing.rules.Add(finalRule);
|
||||||
|
}
|
||||||
|
|
||||||
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
ret.Data = ApplyFullConfigTemplate();
|
ret.Data = ApplyFullConfigTemplate();
|
||||||
|
|
@ -94,18 +100,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
List<IPEndPoint> lstIpEndPoints = new();
|
|
||||||
List<TcpConnectionInformation> lstTcpConns = new();
|
var (lstIpEndPoints, lstTcpConns) = Utils.GetActiveNetworkInfo();
|
||||||
try
|
|
||||||
{
|
|
||||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());
|
|
||||||
lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());
|
|
||||||
lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(_tag, ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
GenLog();
|
GenLog();
|
||||||
_coreConfig.inbounds.Clear();
|
_coreConfig.inbounds.Clear();
|
||||||
|
|
@ -244,6 +240,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
GenLog();
|
GenLog();
|
||||||
GenOutbounds();
|
GenOutbounds();
|
||||||
|
|
||||||
|
_coreConfig.routing.domainStrategy = Global.AsIs;
|
||||||
_coreConfig.routing.rules.Clear();
|
_coreConfig.routing.rules.Clear();
|
||||||
_coreConfig.inbounds.Clear();
|
_coreConfig.inbounds.Clear();
|
||||||
_coreConfig.inbounds.Add(new()
|
_coreConfig.inbounds.Add(new()
|
||||||
|
|
@ -254,6 +251,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
protocol = EInboundProtocol.mixed.ToString(),
|
protocol = EInboundProtocol.mixed.ToString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_coreConfig.routing.rules.Add(BuildFinalRule());
|
||||||
|
|
||||||
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
ret.Data = JsonUtils.Serialize(_coreConfig);
|
ret.Data = JsonUtils.Serialize(_coreConfig);
|
||||||
|
|
|
||||||
|
|
@ -70,18 +70,36 @@ public partial class CoreConfigV2rayService
|
||||||
dnsItem.serveStale = simpleDnsItem?.ServeStale is true ? true : null;
|
dnsItem.serveStale = simpleDnsItem?.ServeStale is true ? true : null;
|
||||||
dnsItem.enableParallelQuery = simpleDnsItem?.ParallelQuery 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
|
_coreConfig.routing.rules.Add(new()
|
||||||
dnsItem.tag = Global.DnsTag;
|
|
||||||
_coreConfig.routing.rules.Add(new RulesItem4Ray
|
|
||||||
{
|
{
|
||||||
type = "field",
|
type = "field",
|
||||||
inboundTag = new List<string> { Global.DnsTag },
|
inboundTag = directDnsTags,
|
||||||
outboundTag = Global.ProxyTag,
|
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;
|
_coreConfig.dns = dnsItem;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -93,45 +111,6 @@ public partial class CoreConfigV2rayService
|
||||||
private void FillDnsServers(Dns4Ray dnsItem)
|
private void FillDnsServers(Dns4Ray dnsItem)
|
||||||
{
|
{
|
||||||
var simpleDNSItem = context.SimpleDnsItem;
|
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 directDNSAddress = ParseDnsAddresses(simpleDNSItem?.DirectDNS, Global.DomainDirectDNSAddress.First());
|
||||||
var remoteDNSAddress = ParseDnsAddresses(simpleDNSItem?.RemoteDNS, Global.DomainRemoteDNSAddress.First());
|
var remoteDNSAddress = ParseDnsAddresses(simpleDNSItem?.RemoteDNS, Global.DomainRemoteDNSAddress.First());
|
||||||
|
|
@ -252,35 +231,102 @@ public partial class CoreConfigV2rayService
|
||||||
|
|
||||||
dnsItem.servers ??= [];
|
dnsItem.servers ??= [];
|
||||||
|
|
||||||
void AddDnsServers(List<string> dnsAddresses, List<string> domains, List<string>? expectedIPs = null)
|
var directDnsTagIndex = 1;
|
||||||
{
|
|
||||||
if (domains.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var dnsAddress in dnsAddresses)
|
|
||||||
{
|
|
||||||
dnsItem.servers.Add(CreateDnsServer(dnsAddress, domains, expectedIPs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddDnsServers(remoteDNSAddress, proxyDomainList);
|
AddDnsServers(remoteDNSAddress, proxyDomainList);
|
||||||
AddDnsServers(directDNSAddress, directDomainList);
|
AddDnsServers(directDNSAddress, directDomainList, true);
|
||||||
AddDnsServers(remoteDNSAddress, proxyGeositeList);
|
AddDnsServers(remoteDNSAddress, proxyGeositeList);
|
||||||
AddDnsServers(directDNSAddress, directGeositeList);
|
AddDnsServers(directDNSAddress, directGeositeList, true);
|
||||||
AddDnsServers(directDNSAddress, expectedDomainList, expectedIPs);
|
AddDnsServers(directDNSAddress, expectedDomainList, true, expectedIPs);
|
||||||
if (dnsServerDomains.Count > 0)
|
if (dnsServerDomains.Count > 0)
|
||||||
{
|
{
|
||||||
AddDnsServers(bootstrapDNSAddress, dnsServerDomains);
|
AddDnsServers(bootstrapDNSAddress, dnsServerDomains);
|
||||||
}
|
}
|
||||||
|
|
||||||
var useDirectDns = rules?.LastOrDefault() is { } lastRule
|
var useDirectDns = false;
|
||||||
&& lastRule.OutboundTag == Global.DirectTag
|
|
||||||
&& (lastRule.Port == "0-65535"
|
|
||||||
|| lastRule.Network == "tcp,udp"
|
|
||||||
|| lastRule.Ip?.Contains("0.0.0.0/0") == true);
|
|
||||||
|
|
||||||
var defaultDnsServers = useDirectDns ? directDNSAddress : remoteDNSAddress;
|
if (rules?.LastOrDefault() is { } lastRule && lastRule.OutboundTag == Global.DirectTag)
|
||||||
dnsItem.servers.AddRange(defaultDnsServers);
|
{
|
||||||
|
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)
|
private void FillDnsHosts(Dns4Ray dnsItem)
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ public partial class CoreConfigV2rayService
|
||||||
case EConfigType.PolicyGroup:
|
case EConfigType.PolicyGroup:
|
||||||
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
|
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.ProxyChain:
|
case EConfigType.ProxyChain:
|
||||||
proxyOutboundList.AddRange(BuildChainOutboundsList(baseTagName));
|
proxyOutboundList.AddRange(BuildChainOutboundsList(baseTagName));
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -181,4 +181,28 @@ public partial class CoreConfigV2rayService
|
||||||
|
|
||||||
return tag;
|
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