diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index e7e49e2c..9c4b3432 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -1,7 +1,7 @@
- 7.18.0
+ 7.19.0
diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props
index 51bdd56f..57dedb74 100644
--- a/v2rayN/Directory.Packages.props
+++ b/v2rayN/Directory.Packages.props
@@ -5,10 +5,10 @@
false
-
-
-
-
+
+
+
+
@@ -19,9 +19,9 @@
-
+
-
+
@@ -29,4 +29,4 @@
-
\ No newline at end of file
+
diff --git a/v2rayN/ServiceLib/Common/Utils.cs b/v2rayN/ServiceLib/Common/Utils.cs
index 70365e99..75ef4627 100644
--- a/v2rayN/ServiceLib/Common/Utils.cs
+++ b/v2rayN/ServiceLib/Common/Utils.cs
@@ -629,12 +629,7 @@ public class Utils
{
try
{
- List lstIpEndPoints = new();
- List 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 endpoints, List connections) GetActiveNetworkInfo()
+ {
+ var endpoints = new List();
+ var connections = new List();
+
+ 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
diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index e3e42484..b0bde1df 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -1235,31 +1235,63 @@ public static class ConfigHandler
/// A SOCKS profile item or null if not needed
public static ProfileItem? GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType)
{
+ if (node.ConfigType != EConfigType.Custom || !(node.PreSocksPort > 0))
+ {
+ return null;
+ }
ProfileItem? itemSocks = null;
- if (node.ConfigType != EConfigType.Custom && coreType != ECoreType.sing_box && config.TunModeItem.EnableTun)
+ var preCoreType = AppManager.Instance.RunningCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray;
+ itemSocks = new ProfileItem()
{
- itemSocks = new ProfileItem()
- {
- CoreType = ECoreType.sing_box,
- ConfigType = EConfigType.SOCKS,
- Address = Global.Loopback,
- Port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks)
- };
- }
- else if (node.ConfigType == EConfigType.Custom && node.PreSocksPort > 0)
- {
- var preCoreType = AppManager.Instance.RunningCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray;
- itemSocks = new ProfileItem()
- {
- CoreType = preCoreType,
- ConfigType = EConfigType.SOCKS,
- Address = Global.Loopback,
- Port = node.PreSocksPort.Value,
- };
- }
+ CoreType = preCoreType,
+ ConfigType = EConfigType.SOCKS,
+ Address = Global.Loopback,
+ Port = node.PreSocksPort.Value,
+ };
return itemSocks;
}
+ public static CoreConfigContext? GetPreSocksCoreConfigContext(CoreConfigContext nodeContext)
+ {
+ var config = nodeContext.AppConfig;
+ var node = nodeContext.Node;
+ var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
+
+ var preSocksItem = GetPreSocksItem(config, node, coreType);
+ if (preSocksItem != null)
+ {
+ return nodeContext with { Node = preSocksItem, };
+ }
+
+ if ((!nodeContext.IsTunEnabled)
+ || coreType != ECoreType.Xray
+ || node.ConfigType == EConfigType.Custom)
+ {
+ return null;
+ }
+ var tunProtectSsPort = Utils.GetFreePort();
+ var proxyRelaySsPort = Utils.GetFreePort();
+ var preItem = new ProfileItem()
+ {
+ CoreType = ECoreType.sing_box,
+ ConfigType = EConfigType.Shadowsocks,
+ Address = Global.Loopback,
+ Port = proxyRelaySsPort,
+ Password = Global.None,
+ };
+ preItem.SetProtocolExtra(preItem.GetProtocolExtra() with
+ {
+ SsMethod = Global.None,
+ });
+ var preContext = nodeContext with
+ {
+ Node = preItem,
+ TunProtectSsPort = tunProtectSsPort,
+ ProxyRelaySsPort = proxyRelaySsPort,
+ };
+ return preContext;
+ }
+
///
/// Remove servers with invalid test results (timeout)
/// Useful for cleaning up subscription lists
diff --git a/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs b/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
index b1e917b6..a38faafa 100644
--- a/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
@@ -159,7 +159,8 @@ public static class CoreConfigHandler
IsTunEnabled = config.TunModeItem.EnableTun,
SimpleDnsItem = config.SimpleDNSItem,
ProtectDomainList = [],
- ProtectSocksPort = 0,
+ TunProtectSsPort = 0,
+ ProxyRelaySsPort = 0,
RawDnsItem = await AppManager.Instance.GetDNSItem(coreType),
RoutingItem = await ConfigHandler.GetDefaultRouting(config),
};
diff --git a/v2rayN/ServiceLib/Manager/CoreManager.cs b/v2rayN/ServiceLib/Manager/CoreManager.cs
index 86934c45..159af85e 100644
--- a/v2rayN/ServiceLib/Manager/CoreManager.cs
+++ b/v2rayN/ServiceLib/Manager/CoreManager.cs
@@ -67,7 +67,15 @@ public class CoreManager
var fileName = Utils.GetBinConfigPath(Global.CoreConfigFileName);
var context = await CoreConfigHandler.BuildCoreConfigContext(_config, node);
- context = context with { IsTunEnabled = _config.TunModeItem.EnableTun };
+ var preContext = ConfigHandler.GetPreSocksCoreConfigContext(context);
+ if (preContext is not null)
+ {
+ context = context with
+ {
+ TunProtectSsPort = preContext.TunProtectSsPort,
+ ProxyRelaySsPort = preContext.ProxyRelaySsPort,
+ };
+ }
var result = await CoreConfigHandler.GenerateClientConfig(context, fileName);
if (result.Success != true)
{
@@ -88,7 +96,7 @@ public class CoreManager
}
await CoreStart(context);
- await CoreStartPreService(context);
+ await CoreStartPreService(preContext);
if (_processService != null)
{
await UpdateFunc(true, $"{node.GetSummary()}");
@@ -183,30 +191,22 @@ public class CoreManager
_processService = proc;
}
- private async Task CoreStartPreService(CoreConfigContext context)
+ private async Task CoreStartPreService(CoreConfigContext? preContext)
{
- var node = context.Node;
- if (_processService != null && !_processService.HasExited)
+ if (_processService is { HasExited: false } && preContext != null)
{
- var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
- var itemSocks = ConfigHandler.GetPreSocksItem(_config, node, coreType);
- if (itemSocks != null)
+ var preCoreType = preContext?.Node?.CoreType ?? ECoreType.sing_box;
+ var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
+ var result = await CoreConfigHandler.GenerateClientConfig(preContext, fileName);
+ if (result.Success)
{
- var preCoreType = itemSocks.CoreType ?? ECoreType.sing_box;
- var fileName = Utils.GetBinConfigPath(Global.CorePreConfigFileName);
- var itemSocksContext = await CoreConfigHandler.BuildCoreConfigContext(_config, itemSocks);
- itemSocksContext.ProtectDomainList.AddRangeSafe(context.ProtectDomainList);
- var result = await CoreConfigHandler.GenerateClientConfig(itemSocksContext, fileName);
- if (result.Success)
+ var coreInfo = CoreInfoManager.Instance.GetCoreInfo(preCoreType);
+ var proc = await RunProcess(coreInfo, Global.CorePreConfigFileName, true, true);
+ if (proc is null)
{
- var coreInfo = CoreInfoManager.Instance.GetCoreInfo(preCoreType);
- var proc = await RunProcess(coreInfo, Global.CorePreConfigFileName, true, true);
- if (proc is null)
- {
- return;
- }
- _processPreService = proc;
+ return;
}
+ _processPreService = proc;
}
}
}
diff --git a/v2rayN/ServiceLib/Models/ConfigItems.cs b/v2rayN/ServiceLib/Models/ConfigItems.cs
index 46caee85..7dc8c266 100644
--- a/v2rayN/ServiceLib/Models/ConfigItems.cs
+++ b/v2rayN/ServiceLib/Models/ConfigItems.cs
@@ -144,7 +144,6 @@ public class TunModeItem
public bool StrictRoute { get; set; } = true;
public string Stack { get; set; }
public int Mtu { get; set; }
- public bool EnableExInbound { get; set; }
public bool EnableIPv6Address { get; set; }
}
diff --git a/v2rayN/ServiceLib/Models/CoreConfigContext.cs b/v2rayN/ServiceLib/Models/CoreConfigContext.cs
index 8c998e41..a0a43a20 100644
--- a/v2rayN/ServiceLib/Models/CoreConfigContext.cs
+++ b/v2rayN/ServiceLib/Models/CoreConfigContext.cs
@@ -16,5 +16,9 @@ public record CoreConfigContext
// TUN Compatibility
public bool IsTunEnabled { get; init; } = false;
public HashSet ProtectDomainList { get; init; } = new();
- public int ProtectSocksPort { get; init; } = 0;
+ // -> tun inbound --(if routing proxy)--> relay outbound
+ // -> proxy core (relay inbound --> proxy outbound --(dialerProxy)--> protect outbound)
+ // -> protect inbound -> direct proxy outbound data -> internet
+ public int TunProtectSsPort { get; init; } = 0;
+ public int ProxyRelaySsPort { get; init; } = 0;
}
diff --git a/v2rayN/ServiceLib/Models/SingboxConfig.cs b/v2rayN/ServiceLib/Models/SingboxConfig.cs
index c1eaa3c8..02deaabf 100644
--- a/v2rayN/ServiceLib/Models/SingboxConfig.cs
+++ b/v2rayN/ServiceLib/Models/SingboxConfig.cs
@@ -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; }
diff --git a/v2rayN/ServiceLib/Models/V2rayConfig.cs b/v2rayN/ServiceLib/Models/V2rayConfig.cs
index 53d34563..80baf43b 100644
--- a/v2rayN/ServiceLib/Models/V2rayConfig.cs
+++ b/v2rayN/ServiceLib/Models/V2rayConfig.cs
@@ -472,7 +472,7 @@ public class HysteriaSettings4Ray
public class HysteriaUdpHop4Ray
{
- public string? ports { get; set; }
+ public string? port { get; set; }
public string? interval { get; set; }
}
diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index 20637ed5..8f798007 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -3780,15 +3780,6 @@ namespace ServiceLib.Resx {
}
}
- ///
- /// 查找类似 Enable additional Inbound 的本地化字符串。
- ///
- public static string TbSettingsEnableExInbound {
- get {
- return ResourceManager.GetString("TbSettingsEnableExInbound", resourceCulture);
- }
- }
-
///
/// 查找类似 Enable fragment 的本地化字符串。
///
@@ -3798,15 +3789,6 @@ namespace ServiceLib.Resx {
}
}
- ///
- /// 查找类似 which conflicts with the group previous proxy 的本地化字符串。
- ///
- public static string TbSettingsEnableFragmentTips {
- get {
- return ResourceManager.GetString("TbSettingsEnableFragmentTips", resourceCulture);
- }
- }
-
///
/// 查找类似 Enable hardware acceleration (requires restart) 的本地化字符串。
///
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index c93a9292..9aba2fed 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
@@ -1071,9 +1071,6 @@
MTU
-
- فعال سازی additional Inbound
-
فعال سازی آدرس IPv6
@@ -1113,9 +1110,6 @@
افزودن سرور [HTTP]
-
- which conflicts with the group previous proxy
-
فعال کردن فرگمنت
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
index 144446f8..3dfbcc09 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
@@ -1068,9 +1068,6 @@
MTU
-
- Activer un port d’écoute supplémentaire
-
Activer IPv6
@@ -1110,9 +1107,6 @@
Ajouter [HTTP]
-
- En conflit avec le proxy amont de groupe
-
Activer le fragmentation (Fragment)
diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
index 9749f552..e69a0a54 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
@@ -1071,9 +1071,6 @@
MTU
-
- További bejövő engedélyezése
-
IPv6 cím engedélyezése
@@ -1113,9 +1110,6 @@
HTTP konfiguráció hozzáadása
-
- which conflicts with the group previous proxy
-
Fragment engedélyezése
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index 1ff10bec..cc304154 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1071,9 +1071,6 @@
MTU
-
- Enable additional Inbound
-
Enable IPv6 Address
@@ -1113,9 +1110,6 @@
Add [HTTP]
-
- which conflicts with the group previous proxy
-
Enable fragment
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index f65a967d..6f093f72 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1071,9 +1071,6 @@
MTU
-
- Включить дополнительный входящий канал
-
Включить IPv6 адреса
@@ -1113,9 +1110,6 @@
Добавить сервер [HTTP]
-
- что конфликтует с предыдущим прокси группы
-
Включить фрагментацию (Fragment)
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index e185636c..c0f8665d 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1068,9 +1068,6 @@
MTU
-
- 启用额外监听端口
-
启用 IPv6
@@ -1110,9 +1107,6 @@
添加 [HTTP]
-
- 和分组前置代理冲突
-
启用分片 (Fragment)
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
index 8b2c4cff..9002c3af 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1068,9 +1068,6 @@
MTU
-
- 啟用額外偵聽連接埠
-
啟用 IPv6
@@ -1110,9 +1107,6 @@
新增 [HTTP] 節點
-
- 和分組前置代理衝突
-
啟用分片(Fragment)
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs
index 1fb409be..87b59e11 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs
@@ -61,6 +61,51 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
ret.Success = true;
ret.Data = ApplyFullConfigTemplate();
+ if (context.TunProtectSsPort is > 0 and <= 65535)
+ {
+ var ssInbound = new
+ {
+ type = "shadowsocks",
+ tag = "tun-protect-ss",
+ listen = Global.Loopback,
+ listen_port = context.TunProtectSsPort,
+ method = "none",
+ password = "none",
+ };
+ var directRule = new Rule4Sbox()
+ {
+ inbound = new List { ssInbound.tag },
+ outbound = Global.DirectTag,
+ };
+ var singboxConfigNode = JsonUtils.ParseJson(ret.Data.ToString())!.AsObject();
+ var inboundsNode = singboxConfigNode["inbounds"]!.AsArray();
+ inboundsNode.Add(JsonUtils.SerializeToNode(ssInbound, new JsonSerializerOptions
+ {
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
+ }));
+ var routeNode = singboxConfigNode["route"]?.AsObject();
+ var rulesNode = routeNode?["rules"]?.AsArray();
+ var protectRuleNode = JsonUtils.SerializeToNode(directRule,
+ new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull });
+ if (rulesNode != null)
+ {
+ rulesNode.Insert(0, protectRuleNode);
+ }
+ else
+ {
+ var newRulesNode = new JsonArray() { protectRuleNode };
+ if (routeNode is null)
+ {
+ var newRouteNode = new JsonObject() { ["rules"] = newRulesNode };
+ singboxConfigNode["route"] = newRouteNode;
+ }
+ else
+ {
+ routeNode["rules"] = newRulesNode;
+ }
+ }
+ ret.Data = JsonUtils.Serialize(singboxConfigNode);
+ }
return ret;
}
catch (Exception ex)
@@ -92,18 +137,8 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
- List lstIpEndPoints = new();
- List 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();
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs
index ab9a9d9f..3a27c7da 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs
@@ -7,10 +7,11 @@ public partial class CoreConfigSingboxService
try
{
var listen = "0.0.0.0";
+ var listenPort = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
_coreConfig.inbounds = [];
- if (!_config.TunModeItem.EnableTun
- || (_config.TunModeItem.EnableTun && _config.TunModeItem.EnableExInbound && AppManager.Instance.RunningCoreType == ECoreType.sing_box))
+ if (!context.IsTunEnabled
+ || (context.IsTunEnabled && _node.Port != listenPort))
{
var inbound = new Inbound4Sbox()
{
@@ -20,7 +21,7 @@ public partial class CoreConfigSingboxService
};
_coreConfig.inbounds.Add(inbound);
- inbound.listen_port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
+ inbound.listen_port = listenPort;
if (_config.Inbound.First().SecondLocalPortEnabled)
{
@@ -49,7 +50,7 @@ public partial class CoreConfigSingboxService
}
}
- if (_config.TunModeItem.EnableTun)
+ if (context.IsTunEnabled)
{
if (_config.TunModeItem.Mtu <= 0)
{
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs
index 23b331f6..40f8951d 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs
@@ -43,6 +43,7 @@ public partial class CoreConfigSingboxService
case EConfigType.PolicyGroup:
proxyOutboundList = BuildOutboundsList(baseTagName);
break;
+
case EConfigType.ProxyChain:
proxyOutboundList = BuildChainOutboundsList(baseTagName);
break;
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs
index 49dcdf19..f4c9c852 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs
@@ -15,6 +15,10 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
var ret = new RetResult();
try
{
+ if (context.IsTunEnabled && context.TunProtectSsPort > 0 && context.ProxyRelaySsPort > 0)
+ {
+ return GenerateClientProxyRelayConfig();
+ }
if (_node == null
|| !_node.IsValid())
{
@@ -90,18 +94,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
- List lstIpEndPoints = new();
- List 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();
@@ -263,5 +257,106 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
}
}
+ public RetResult GenerateClientProxyRelayConfig()
+ {
+ var ret = new RetResult();
+ try
+ {
+ if (_node == null
+ || !_node.IsValid())
+ {
+ ret.Msg = ResUI.CheckServerSettings;
+ return ret;
+ }
+
+ if (_node.GetNetwork() is nameof(ETransport.quic))
+ {
+ ret.Msg = ResUI.Incorrectconfiguration + $" - {_node.GetNetwork()}";
+ return ret;
+ }
+
+ var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
+ if (result.IsNullOrEmpty())
+ {
+ ret.Msg = ResUI.FailedGetDefaultConfiguration;
+ return ret;
+ }
+
+ _coreConfig = JsonUtils.Deserialize(result);
+ if (_coreConfig == null)
+ {
+ ret.Msg = ResUI.FailedGenDefaultConfiguration;
+ return ret;
+ }
+
+ GenLog();
+ _coreConfig.outbounds.Clear();
+ GenOutbounds();
+
+ var protectNode = new ProfileItem()
+ {
+ CoreType = ECoreType.Xray,
+ ConfigType = EConfigType.Shadowsocks,
+ Address = Global.Loopback,
+ Port = context.TunProtectSsPort,
+ Password = Global.None,
+ };
+ protectNode.SetProtocolExtra(protectNode.GetProtocolExtra() with
+ {
+ SsMethod = Global.None,
+ });
+
+ foreach (var outbound in _coreConfig.outbounds.Where(outbound => outbound.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true))
+ {
+ outbound.streamSettings ??= new StreamSettings4Ray();
+ outbound.streamSettings.sockopt ??= new Sockopt4Ray();
+ outbound.streamSettings.sockopt.dialerProxy = "tun-project-ss";
+ }
+ _coreConfig.outbounds.Add(new CoreConfigV2rayService(context with
+ {
+ Node = protectNode,
+ }).BuildProxyOutbound("tun-project-ss"));
+
+ var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 };
+ _coreConfig.routing.rules =
+ [
+ new()
+ {
+ inboundTag = new List { "proxy-relay-ss" },
+ outboundTag = hasBalancer ? null : Global.ProxyTag,
+ balancerTag = hasBalancer ? Global.ProxyTag + Global.BalancerTagSuffix: null,
+ type = "field"
+ }
+ ];
+ _coreConfig.inbounds.Clear();
+
+ var configNode = JsonUtils.ParseJson(JsonUtils.Serialize(_coreConfig))!;
+ configNode["inbounds"]!.AsArray().Add(new
+ {
+ listen = Global.Loopback,
+ port = context.ProxyRelaySsPort,
+ protocol = "shadowsocks",
+ settings = new
+ {
+ network = "tcp,udp",
+ method = Global.None,
+ password = Global.None,
+ },
+ tag = "proxy-relay-ss",
+ });
+
+ ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
+ ret.Success = true;
+ ret.Data = JsonUtils.Serialize(configNode);
+ return ret;
+ }
+ catch (Exception ex)
+ {
+ Logging.SaveLog(_tag, ex);
+ ret.Msg = ResUI.FailedGenDefaultConfiguration;
+ return ret;
+ }
+ }
+
#endregion public gen function
}
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs
index a6bb21ec..c8862648 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs
@@ -31,7 +31,7 @@ public partial class CoreConfigV2rayService
var fragmentOutbound = new Outbounds4Ray
{
protocol = "freedom",
- tag = $"frag-{Global.ProxyTag}",
+ tag = $"frag-{baseTagName}",
settings = new()
{
fragment = new()
@@ -44,16 +44,17 @@ public partial class CoreConfigV2rayService
};
var actOutboundWithTlsList =
proxyOutboundList.Where(n => n.streamSettings?.security.IsNullOrEmpty() == false
- && (n.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true));
+ && (n.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true)).ToList();
+ if (actOutboundWithTlsList.Count > 0)
+ {
+ proxyOutboundList.Add(fragmentOutbound);
+ }
foreach (var outbound in actOutboundWithTlsList)
{
- var fragmentOutboundClone = JsonUtils.DeepCopy(fragmentOutbound);
- fragmentOutboundClone.tag = $"frag-{outbound.tag}";
outbound.streamSettings.sockopt = new()
{
- dialerProxy = fragmentOutboundClone.tag
+ dialerProxy = fragmentOutbound.tag
};
- proxyOutboundList.Add(fragmentOutboundClone);
}
}
return proxyOutboundList;
@@ -67,6 +68,7 @@ public partial class CoreConfigV2rayService
case EConfigType.PolicyGroup:
proxyOutboundList.AddRange(BuildOutboundsList(baseTagName));
break;
+
case EConfigType.ProxyChain:
proxyOutboundList.AddRange(BuildChainOutboundsList(baseTagName));
break;
@@ -601,7 +603,7 @@ public partial class CoreConfigV2rayService
{
udpHop = new HysteriaUdpHop4Ray
{
- ports = ports.Replace(':', '-'),
+ port = ports.Replace(':', '-'),
interval = hopInterval,
};
}
diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
index 86251873..8462a2c3 100644
--- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs
@@ -95,7 +95,6 @@ public class OptionSettingViewModel : MyReactiveObject
[Reactive] public bool TunStrictRoute { get; set; }
[Reactive] public string TunStack { get; set; }
[Reactive] public int TunMtu { get; set; }
- [Reactive] public bool TunEnableExInbound { get; set; }
[Reactive] public bool TunEnableIPv6Address { get; set; }
#endregion Tun mode
@@ -220,7 +219,6 @@ public class OptionSettingViewModel : MyReactiveObject
TunStrictRoute = _config.TunModeItem.StrictRoute;
TunStack = _config.TunModeItem.Stack;
TunMtu = _config.TunModeItem.Mtu;
- TunEnableExInbound = _config.TunModeItem.EnableExInbound;
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
#endregion Tun mode
@@ -380,7 +378,6 @@ public class OptionSettingViewModel : MyReactiveObject
_config.TunModeItem.StrictRoute = TunStrictRoute;
_config.TunModeItem.Stack = TunStack;
_config.TunModeItem.Mtu = TunMtu;
- _config.TunModeItem.EnableExInbound = TunEnableExInbound;
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
//coreType
diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
index 65218738..cfcb48f0 100644
--- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
@@ -325,12 +325,6 @@
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
-
@@ -843,19 +837,6 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
-
-
-
this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
- this.Bind(ViewModel, vm => vm.TunEnableExInbound, v => v.togEnableExInbound.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
index 00b2dc9e..8f0d24d4 100644
--- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
+++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
@@ -391,13 +391,6 @@
Grid.Column="1"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
-
@@ -1097,20 +1090,6 @@
HorizontalAlignment="Left"
Style="{StaticResource DefComboBox}" />
-
-
-
vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
- this.Bind(ViewModel, vm => vm.TunEnableExInbound, v => v.togEnableExInbound.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);