diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index 26619666..b9a369ec 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -1233,28 +1233,19 @@ 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;
}
diff --git a/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs b/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
index cebf2d3f..359aab3b 100644
--- a/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs
@@ -154,7 +154,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..0e4c33d6 100644
--- a/v2rayN/ServiceLib/Manager/CoreManager.cs
+++ b/v2rayN/ServiceLib/Manager/CoreManager.cs
@@ -67,7 +67,38 @@ public class CoreManager
var fileName = Utils.GetBinConfigPath(Global.CoreConfigFileName);
var context = await CoreConfigHandler.BuildCoreConfigContext(_config, node);
- context = context with { IsTunEnabled = _config.TunModeItem.EnableTun };
+ CoreConfigContext? preContext = null;
+ if (context.IsTunEnabled)
+ {
+ var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
+ if (coreType == ECoreType.Xray && node.ConfigType != EConfigType.Custom)
+ {
+ var tunProtectSsPort = Utils.GetFreePort();
+ var proxyRelaySsPort = Utils.GetFreePort();
+ context = context with { TunProtectSsPort = tunProtectSsPort, ProxyRelaySsPort = proxyRelaySsPort, };
+ 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,
+ });
+ preContext = context with { Node = preItem, };
+ }
+ else
+ {
+ var preItem = ConfigHandler.GetPreSocksItem(_config, node, coreType);
+ if (preItem is not null)
+ {
+ preContext = context with { Node = preItem, };
+ }
+ }
+ }
var result = await CoreConfigHandler.GenerateClientConfig(context, fileName);
if (result.Success != true)
{
@@ -88,7 +119,7 @@ public class CoreManager
}
await CoreStart(context);
- await CoreStartPreService(context);
+ await CoreStartPreService(preContext);
if (_processService != null)
{
await UpdateFunc(true, $"{node.GetSummary()}");
@@ -183,30 +214,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 9551d39d..59e9537e 100644
--- a/v2rayN/ServiceLib/Models/CoreConfigContext.cs
+++ b/v2rayN/ServiceLib/Models/CoreConfigContext.cs
@@ -13,5 +13,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/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index 6f223693..0f3a45a7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -3771,15 +3771,6 @@ namespace ServiceLib.Resx {
}
}
- ///
- /// 查找类似 Enable additional Inbound 的本地化字符串。
- ///
- public static string TbSettingsEnableExInbound {
- get {
- return ResourceManager.GetString("TbSettingsEnableExInbound", resourceCulture);
- }
- }
-
///
/// 查找类似 Enable fragment 的本地化字符串。
///
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx
index dbce6ac4..8a05f2b3 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
diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx
index 005a51d5..2b92417f 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
diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx
index 3d169590..94711705 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
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index 041a103b..756a9c93 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1071,9 +1071,6 @@
MTU
-
- Enable additional Inbound
-
Enable IPv6 Address
diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
index 66ebef79..51a31851 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx
@@ -1071,9 +1071,6 @@
MTU
-
- Включить дополнительный входящий канал
-
Включить IPv6 адреса
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index c8936668..281c81e2 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1068,9 +1068,6 @@
MTU
-
- 启用额外监听端口
-
启用 IPv6
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
index 2ee4dc4f..ce4198ce 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx
@@ -1068,9 +1068,6 @@
MTU
-
- 啟用額外偵聽連接埠
-
啟用 IPv6
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/CoreConfigSingboxService.cs
index c0ce7154..1c08fcc5 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)
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/V2ray/CoreConfigV2rayService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/CoreConfigV2rayService.cs
index 3ad71592..8187f854 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())
{
@@ -262,5 +266,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.sing_box,
+ 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 : 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/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..6160cfad 100644
--- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml
@@ -843,19 +843,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..ed82860d 100644
--- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
+++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml
@@ -1097,20 +1097,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);