Add DNS via NetBridge

This commit is contained in:
2dust
2026-06-19 17:13:51 +08:00
parent 0d225cd29d
commit ff456a9389
10 changed files with 123 additions and 10 deletions

View File

@@ -166,6 +166,18 @@ public sealed class NetBridgeManager
}
}
public async Task<bool> SetDnsViaProxy(bool enable)
{
if (_netBridgeService == null)
{
return false;
}
_netBridgeService.SetDnsViaProxy(enable);
return await Task.FromResult(true);
}
private async Task<bool> ApplyRoutesInternal()
{
if (_netBridgeService == null)
@@ -208,6 +220,11 @@ public sealed class NetBridgeManager
private static List<NetBridgeRuleConfig> BuildRuleConfigs(string? ruleProcess)
{
if (ruleProcess.IsNullOrEmpty())
{
return new();
}
var processNames = Utils.String2List(Utils.Convert2Comma(ruleProcess));
return processNames.Select(processName => new NetBridgeRuleConfig
{

View File

@@ -282,4 +282,5 @@ public class SimpleDNSItem
public class NetBridgeItem
{
public string? RuleProcess { get; set; }
public bool EnableDnsViaProxy { get; set; }
}

View File

@@ -3052,7 +3052,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Enables process traffic hijacking (experimental), similar to Proxifer; can coexist with system proxy; conflicts with TUN mode, please do not enable them simultaneously; 的本地化字符串。
/// 查找类似 Enables process traffic hijacking (experimental), similar to Proxifer; can coexist with system proxy; conflicts with TUN mode, please do not enable them simultaneously;please allow v2rayN to use a private network in your firewall. 的本地化字符串。
/// </summary>
public static string TbEnableNetBridge {
get {
@@ -3060,6 +3060,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 DNS via Bridge 的本地化字符串。
/// </summary>
public static string TbEnabletDnsViaProxy {
get {
return ResourceManager.GetString("TbEnabletDnsViaProxy", resourceCulture);
}
}
/// <summary>
/// 查找类似 Enable Tun 的本地化字符串。
/// </summary>
@@ -3699,6 +3708,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Save rules 的本地化字符串。
/// </summary>
public static string TbSaveNetBridgeRule {
get {
return ResourceManager.GetString("TbSaveNetBridgeRule", resourceCulture);
}
}
/// <summary>
/// 查找类似 sing-box Full Config Template 的本地化字符串。
/// </summary>

View File

@@ -1765,7 +1765,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<value>Split the tail of packets into smaller fragments. This may affect throughput and latency.</value>
</data>
<data name="TbEnableNetBridge" xml:space="preserve">
<value>Enables process traffic hijacking (experimental), similar to Proxifer; can coexist with system proxy; conflicts with TUN mode, please do not enable them simultaneously;</value>
<value>Enables process traffic hijacking (experimental), similar to Proxifer; can coexist with system proxy; conflicts with TUN mode, please do not enable them simultaneously;please allow v2rayN to use a private network in your firewall.</value>
</data>
<data name="NetBridgeRuleTips" xml:space="preserve">
<value>The process names that need to be proxied; separate multiple processes with commas. Processes not in the list will also be hijacked, but will connect directly.</value>
@@ -1773,4 +1773,10 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="menuNetBridge" xml:space="preserve">
<value>Process traffic hijacking (experimental)</value>
</data>
</root>
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
<value>DNS via Bridge</value>
</data>
<data name="TbSaveNetBridgeRule" xml:space="preserve">
<value>Save rules</value>
</data>
</root>

View File

@@ -1762,7 +1762,7 @@
<value>将数据包末端拆分为更小片段发送,可能影响吞吐与延迟。</value>
</data>
<data name="TbEnableNetBridge" xml:space="preserve">
<value>启用进程流量劫持(实验性),类似 Proxifer 功能;可以和系统代理并存;和 TUN 模式冲突,请不要同时开启;</value>
<value>启用进程流量劫持(实验性),类似 Proxifer 功能;可以和系统代理并存;和 TUN 模式冲突,请不要同时开启;请在防火墙中允许 v2rayN 使用专用网络</value>
</data>
<data name="NetBridgeRuleTips" xml:space="preserve">
<value>需要代理的进程名,多个进程请用逗号分隔;不在列表中的进程也会被劫持,但是会直连</value>
@@ -1770,4 +1770,10 @@
<data name="menuNetBridge" xml:space="preserve">
<value>进程流量劫持(实验性)</value>
</data>
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
<value>DNS 通过 Bridge</value>
</data>
<data name="TbSaveNetBridgeRule" xml:space="preserve">
<value>保存规则</value>
</data>
</root>

View File

@@ -1762,7 +1762,7 @@
<value>將封包末端拆分為更小的片段進行傳送,可能會影響吞吐量與延遲</value>
</data>
<data name="TbEnableNetBridge" xml:space="preserve">
<value>啟用進程流量劫持(實驗性),類似 Proxifer 功能;可以和系統代理並存;和 TUN 模式衝突,請不要同時開啟;</value>
<value>啟用進程流量劫持(實驗性),類似 Proxifer 功能;可以和系統代理並存;和 TUN 模式衝突,請不要同時開啟;請在防火牆中允許 v2rayN 使用專用網絡</value>
</data>
<data name="NetBridgeRuleTips" xml:space="preserve">
<value>需要代理程式的進程名,多個進程請用逗號分隔;不在清單中的進程也會被劫持,但是會直連</value>
@@ -1770,4 +1770,10 @@
<data name="menuNetBridge" xml:space="preserve">
<value>進程流量劫持(實驗性)</value>
</data>
<data name="TbEnabletDnsViaProxy" xml:space="preserve">
<value>DNS 透過 Bridge</value>
</data>
<data name="TbSaveNetBridgeRule" xml:space="preserve">
<value>保存規則</value>
</data>
</root>

View File

@@ -5,6 +5,9 @@ public class NetBridgeViewModel : MyReactiveObject
[Reactive]
public bool EnableNetBridge { get; set; }
[Reactive]
public bool EnabletDnsViaProxy { get; set; }
[Reactive]
public string RuleProcess { get; set; }
@@ -27,22 +30,31 @@ public class NetBridgeViewModel : MyReactiveObject
await ToggleNetBridgeAsync(enabled);
});
this.WhenAnyValue(x => x.EnabletDnsViaProxy)
.Skip(1)
.Subscribe(async enabled =>
{
await ToggleDnsViaProxyAsync(enabled);
});
_ = Init();
}
private async Task Init()
{
EnabletDnsViaProxy = _config.NetBridgeItem.EnableDnsViaProxy;
_config.NetBridgeItem ??= new()
{
RuleProcess = string.Empty
};
EnableNetBridge = false;
RuleProcess = _config.NetBridgeItem.RuleProcess;
if (RuleProcess.IsNullOrEmpty())
if (_config.NetBridgeItem.RuleProcess.IsNullOrEmpty())
{
RuleProcess = "Chrome.exe";
_config.NetBridgeItem.RuleProcess = "Chrome.exe";
}
RuleProcess = _config.NetBridgeItem.RuleProcess;
await Task.CompletedTask;
}
@@ -58,6 +70,7 @@ public class NetBridgeViewModel : MyReactiveObject
{
await NetBridgeManager.Instance.UpdateProxyConfig(Global.Loopback, AppManager.Instance.GetLocalPort(EInboundProtocol.socks));
await NetBridgeManager.Instance.UpdateRoutes(RuleProcess);
await NetBridgeManager.Instance.SetDnsViaProxy(EnabletDnsViaProxy);
}
NoticeManager.Instance.Enqueue(succeed ? ResUI.OperationSuccess : ResUI.OperationFailed);
}
@@ -68,6 +81,13 @@ public class NetBridgeViewModel : MyReactiveObject
}
}
private async Task ToggleDnsViaProxyAsync(bool enabled)
{
_config.NetBridgeItem.EnableDnsViaProxy = enabled;
await NetBridgeManager.Instance.SetDnsViaProxy(enabled);
}
/// </summary>
private async Task SaveRulesAsync()
{

View File

@@ -34,6 +34,25 @@
TextWrapping="Wrap" />
</StackPanel>
<StackPanel
Margin="{StaticResource Margin8}"
DockPanel.Dock="Top"
Orientation="Horizontal">
<ToggleSwitch
x:Name="togEnabletDnsViaProxy"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Width="500"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbEnabletDnsViaProxy}"
TextWrapping="Wrap" />
</StackPanel>
<DockPanel>
<StackPanel
Margin="{StaticResource Margin8}"
@@ -57,7 +76,7 @@
<Button
x:Name="btnSave"
Width="100"
Content="{x:Static resx:ResUI.TbConfirm}"
Content="{x:Static resx:ResUI.TbSaveNetBridgeRule}"
IsDefault="True" />
</StackPanel>

View File

@@ -35,6 +35,25 @@
TextWrapping="Wrap" />
</StackPanel>
<StackPanel
Margin="{StaticResource Margin8}"
DockPanel.Dock="Top"
Orientation="Horizontal">
<ToggleButton
x:Name="togEnabletDnsViaProxy"
Margin="{StaticResource Margin8}"
HorizontalAlignment="Left" />
<TextBlock
Width="500"
Margin="{StaticResource Margin8}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbEnabletDnsViaProxy}"
TextWrapping="Wrap" />
</StackPanel>
<DockPanel>
<StackPanel
Margin="{StaticResource Margin8}"
@@ -59,7 +78,7 @@
<Button
x:Name="btnSave"
Width="100"
Content="{x:Static resx:ResUI.TbConfirm}"
Content="{x:Static resx:ResUI.TbSaveNetBridgeRule}"
IsDefault="True"
Style="{StaticResource DefButton}" />
</StackPanel>

View File

@@ -13,6 +13,7 @@ public partial class NetBridgeView
this.BindCommand(ViewModel, vm => vm.SaveRulesCmd, v => v.btnSave).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableNetBridge, v => v.togEnableNetBridge.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnabletDnsViaProxy, v => v.togEnabletDnsViaProxy.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RuleProcess, v => v.txtRuleProcess.Text).DisposeWith(disposables);
});