diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 0a52f678..e9a5a41e 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -675,5 +675,14 @@ public class Global "" ]; + public static readonly List TunIcmpRoutingPolicies = + [ + "rule", + "direct", + "unreachable", + "drop", + "reply", + ]; + #endregion const } diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 524d9d6a..8f079451 100644 --- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -91,6 +91,7 @@ public static class ConfigHandler { EnableTun = false, Mtu = 9000, + IcmpRouting = Global.TunIcmpRoutingPolicies.First(), }; config.GuiItem ??= new(); config.MsgUIItem ??= new(); diff --git a/v2rayN/ServiceLib/Models/ConfigItems.cs b/v2rayN/ServiceLib/Models/ConfigItems.cs index 741c21e5..8583906b 100644 --- a/v2rayN/ServiceLib/Models/ConfigItems.cs +++ b/v2rayN/ServiceLib/Models/ConfigItems.cs @@ -144,6 +144,7 @@ public class TunModeItem public string Stack { get; set; } public int Mtu { get; set; } public bool EnableIPv6Address { get; set; } + public string IcmpRouting { get; set; } } [Serializable] diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 33fd37c5..bd26cd9e 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3078,6 +3078,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 ICMP routing policy 的本地化字符串。 + /// + public static string TbIcmpRoutingPolicy { + get { + return ResourceManager.GetString("TbIcmpRoutingPolicy", resourceCulture); + } + } + /// /// 查找类似 UUID(id) 的本地化字符串。 /// diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index 580f3f03..f95646a6 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1692,4 +1692,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Username + + ICMP routing policy + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayN/ServiceLib/Resx/ResUI.fr.resx index 79887d15..fcdab47a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1689,4 +1689,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Username + + ICMP routing policy + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 2f8305c7..a22a476a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1692,4 +1692,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Username + + ICMP routing policy + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index b4658076..26d54e51 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1692,4 +1692,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Username + + ICMP routing policy + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 0f63f5c2..aa0594bd 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1692,4 +1692,7 @@ Username + + ICMP routing policy + diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 11dc2588..484e2a12 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1689,4 +1689,7 @@ 用户名 + + ICMP 路由策略 + \ 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 1f039299..8496f293 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1689,4 +1689,7 @@ Username + + ICMP routing policy + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs index 45620c41..7e1af389 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxRoutingService.cs @@ -47,6 +47,36 @@ public partial class CoreConfigSingboxService outbound = Global.DirectTag, process_name = lstDirectExe }); + + // ICMP Routing + var icmpRouting = _config.TunModeItem.IcmpRouting ?? ""; + if (!Global.TunIcmpRoutingPolicies.Contains(icmpRouting)) + { + icmpRouting = Global.TunIcmpRoutingPolicies.First(); + } + if (icmpRouting == "direct") + { + _coreConfig.route.rules.Add(new() + { + network = ["icmp"], + outbound = Global.DirectTag, + }); + } + else if (icmpRouting != "rule") + { + var rejectMethod = icmpRouting switch + { + "unreachable" => "default", + "drop" => "drop", + _ => "reply", + }; + _coreConfig.route.rules.Add(new() + { + network = ["icmp"], + action = "reject", + method = rejectMethod, + }); + } } if (_config.Inbound.First().SniffingEnabled) diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index d936c5df..5df75264 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -95,6 +95,7 @@ public class OptionSettingViewModel : MyReactiveObject [Reactive] public string TunStack { get; set; } [Reactive] public int TunMtu { get; set; } [Reactive] public bool TunEnableIPv6Address { get; set; } + [Reactive] public string TunIcmpRouting { get; set; } #endregion Tun mode @@ -218,6 +219,7 @@ public class OptionSettingViewModel : MyReactiveObject TunStack = _config.TunModeItem.Stack; TunMtu = _config.TunModeItem.Mtu; TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address; + TunIcmpRouting = _config.TunModeItem.IcmpRouting; #endregion Tun mode @@ -376,6 +378,7 @@ public class OptionSettingViewModel : MyReactiveObject _config.TunModeItem.Stack = TunStack; _config.TunModeItem.Mtu = TunMtu; _config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address; + _config.TunModeItem.IcmpRouting = TunIcmpRouting; //coreType await SaveCoreType(); diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index 8c4f1fcc..7d80088a 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -824,6 +824,20 @@ Margin="{StaticResource Margin4}" HorizontalAlignment="Left" /> + + + cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs; cmbMtu.ItemsSource = Global.TunMtus; cmbStack.ItemsSource = Global.TunStacks; + cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies; cmbCoreType1.ItemsSource = Global.CoreTypes; cmbCoreType2.ItemsSource = Global.CoreTypes; @@ -114,6 +115,7 @@ public partial class OptionSettingWindow : WindowBase 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.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.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 133b4134..41d3b8d1 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -1076,6 +1076,22 @@ HorizontalAlignment="Left" Style="{StaticResource DefComboBox}" /> + + + 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.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.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);