From 4f93a83f9f7eeb351e64595b9c87bf368944b612 Mon Sep 17 00:00:00 2001 From: DHR60 Date: Fri, 6 Mar 2026 15:58:33 +0800 Subject: [PATCH] Add ICMP routing --- v2rayN/ServiceLib/Global.cs | 9 ++++++ v2rayN/ServiceLib/Handler/ConfigHandler.cs | 1 + v2rayN/ServiceLib/Models/ConfigItems.cs | 1 + v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 9 ++++++ v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.fr.resx | 5 +++- v2rayN/ServiceLib/Resx/ResUI.hu.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.ru.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 3 ++ v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 3 ++ .../Singbox/SingboxRoutingService.cs | 30 +++++++++++++++++++ .../ViewModels/OptionSettingViewModel.cs | 3 ++ .../Views/OptionSettingWindow.axaml | 14 +++++++++ .../Views/OptionSettingWindow.axaml.cs | 2 ++ v2rayN/v2rayN/Views/OptionSettingWindow.xaml | 16 ++++++++++ .../v2rayN/Views/OptionSettingWindow.xaml.cs | 2 ++ 17 files changed, 109 insertions(+), 1 deletion(-) diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs index 5478cd2a..24ea549c 100644 --- a/v2rayN/ServiceLib/Global.cs +++ b/v2rayN/ServiceLib/Global.cs @@ -660,5 +660,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 de4c774d..9d23bf10 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 7dc8c266..3fd1454e 100644 --- a/v2rayN/ServiceLib/Models/ConfigItems.cs +++ b/v2rayN/ServiceLib/Models/ConfigItems.cs @@ -145,6 +145,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 b00bec2d..8ddc0485 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3033,6 +3033,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 16836861..0aed6871 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1671,4 +1671,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Group by Region + + 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 253831ef..a58440bf 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1668,4 +1668,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Group by Region - + + 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 a29d8987..54294481 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1671,4 +1671,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Group by Region + + ICMP routing policy + \ No newline at end of file diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 17416125..ab49e18b 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1671,4 +1671,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Group by Region + + 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 d8a174d5..a386413a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1671,4 +1671,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Group by Region + + ICMP routing policy + \ 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 3a4e4924..61c489b9 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1668,4 +1668,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 c4125679..bc716220 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1668,4 +1668,7 @@ 按區域分組 + + 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 8462a2c3..fa203a5c 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -96,6 +96,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 @@ -220,6 +221,7 @@ public class OptionSettingViewModel : MyReactiveObject TunStack = _config.TunModeItem.Stack; TunMtu = _config.TunModeItem.Mtu; TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address; + TunIcmpRouting = _config.TunModeItem.IcmpRouting; #endregion Tun mode @@ -379,6 +381,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 cfcb48f0..3c8fbf80 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -837,6 +837,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; @@ -115,6 +116,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 8f0d24d4..13bb85c9 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml @@ -1090,6 +1090,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);