diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 103c993c..92c50a37 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -2,8 +2,6 @@ namespace ServiceLib; public class Global { - #region const - public const string AppName = "v2rayN"; public const string GithubUrl = "https://github.com"; public const string GithubApiUrl = "https://api.github.com/repos"; @@ -106,9 +104,7 @@ public class Global public const string SingboxFakeDNSTag = "fake_dns"; public const int Hysteria2DefaultHopInt = 30; - public const string PolicyGroupExcludeKeywords = @"剩余|过期|到期|重置|[Rr]emaining|[Ee]xpir|[Rr]eset"; - public const string PolicyGroupDefaultAllFilter = $"^(?!.*(?:{PolicyGroupExcludeKeywords})).*$"; public static readonly List PolicyGroupDefaultFilterList = @@ -749,5 +745,27 @@ public class Global MozillaRootProvider, ]; - #endregion const + public static readonly IReadOnlyList TunIpv4Address = + [ + "172.18.0.1/30", + "172.31.0.1/30", + "172.20.0.1/30", + "172.16.0.1/30", + "192.168.100.1/30", + "10.10.14.1/30", + "10.1.0.1/30", + "10.0.0.1/30", + ]; + + public static readonly IReadOnlyList TunIpv6Address = + [ + "fc00::172:18:0:1/128", + "fc00::172:31:0:1/128", + "fc00::172:20:0:1/128", + "fc00::172:16:0:1/128", + "fc00::192:168:100:1/128", + "fc00::10:10:14:1/128", + "fc00::10:1:0:1/128", + "fc00::10:0:0:1/128", + ]; } diff --git a/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs b/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs index c1e1619e..d1524898 100644 --- a/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs +++ b/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs @@ -149,6 +149,8 @@ public class TunModeItem public string IcmpRouting { get; set; } public bool EnableLegacyProtect { get; set; } public List? RouteExcludeAddress { get; set; } + public string Ipv4Address { get; set; } + public string Ipv6Address { get; set; } } [Serializable] @@ -255,6 +257,7 @@ public class Fragment4RayItem // For migration from old version, remove those properties in the future public string? Length { get; set; } + public string? Interval { get; set; } // migration end } diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 3cf47d8a..e3dbdae6 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3348,6 +3348,24 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Ipv4 Address 的本地化字符串。 + /// + public static string TbIpv4Address { + get { + return ResourceManager.GetString("TbIpv4Address", resourceCulture); + } + } + + /// + /// 查找类似 Ipv6 Address 的本地化字符串。 + /// + public static string TbIpv6Address { + get { + return ResourceManager.GetString("TbIpv6Address", resourceCulture); + } + } + /// /// 查找类似 Most Stable 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 24b92359..7085ff1c 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1842,4 +1842,10 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Requires the UseIP Strategy. When enabled, it attempts IPv4 and IPv6 connections simultaneously and automatically selects the faster available path. + + Ipv6 Address + + + Ipv4 Address + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index a767d784..41fc80b5 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1839,4 +1839,10 @@ 需配合 UseIP 策略使用。启用后将同时尝试 IPv4 和 IPv6 连接,并自动选择更快可用的路径。 + + Ipv6 地址 + + + Ipv4 地址 + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 3403eacd..e08ebe10 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1839,4 +1839,10 @@ 需搭配 UseIP 策略,啟用後會同時嘗試 IPv4 與 IPv6 連線,並自動選擇速度較快的路徑 + + Ipv6 位址 + + + Ipv4 位址 + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs index 1eeffa43..5eb30ba4 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs @@ -67,9 +67,13 @@ public partial class CoreConfigSingboxService tunInbound.auto_route = _config.TunModeItem.AutoRoute; tunInbound.strict_route = _config.TunModeItem.StrictRoute; tunInbound.stack = _config.TunModeItem.Stack; - if (_config.TunModeItem.EnableIPv6Address == false) + + var address = _config.TunModeItem.Ipv4Address.NullIfEmpty() ?? Global.TunIpv4Address.First(); + tunInbound.address = [address]; + if (_config.TunModeItem.EnableIPv6Address == true) { - tunInbound.address = ["172.18.0.1/30"]; + var address6 = _config.TunModeItem.Ipv6Address.NullIfEmpty() ?? Global.TunIpv6Address.First(); + tunInbound.address.Add(address6); } tunInbound.route_exclude_address = _config.TunModeItem.RouteExcludeAddress; diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayInboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayInboundService.cs index 4041f0fd..9f4d7180 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayInboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayInboundService.cs @@ -63,11 +63,16 @@ public partial class CoreConfigV2rayService new Inbounds4Ray(); tunInbound.settings.name = context.IsMacOS ? $"utun{new Random().Next(99)}" : "xray_tun"; tunInbound.settings.MTU = _config.TunModeItem.Mtu; - if (!_config.TunModeItem.EnableIPv6Address) + + var address = _config.TunModeItem.Ipv4Address.NullIfEmpty() ?? Global.TunIpv4Address.First(); + tunInbound.settings.gateway = [address]; + if (_config.TunModeItem.EnableIPv6Address == true) { - tunInbound.settings.gateway = ["172.18.0.1/30"]; - tunInbound.settings.autoSystemRoutingTable = ["0.0.0.0/0"]; + var address6 = _config.TunModeItem.Ipv6Address.NullIfEmpty() ?? Global.TunIpv6Address.First(); + tunInbound.settings.gateway.Add(address6); } + tunInbound.settings.dns = [address.Split('/').First()]; + tunInbound.settings.autoSystemRoutingTable = ["0.0.0.0/0"]; var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx(); if (!bindInterface.IsNullOrEmpty()) { diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index fe28d496..9c97e9d8 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -95,6 +95,8 @@ public class OptionSettingViewModel : MyReactiveObject, ICloseable [Reactive] public string TunIcmpRouting { get; set; } [Reactive] public bool TunEnableLegacyProtect { get; set; } [Reactive] public string TunRouteExcludeAddress { get; set; } + [Reactive] public string TunIpv4Address { get; set; } + [Reactive] public string TunIpv6Address { get; set; } #endregion Tun mode @@ -214,6 +216,8 @@ public class OptionSettingViewModel : MyReactiveObject, ICloseable TunIcmpRouting = _config.TunModeItem.IcmpRouting; TunEnableLegacyProtect = _config.TunModeItem.EnableLegacyProtect; TunRouteExcludeAddress = Utils.List2String(_config.TunModeItem.RouteExcludeAddress, true); + TunIpv4Address = _config.TunModeItem.Ipv4Address; + TunIpv6Address = _config.TunModeItem.Ipv6Address; #endregion Tun mode @@ -378,6 +382,8 @@ public class OptionSettingViewModel : MyReactiveObject, ICloseable _config.TunModeItem.IcmpRouting = TunIcmpRouting; _config.TunModeItem.EnableLegacyProtect = TunEnableLegacyProtect; _config.TunModeItem.RouteExcludeAddress = Utils.String2List(TunRouteExcludeAddress); + _config.TunModeItem.Ipv4Address = TunIpv4Address; + _config.TunModeItem.Ipv6Address = TunIpv6Address; //coreType await SaveCoreType(); diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index 0dbee8b0..6ed09193 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -961,7 +961,7 @@ Margin="{StaticResource Margin4}" ColumnDefinitions="Auto,Auto,Auto" DockPanel.Dock="Top" - RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"> + RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"> + + + + + + diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs index e33c6afe..e0b8b535 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml.cs @@ -33,6 +33,8 @@ public partial class OptionSettingWindow : WindowBase cmbMtu.ItemsSource = Global.TunMtus; cmbStack.ItemsSource = Global.TunStacks; cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies; + cmbIpv4Address.ItemsSource = Global.TunIpv4Address; + cmbIpv6Address.ItemsSource = Global.TunIpv6Address; cmbFragmentPackets.ItemsSource = Global.FragmentPacketsOptions; cmbCoreType1.ItemsSource = Global.CoreTypes; @@ -129,6 +131,8 @@ public partial class OptionSettingWindow : WindowBase this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunEnableLegacyProtect, v => v.togEnableLegacyProtect.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunRouteExcludeAddress, v => v.txtRouteExcludeAddress.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunIpv4Address, v => v.cmbIpv4Address.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunIpv6Address, v => v.cmbIpv6Address.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml index 5b8c9a0e..f9cafbc0 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -1198,6 +1198,8 @@ + + @@ -1346,6 +1348,39 @@ Style="{StaticResource ToolbarTextBlock}" Text="{x:Static resx:ResUI.TbRouteExcludeAddressTip}" TextWrapping="Wrap" /> + + + + + + + diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs index 91bebafc..fc7f85a8 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs @@ -29,6 +29,8 @@ public partial class OptionSettingWindow cmbMtu.ItemsSource = Global.TunMtus; cmbStack.ItemsSource = Global.TunStacks; cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies; + cmbIpv4Address.ItemsSource = Global.TunIpv4Address; + cmbIpv6Address.ItemsSource = Global.TunIpv6Address; cmbFragmentPackets.ItemsSource = Global.FragmentPacketsOptions; cmbCoreType1.ItemsSource = Global.CoreTypes; @@ -86,14 +88,6 @@ public partial class OptionSettingWindow this.Bind(ViewModel, vm => vm.FragmentDelays, v => v.txtFragmentDelays.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.FragmentMaxSplit, v => v.txtFragmentMaxSplit.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.Kcpmtu, v => v.txtKcpmtu.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.Kcptti, v => v.txtKcptti.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.KcpuplinkCapacity, v => v.txtKcpuplinkCapacity.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.KcpdownlinkCapacity, v => v.txtKcpdownlinkCapacity.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.KcpreadBufferSize, v => v.txtKcpreadBufferSize.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.KcpwriteBufferSize, v => v.txtKcpwriteBufferSize.Text).DisposeWith(disposables); - //this.Bind(ViewModel, vm => vm.Kcpcongestion, v => v.togKcpcongestion.IsChecked).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DisplayRealTimeSpeed, v => v.togDisplayRealTimeSpeed.IsChecked).DisposeWith(disposables); @@ -132,6 +126,8 @@ public partial class OptionSettingWindow this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunEnableLegacyProtect, v => v.togEnableLegacyProtect.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.TunRouteExcludeAddress, v => v.txtRouteExcludeAddress.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunIpv4Address, v => v.cmbIpv4Address.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunIpv6Address, v => v.cmbIpv6Address.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);