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);