mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-07 21:15:01 +03:00
feat: add sing-box TUN dns_mode setting (#10336)
This commit is contained in:
@@ -46,6 +46,72 @@ public class CoreConfigSingboxServiceTests
|
||||
await cfg.inbounds.Should().Contain(i => i.type == "tun");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Arguments(null)]
|
||||
[Arguments("Default")]
|
||||
public async Task GenerateClientConfigContent_TunDnsModeDefault_ShouldNotIncludeDnsMode(string? dnsMode)
|
||||
{
|
||||
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
|
||||
config.TunModeItem.EnableTun = true;
|
||||
config.TunModeItem.DnsMode = dnsMode;
|
||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||
var node = CoreConfigTestFactory.CreateSocksNode(ECoreType.sing_box);
|
||||
var context = CoreConfigTestFactory.CreateContext(config, node, ECoreType.sing_box) with
|
||||
{
|
||||
IsTunEnabled = true,
|
||||
};
|
||||
|
||||
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
|
||||
|
||||
await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
|
||||
await result.Data!.ToString().Should().NotContain("\"dns_mode\"");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GenerateClientConfigContent_TunDnsModeDisabled_ShouldIncludeDnsMode()
|
||||
{
|
||||
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
|
||||
config.TunModeItem.EnableTun = true;
|
||||
config.TunModeItem.DnsMode = "disabled";
|
||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||
var node = CoreConfigTestFactory.CreateSocksNode(ECoreType.sing_box);
|
||||
var context = CoreConfigTestFactory.CreateContext(config, node, ECoreType.sing_box) with
|
||||
{
|
||||
IsTunEnabled = true,
|
||||
};
|
||||
|
||||
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
|
||||
|
||||
await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
|
||||
var cfg = JsonUtils.Deserialize<SingboxConfig>(result.Data!.ToString())!;
|
||||
var tun = cfg.inbounds.First(i => i.type == "tun");
|
||||
await tun.dns_mode.Should().BeEqualTo("disabled");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Arguments(true)]
|
||||
[Arguments(false)]
|
||||
public async Task GenerateClientConfigContent_TunDnsModeDisabled_ShouldNotIncludeGlobalDnsHijackRule(bool sniffingEnabled)
|
||||
{
|
||||
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
|
||||
config.TunModeItem.EnableTun = true;
|
||||
config.TunModeItem.DnsMode = "disabled";
|
||||
config.Inbound.First().SniffingEnabled = sniffingEnabled;
|
||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||
var node = CoreConfigTestFactory.CreateSocksNode(ECoreType.sing_box);
|
||||
var context = CoreConfigTestFactory.CreateContext(config, node, ECoreType.sing_box) with
|
||||
{
|
||||
IsTunEnabled = true,
|
||||
};
|
||||
|
||||
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
|
||||
|
||||
await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
|
||||
var cfg = JsonUtils.Deserialize<SingboxConfig>(result.Data!.ToString())!;
|
||||
await cfg.route.rules.Any(
|
||||
r => r.action == "hijack-dns" && r.process_path == null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GenerateClientConfigContent_TunEnabled_ShouldKeepEmbeddedTunRules()
|
||||
{
|
||||
|
||||
@@ -607,6 +607,16 @@ public class Global
|
||||
"mixed"
|
||||
];
|
||||
|
||||
public const string TunDnsModeDefault = "Default";
|
||||
|
||||
public static readonly List<string> TunDnsModes =
|
||||
[
|
||||
TunDnsModeDefault,
|
||||
"disabled",
|
||||
"native",
|
||||
"hijack"
|
||||
];
|
||||
|
||||
public static readonly List<string> PresetMsgFilters =
|
||||
[
|
||||
"proxy",
|
||||
|
||||
@@ -137,6 +137,7 @@ public class TunModeItem
|
||||
public bool EnableIPv6Address { get; set; }
|
||||
public string IcmpRouting { get; set; }
|
||||
public bool EnableLegacyProtect { get; set; } = true;
|
||||
public string? DnsMode { get; set; }
|
||||
public List<string>? RouteExcludeAddress { get; set; }
|
||||
public string IPv4Address { get; set; }
|
||||
public string IPv6Address { get; set; }
|
||||
|
||||
@@ -114,6 +114,7 @@ public class Inbound4Sbox
|
||||
public bool? auto_route { get; set; }
|
||||
public bool? strict_route { get; set; }
|
||||
public string? stack { get; set; }
|
||||
public string? dns_mode { get; set; }
|
||||
public List<User4Sbox> users { get; set; }
|
||||
public List<string>? route_exclude_address { get; set; }
|
||||
}
|
||||
|
||||
Generated
+9
@@ -4913,6 +4913,15 @@ namespace ServiceLib.Resx {
|
||||
return ResourceManager.GetString("TbSettingsTunAutoRoute", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 DNS mode 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsTunDnsMode {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsTunDnsMode", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Tun Mode settings 的本地化字符串。
|
||||
|
||||
@@ -1080,6 +1080,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Stek</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>DNS rejimi</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
|
||||
@@ -1065,6 +1065,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>پشته شبکه</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>حالت DNS</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
@@ -1773,4 +1776,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuNewUpdate" xml:space="preserve">
|
||||
<value>New Update</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -1059,6 +1059,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Pile de protocoles</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>Mode DNS</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
@@ -1767,4 +1770,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuNewUpdate" xml:space="preserve">
|
||||
<value>Nouvelle MAJ</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -1062,6 +1062,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Hálózati verem</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>DNS-mód</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
@@ -1770,4 +1773,4 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuNewUpdate" xml:space="preserve">
|
||||
<value>New Update</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -1062,6 +1062,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Stack</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>Mode DNS</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
@@ -1794,4 +1797,4 @@ Tindakan "Ambil sertifikat" mungkin gagal jika sertifikat self-signed digunakan
|
||||
<data name="TbEnableFinalFragmentTip" xml:space="preserve">
|
||||
<value>Memecah bagian akhir paket menjadi fragmen yang lebih kecil. Hal ini dapat memengaruhi throughput dan latensi.</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -1083,6 +1083,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Stack</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>DNS mode</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
|
||||
@@ -1083,6 +1083,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Сетевой стек</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>Режим DNS</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
@@ -1905,4 +1908,4 @@
|
||||
<data name="menuAddMasqueServer" xml:space="preserve">
|
||||
<value>Добавить сервер [MASQUE]</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
|
||||
@@ -1071,6 +1071,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>协议栈</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>DNS 模式</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
|
||||
@@ -1080,6 +1080,9 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>協定堆疊</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunDnsMode" xml:space="preserve">
|
||||
<value>DNS 模式</value>
|
||||
</data>
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
|
||||
@@ -68,6 +68,9 @@ public partial class CoreConfigSingboxService
|
||||
tunInbound.auto_route = _config.TunModeItem.AutoRoute;
|
||||
tunInbound.strict_route = _config.TunModeItem.StrictRoute;
|
||||
tunInbound.stack = _config.TunModeItem.Stack;
|
||||
tunInbound.dns_mode = _config.TunModeItem.DnsMode == Global.TunDnsModeDefault
|
||||
? null
|
||||
: _config.TunModeItem.DnsMode.NullIfEmpty();
|
||||
|
||||
var address = _config.TunModeItem.IPv4Address.NullIfEmpty() ?? Global.TunIPv4Address.First();
|
||||
tunInbound.address = [address];
|
||||
|
||||
@@ -113,23 +113,27 @@ public partial class CoreConfigSingboxService
|
||||
}
|
||||
}
|
||||
|
||||
var disableDnsHijack = string.Equals(_config.TunModeItem.DnsMode, "disabled", StringComparison.OrdinalIgnoreCase);
|
||||
if (_config.Inbound.First().SniffingEnabled)
|
||||
{
|
||||
_coreConfig.route.rules.Add(new()
|
||||
{
|
||||
action = "sniff"
|
||||
});
|
||||
_coreConfig.route.rules.Add(new()
|
||||
if (!disableDnsHijack)
|
||||
{
|
||||
type = "logical",
|
||||
mode = "or",
|
||||
action = "hijack-dns",
|
||||
rules =
|
||||
[
|
||||
new() { port = [53] },
|
||||
new() { protocol = ["dns"] },
|
||||
],
|
||||
});
|
||||
_coreConfig.route.rules.Add(new()
|
||||
{
|
||||
type = "logical",
|
||||
mode = "or",
|
||||
action = "hijack-dns",
|
||||
rules =
|
||||
[
|
||||
new() { port = [53] },
|
||||
new() { protocol = ["dns"] },
|
||||
],
|
||||
});
|
||||
}
|
||||
if (_config.CoreBasicItem.EnableFinalFragment)
|
||||
{
|
||||
_coreConfig.route.rules.Add(new()
|
||||
@@ -142,11 +146,14 @@ public partial class CoreConfigSingboxService
|
||||
}
|
||||
else
|
||||
{
|
||||
_coreConfig.route.rules.Add(new()
|
||||
if (!disableDnsHijack)
|
||||
{
|
||||
port = [53],
|
||||
action = "hijack-dns",
|
||||
});
|
||||
_coreConfig.route.rules.Add(new()
|
||||
{
|
||||
port = [53],
|
||||
action = "hijack-dns",
|
||||
});
|
||||
}
|
||||
if (_config.CoreBasicItem.EnableFinalFragment)
|
||||
{
|
||||
_coreConfig.route.rules.Add(new()
|
||||
|
||||
@@ -97,6 +97,7 @@ public partial class OptionSettingViewModel : MyReactiveObject, ICloseable
|
||||
[Reactive] public partial bool TunEnableIPv6Address { get; set; }
|
||||
[Reactive] public partial string TunIcmpRouting { get; set; }
|
||||
[Reactive] public partial bool TunEnableLegacyProtect { get; set; }
|
||||
[Reactive] public partial string TunDnsMode { get; set; }
|
||||
[Reactive] public partial string TunRouteExcludeAddress { get; set; }
|
||||
[Reactive] public partial string TunIPv4Address { get; set; }
|
||||
[Reactive] public partial string TunIPv6Address { get; set; }
|
||||
@@ -222,6 +223,7 @@ public partial class OptionSettingViewModel : MyReactiveObject, ICloseable
|
||||
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
||||
TunIcmpRouting = _config.TunModeItem.IcmpRouting;
|
||||
TunEnableLegacyProtect = _config.TunModeItem.EnableLegacyProtect;
|
||||
TunDnsMode = _config.TunModeItem.DnsMode.NullIfEmpty() ?? Global.TunDnsModeDefault;
|
||||
TunRouteExcludeAddress = Utils.List2String(_config.TunModeItem.RouteExcludeAddress, true);
|
||||
TunIPv4Address = _config.TunModeItem.IPv4Address;
|
||||
TunIPv6Address = _config.TunModeItem.IPv6Address;
|
||||
@@ -395,6 +397,7 @@ public partial class OptionSettingViewModel : MyReactiveObject, ICloseable
|
||||
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
||||
_config.TunModeItem.IcmpRouting = TunIcmpRouting;
|
||||
_config.TunModeItem.EnableLegacyProtect = TunEnableLegacyProtect;
|
||||
_config.TunModeItem.DnsMode = TunDnsMode == Global.TunDnsModeDefault ? null : TunDnsMode;
|
||||
_config.TunModeItem.RouteExcludeAddress = Utils.String2List(TunRouteExcludeAddress);
|
||||
_config.TunModeItem.IPv4Address = TunIPv4Address;
|
||||
_config.TunModeItem.IPv6Address = TunIPv6Address;
|
||||
|
||||
@@ -1035,7 +1035,7 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
ColumnDefinitions="Auto,Auto,Auto"
|
||||
DockPanel.Dock="Top"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
@@ -1189,6 +1189,20 @@
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="12"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunDnsMode}" />
|
||||
<ComboBox
|
||||
x:Name="cmbDnsMode"
|
||||
Grid.Row="12"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
@@ -33,6 +33,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
cmbmux4RayXudpProxyUDP443.ItemsSource = new[] { "reject", "skip" };
|
||||
cmbMtu.ItemsSource = Global.TunMtus;
|
||||
cmbStack.ItemsSource = Global.TunStacks;
|
||||
cmbDnsMode.ItemsSource = Global.TunDnsModes;
|
||||
cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies;
|
||||
cmbIpv4Address.ItemsSource = Global.TunIPv4Address;
|
||||
cmbIpv6Address.ItemsSource = Global.TunIPv6Address;
|
||||
@@ -135,6 +136,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
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.TunEnableLegacyProtect, v => v.togEnableLegacyProtect.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDnsMode, v => v.cmbDnsMode.SelectedValue).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);
|
||||
|
||||
@@ -1278,6 +1278,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -1458,6 +1459,22 @@
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="12"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunDnsMode}" />
|
||||
<ComboBox
|
||||
x:Name="cmbDnsMode"
|
||||
Grid.Row="12"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
@@ -29,6 +29,7 @@ public partial class OptionSettingWindow
|
||||
cmbmux4RayXudpProxyUDP443.ItemsSource = new[] { "reject", "skip" };
|
||||
cmbMtu.ItemsSource = Global.TunMtus;
|
||||
cmbStack.ItemsSource = Global.TunStacks;
|
||||
cmbDnsMode.ItemsSource = Global.TunDnsModes;
|
||||
cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies;
|
||||
cmbIpv4Address.ItemsSource = Global.TunIPv4Address;
|
||||
cmbIpv6Address.ItemsSource = Global.TunIPv6Address;
|
||||
@@ -131,6 +132,7 @@ public partial class OptionSettingWindow
|
||||
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.TunEnableLegacyProtect, v => v.togEnableLegacyProtect.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunDnsMode, v => v.cmbDnsMode.Text).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);
|
||||
|
||||
Reference in New Issue
Block a user