mirror of
https://github.com/netchx/netch.git
synced 2026-03-18 18:13:21 +08:00
replace eycorsican/go-tun2socks with aiocloud/tun2socks(WinTUN)
This commit is contained in:
@@ -4,14 +4,18 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Utils;
|
||||
using Vanara.PInvoke;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
using static Vanara.PInvoke.Ws2_32;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNTAPController : Guard, IModeController
|
||||
public class TUNController : Guard, IModeController
|
||||
{
|
||||
private readonly List<string> _directIPs = new();
|
||||
|
||||
@@ -26,9 +30,9 @@ namespace Netch.Controllers
|
||||
/// </summary>
|
||||
public DNSController DNSController = new();
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"Running"};
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"Started"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"failed", "invalid vconfig file"};
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new List<string>();
|
||||
|
||||
public override string MainFile { get; protected set; } = "tun2socks.exe";
|
||||
|
||||
@@ -36,69 +40,43 @@ namespace Netch.Controllers
|
||||
|
||||
public override string Name { get; } = "tun2socks";
|
||||
|
||||
private readonly OutboundAdapter _outbound = new();
|
||||
private TapAdapter _tap = null!;
|
||||
private readonly OutboundAdapter _outboundAdapter = new();
|
||||
private IAdapter _tunAdapter = null!;
|
||||
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
var server = MainController.Server!;
|
||||
_serverAddresses = DnsUtils.Lookup(server.Hostname)!; // server address have been cached when MainController.Start
|
||||
|
||||
if (TUNTAP.GetComponentID() == null)
|
||||
TUNTAP.AddTap();
|
||||
var parameter = new WinTun2socksParameter();
|
||||
|
||||
_tap = new TapAdapter();
|
||||
|
||||
List<string> dns;
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
if (server is Socks5 socks5)
|
||||
{
|
||||
dns = Global.Settings.TUNTAP.DNS.Any() ? Global.Settings.TUNTAP.DNS : Global.Settings.TUNTAP.DNS = new List<string> {"1.1.1.1"};
|
||||
parameter.hostname = $"{server.AutoResolveHostname()}:{server.Port}";
|
||||
if (socks5.Auth())
|
||||
{
|
||||
parameter.username = socks5.Username!;
|
||||
parameter.password = socks5.Password!;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainController.PortCheck(53, "DNS");
|
||||
DNSController.Start();
|
||||
dns = new List<string> {"127.0.0.1"};
|
||||
}
|
||||
parameter.hostname = $"127.0.0.1:{Global.Settings.Socks5LocalPort}";
|
||||
|
||||
var parameter = new Tun2SocksParameter
|
||||
{
|
||||
tunAddr = Global.Settings.TUNTAP.Address,
|
||||
tunMask = Global.Settings.TUNTAP.Netmask,
|
||||
tunGw = Global.Settings.TUNTAP.Gateway,
|
||||
tunDns = DnsUtils.Join(dns),
|
||||
tunName = TUNTAP.GetName(_tap.ComponentID),
|
||||
fakeDns = Global.Settings.TUNTAP.UseFakeDNS && Flags.SupportFakeDns
|
||||
};
|
||||
MainFile = "tun2socks.exe";
|
||||
StartInstanceAuto(parameter.ToString());
|
||||
_tunAdapter = new TunAdapter();
|
||||
|
||||
if (server is Socks5 socks5 && !socks5.Auth())
|
||||
parameter.proxyServer = $"{server.AutoResolveHostname()}:{server.Port}";
|
||||
else
|
||||
parameter.proxyServer = $"127.0.0.1:{Global.Settings.Socks5LocalPort}";
|
||||
/*
|
||||
InitializeUnicastIpAddressEntry(out var addr_row);
|
||||
CreateUnicastIpAddressEntry(ref addr_row);
|
||||
*/
|
||||
|
||||
StartInstanceAuto(parameter.ToString(), ProcessPriorityClass.RealTime);
|
||||
Utils.Utils.ProcessRunHiddenAsync("netsh", "interface ipv4 add address aioCloud 100.64.0.100 255.255.255.0").Wait();
|
||||
Utils.Utils.ProcessRunHiddenAsync("route", "print -4", false).Wait();
|
||||
|
||||
SetupRouteTable(mode);
|
||||
}
|
||||
|
||||
[Verb]
|
||||
public class Tun2SocksParameter : ParameterBase
|
||||
{
|
||||
public string proxyServer { get; set; }
|
||||
|
||||
public string tunAddr { get; set; }
|
||||
|
||||
public string tunMask { get; set; }
|
||||
|
||||
public string tunGw { get; set; }
|
||||
|
||||
public string tunDns { get; set; }
|
||||
|
||||
public string tunName { get; set; }
|
||||
|
||||
public bool fakeDns { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
@@ -123,6 +101,13 @@ namespace Netch.Controllers
|
||||
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
|
||||
Logging.Info("设置路由规则");
|
||||
|
||||
Logging.Info("绕行 → 服务器 IP");
|
||||
if (!IPAddress.IsLoopback(_serverAddresses))
|
||||
RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound);
|
||||
|
||||
Logging.Info("绕行 → 全局绕过 IP");
|
||||
RouteAction(Action.Create, Global.Settings.BypassIPs, RouteType.Outbound);
|
||||
|
||||
#region Rule IPs
|
||||
|
||||
switch (mode.Type)
|
||||
@@ -132,11 +117,11 @@ namespace Netch.Controllers
|
||||
Logging.Info("代理 → 规则 IP");
|
||||
RouteAction(Action.Create, mode.FullRule, RouteType.TUNTAP);
|
||||
|
||||
if (Global.Settings.TUNTAP.ProxyDNS)
|
||||
if (Global.Settings.WinTUN.ProxyDNS)
|
||||
{
|
||||
Logging.Info("代理 → 自定义 DNS");
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
RouteAction(Action.Create, Global.Settings.TUNTAP.DNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP);
|
||||
if (Global.Settings.WinTUN.UseCustomDNS)
|
||||
RouteAction(Action.Create, Global.Settings.WinTUN.DNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP);
|
||||
else
|
||||
RouteAction(Action.Create, $"{Global.Settings.AioDNS.OtherDNS}/32", RouteType.TUNTAP);
|
||||
}
|
||||
@@ -145,9 +130,6 @@ namespace Netch.Controllers
|
||||
case 2:
|
||||
// 绕过规则 IP
|
||||
|
||||
// 将 TUN/TAP 网卡权重放到最高
|
||||
SetInterface(RouteType.TUNTAP, 0);
|
||||
|
||||
Logging.Info("绕行 → 规则 IP");
|
||||
RouteAction(Action.Create, mode.FullRule, RouteType.Outbound);
|
||||
break;
|
||||
@@ -155,41 +137,23 @@ namespace Netch.Controllers
|
||||
|
||||
#endregion
|
||||
|
||||
Logging.Info("绕行 → 服务器 IP");
|
||||
if (!IPAddress.IsLoopback(_serverAddresses))
|
||||
RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound);
|
||||
|
||||
Logging.Info("绕行 → 全局绕过 IP");
|
||||
RouteAction(Action.Create, Global.Settings.BypassIPs, RouteType.Outbound);
|
||||
|
||||
if (mode.Type == 2)
|
||||
{
|
||||
Logging.Info("代理 → 全局");
|
||||
SetInterface(RouteType.TUNTAP, 0);
|
||||
RouteAction(Action.Create, "0.0.0.0/0", RouteType.TUNTAP);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetInterface(RouteType routeType, int? metric = null)
|
||||
{
|
||||
IAdapter adapter = routeType switch
|
||||
{
|
||||
RouteType.Outbound => _outbound,
|
||||
RouteType.TUNTAP => _tap,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
|
||||
};
|
||||
var adapter = routeType == RouteType.Outbound ? _outboundAdapter : _tunAdapter;
|
||||
|
||||
var arguments = $"interface ip set interface {adapter.Index} ";
|
||||
var arguments = $"interface ip set interface {adapter.InterfaceIndex} ";
|
||||
if (metric != null)
|
||||
arguments += $"metric={metric} ";
|
||||
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "netsh",
|
||||
Arguments = arguments,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = true,
|
||||
CreateNoWindow = true
|
||||
});
|
||||
Utils.Utils.ProcessRunHiddenAsync("netsh", arguments).Wait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -197,10 +161,16 @@ namespace Netch.Controllers
|
||||
/// </summary>
|
||||
private bool ClearRouteTable()
|
||||
{
|
||||
var mode = MainController.Mode!;
|
||||
RouteAction(Action.Delete, _directIPs, RouteType.Outbound);
|
||||
RouteAction(Action.Delete, _proxyIPs, RouteType.TUNTAP);
|
||||
_directIPs.Clear();
|
||||
_proxyIPs.Clear();
|
||||
if (mode.Type == 2)
|
||||
{
|
||||
SetInterface(RouteType.Outbound);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -218,6 +188,8 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
#region Package
|
||||
|
||||
private void RouteAction(Action action, in IEnumerable<string> ipNetworks, RouteType routeType, int metric = 0)
|
||||
{
|
||||
foreach (var address in ipNetworks)
|
||||
@@ -239,11 +211,11 @@ namespace Netch.Controllers
|
||||
switch (routeType)
|
||||
{
|
||||
case RouteType.TUNTAP:
|
||||
adapter = _tap;
|
||||
adapter = _tunAdapter;
|
||||
ipList = _proxyIPs;
|
||||
break;
|
||||
case RouteType.Outbound:
|
||||
adapter = _outbound;
|
||||
adapter = _outboundAdapter;
|
||||
ipList = _directIPs;
|
||||
break;
|
||||
default:
|
||||
@@ -253,13 +225,16 @@ namespace Netch.Controllers
|
||||
string network = s[0];
|
||||
var cidr = ushort.Parse(s[1]);
|
||||
string gateway = adapter.Gateway.ToString();
|
||||
var index = adapter.Index;
|
||||
var index = adapter.InterfaceIndex;
|
||||
|
||||
bool result;
|
||||
switch (action)
|
||||
{
|
||||
case Action.Create:
|
||||
result = NativeMethods.CreateRoute(network, cidr, gateway, index, metric);
|
||||
#if DEBUG
|
||||
Console.WriteLine($"CreateRoute(\"{network}\", {cidr}, \"{gateway}\", {index}, {metric})");
|
||||
#endif
|
||||
ipList.Add(ipNetwork);
|
||||
break;
|
||||
case Action.Delete:
|
||||
@@ -286,5 +261,46 @@ namespace Netch.Controllers
|
||||
Create,
|
||||
Delete
|
||||
}
|
||||
|
||||
[Verb]
|
||||
public class Tap2SocksParameter : ParameterBase
|
||||
{
|
||||
public string? proxyServer { get; set; }
|
||||
|
||||
public string? tunAddr { get; set; }
|
||||
|
||||
public string? tunMask { get; set; }
|
||||
|
||||
public string? tunGw { get; set; }
|
||||
|
||||
public string? tunDns { get; set; }
|
||||
|
||||
public string? tunName { get; set; }
|
||||
|
||||
public bool fakeDns { get; set; }
|
||||
}
|
||||
|
||||
[Verb]
|
||||
class WinTun2socksParameter : ParameterBase
|
||||
{
|
||||
public string? bind { get; set; } = "10.0.0.100";
|
||||
|
||||
[Quote]
|
||||
public string? list { get; set; } = "disabled";
|
||||
|
||||
public string? hostname { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? username { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? password { get; set; }
|
||||
|
||||
public string? dns { get; set; } = "1.1.1.1:53";
|
||||
|
||||
public int? mtu { get; set; } = 1500;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,6 @@ namespace Netch
|
||||
{
|
||||
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
|
||||
|
||||
private static readonly Lazy<bool> LazySupportFakeDns = new(() => new TUNTAPController().TestFakeDNS());
|
||||
|
||||
public static bool SupportFakeDns => LazySupportFakeDns.Value;
|
||||
|
||||
public static bool AlwaysShowNewVersionFound { get; set; }
|
||||
}
|
||||
}
|
||||
10
Netch/Forms/MainForm.Designer.cs
generated
10
Netch/Forms/MainForm.Designer.cs
generated
@@ -46,7 +46,6 @@
|
||||
this.updateACLWithProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.updatePACToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallTapDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.removeNetchFirewallRulesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.HelpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CheckForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -208,7 +207,6 @@
|
||||
this.updateACLWithProxyToolStripMenuItem,
|
||||
this.updatePACToolStripMenuItem,
|
||||
this.UninstallServiceToolStripMenuItem,
|
||||
this.UninstallTapDriverToolStripMenuItem,
|
||||
this.removeNetchFirewallRulesToolStripMenuItem});
|
||||
this.OptionsToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.OptionsToolStripMenuItem.Name = "OptionsToolStripMenuItem";
|
||||
@@ -257,13 +255,6 @@
|
||||
this.UninstallServiceToolStripMenuItem.Text = "Uninstall NF Service";
|
||||
this.UninstallServiceToolStripMenuItem.Click += new System.EventHandler(this.UninstallServiceToolStripMenuItem_Click);
|
||||
//
|
||||
// UninstallTapDriverToolStripMenuItem
|
||||
//
|
||||
this.UninstallTapDriverToolStripMenuItem.Name = "UninstallTapDriverToolStripMenuItem";
|
||||
this.UninstallTapDriverToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.UninstallTapDriverToolStripMenuItem.Text = "Uninstall TUN/TAP driver";
|
||||
this.UninstallTapDriverToolStripMenuItem.Click += new System.EventHandler(this.UninstallTapDriverToolStripMenuItem_Click);
|
||||
//
|
||||
// removeNetchFirewallRulesToolStripMenuItem
|
||||
//
|
||||
this.removeNetchFirewallRulesToolStripMenuItem.Name = "removeNetchFirewallRulesToolStripMenuItem";
|
||||
@@ -801,7 +792,6 @@
|
||||
private System.Windows.Forms.Label ProfileLabel;
|
||||
private System.Windows.Forms.TextBox ProfileNameText;
|
||||
private System.Windows.Forms.TableLayoutPanel ProfileTable;
|
||||
private System.Windows.Forms.ToolStripMenuItem UninstallTapDriverToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem CheckForUpdatesToolStripMenuItem;
|
||||
private System.Windows.Forms.ComboBox ServerComboBox;
|
||||
private System.Windows.Forms.Label ServerLabel;
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace Netch.Forms
|
||||
#region i18N Translations
|
||||
|
||||
_mainFormText.Add(UninstallServiceToolStripMenuItem.Name, new[] {"Uninstall {0}", "NF Service"});
|
||||
_mainFormText.Add(UninstallTapDriverToolStripMenuItem.Name, new[] {"Uninstall {0}", "TUN/TAP driver"});
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -508,26 +507,6 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private async void UninstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
StatusText(i18N.TranslateFormat("Uninstalling {0}", "TUN/TAP driver"));
|
||||
try
|
||||
{
|
||||
await Task.Run(TUNTAP.deltapall);
|
||||
NotifyTip(i18N.TranslateFormat("{0} has been uninstalled", "TUN/TAP driver"));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logging.Error($"卸载 TUN/TAP 适配器失败: {exception}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
StatusText();
|
||||
Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveNetchFirewallRulesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Firewall.RemoveNetchFwRules();
|
||||
@@ -1101,7 +1080,7 @@ namespace Netch.Forms
|
||||
// 启动需要禁用的控件
|
||||
UninstallServiceToolStripMenuItem.Enabled = UpdateACLToolStripMenuItem.Enabled = updateACLWithProxyToolStripMenuItem.Enabled =
|
||||
updatePACToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
|
||||
UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Enabled = UninstallTapDriverToolStripMenuItem.Enabled = enabled;
|
||||
UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Enabled = enabled;
|
||||
}
|
||||
|
||||
_state = value;
|
||||
|
||||
17
Netch/Forms/SettingForm.Designer.cs
generated
17
Netch/Forms/SettingForm.Designer.cs
generated
@@ -81,7 +81,6 @@ namespace Netch.Forms
|
||||
this.TUNTAPDNSTextBox = new System.Windows.Forms.TextBox();
|
||||
this.UseCustomDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ProxyDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.UseFakeDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.GlobalBypassIPsButton = new System.Windows.Forms.Button();
|
||||
this.v2rayTabPage = new System.Windows.Forms.TabPage();
|
||||
this.XrayConeCheckBox = new System.Windows.Forms.CheckBox();
|
||||
@@ -544,13 +543,13 @@ namespace Netch.Forms
|
||||
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPDNSTextBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.ProxyDNSCheckBox);
|
||||
this.TUNTAPGroupBox.Controls.Add(this.UseFakeDNSCheckBox);
|
||||
this.TUNTAPGroupBox.Location = new System.Drawing.Point(6, 6);
|
||||
this.TUNTAPGroupBox.Name = "TUNTAPGroupBox";
|
||||
this.TUNTAPGroupBox.Size = new System.Drawing.Size(420, 187);
|
||||
this.TUNTAPGroupBox.Size = new System.Drawing.Size(420, 175);
|
||||
this.TUNTAPGroupBox.TabIndex = 0;
|
||||
this.TUNTAPGroupBox.TabStop = false;
|
||||
this.TUNTAPGroupBox.Text = "TUN/TAP";
|
||||
this.TUNTAPGroupBox.Visible = false;
|
||||
//
|
||||
// TUNTAPAddressLabel
|
||||
//
|
||||
@@ -642,17 +641,6 @@ namespace Netch.Forms
|
||||
this.ProxyDNSCheckBox.Text = "Proxy DNS in Proxy Rule IPs Mode";
|
||||
this.ProxyDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// UseFakeDNSCheckBox
|
||||
//
|
||||
this.UseFakeDNSCheckBox.AutoSize = true;
|
||||
this.UseFakeDNSCheckBox.Location = new System.Drawing.Point(10, 160);
|
||||
this.UseFakeDNSCheckBox.Name = "UseFakeDNSCheckBox";
|
||||
this.UseFakeDNSCheckBox.Size = new System.Drawing.Size(96, 16);
|
||||
this.UseFakeDNSCheckBox.TabIndex = 10;
|
||||
this.UseFakeDNSCheckBox.Text = "Use Fake DNS";
|
||||
this.UseFakeDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.UseFakeDNSCheckBox.Visible = false;
|
||||
//
|
||||
// GlobalBypassIPsButton
|
||||
//
|
||||
this.GlobalBypassIPsButton.Location = new System.Drawing.Point(6, 199);
|
||||
@@ -1095,7 +1083,6 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.TextBox Socks5PortTextBox;
|
||||
private System.Windows.Forms.CheckBox ResolveServerHostnameCheckBox;
|
||||
private System.Windows.Forms.GroupBox TUNTAPGroupBox;
|
||||
private System.Windows.Forms.CheckBox UseFakeDNSCheckBox;
|
||||
private System.Windows.Forms.CheckBox ProxyDNSCheckBox;
|
||||
private System.Windows.Forms.CheckBox UseCustomDNSCheckBox;
|
||||
private System.Windows.Forms.Label TUNTAPDNSLabel;
|
||||
|
||||
@@ -110,11 +110,17 @@ namespace Netch.Forms
|
||||
|
||||
BindCheckBox(DNSRedirectorCheckBox, b => Global.Settings.RedirectDNS = b, Global.Settings.RedirectDNS);
|
||||
|
||||
BindTextBox(RDRDNSTextBox, s => DnsUtils.TrySplit(s, out _, 2), s => Global.Settings.RedirectDNSAddr = s, Global.Settings.RedirectDNSAddr);
|
||||
BindTextBox(RDRDNSTextBox,
|
||||
s => DnsUtils.TrySplit(s, out _, 2),
|
||||
s => Global.Settings.RedirectDNSAddr = s,
|
||||
Global.Settings.RedirectDNSAddr);
|
||||
|
||||
BindCheckBox(ICMPRedirectorCheckBox, b => Global.Settings.RedirectICMP = b, Global.Settings.RedirectICMP);
|
||||
|
||||
BindTextBox(ModifiedICMPTextBox, s => DnsUtils.TrySplit(s, out _, 2), s => Global.Settings.RedirectICMPAddr = s, Global.Settings.RedirectICMPAddr);
|
||||
BindTextBox(ModifiedICMPTextBox,
|
||||
s => DnsUtils.TrySplit(s, out _, 2),
|
||||
s => Global.Settings.RedirectICMPAddr = s,
|
||||
Global.Settings.RedirectICMPAddr);
|
||||
|
||||
BindCheckBox(RedirectorSSCheckBox, s => Global.Settings.RedirectorSS = s, Global.Settings.RedirectorSS);
|
||||
|
||||
@@ -131,32 +137,31 @@ namespace Netch.Forms
|
||||
|
||||
BindTextBox(TUNTAPAddressTextBox,
|
||||
s => IPAddress.TryParse(s, out _),
|
||||
s => Global.Settings.TUNTAP.Address = s,
|
||||
Global.Settings.TUNTAP.Address);
|
||||
s => Global.Settings.WinTUN.Address = s,
|
||||
Global.Settings.WinTUN.Address);
|
||||
|
||||
BindTextBox(TUNTAPNetmaskTextBox,
|
||||
s => IPAddress.TryParse(s, out _),
|
||||
s => Global.Settings.TUNTAP.Netmask = s,
|
||||
Global.Settings.TUNTAP.Netmask);
|
||||
s => Global.Settings.WinTUN.Netmask = s,
|
||||
Global.Settings.WinTUN.Netmask);
|
||||
|
||||
BindTextBox(TUNTAPGatewayTextBox,
|
||||
s => IPAddress.TryParse(s, out _),
|
||||
s => Global.Settings.TUNTAP.Gateway = s,
|
||||
Global.Settings.TUNTAP.Gateway);
|
||||
s => Global.Settings.WinTUN.Gateway = s,
|
||||
Global.Settings.WinTUN.Gateway);
|
||||
|
||||
BindCheckBox(UseCustomDNSCheckBox, b => { Global.Settings.TUNTAP.UseCustomDNS = b; }, Global.Settings.TUNTAP.UseCustomDNS);
|
||||
BindCheckBox(UseCustomDNSCheckBox, b => { Global.Settings.WinTUN.UseCustomDNS = b; }, Global.Settings.WinTUN.UseCustomDNS);
|
||||
|
||||
BindTextBox(TUNTAPDNSTextBox,
|
||||
s => !UseCustomDNSCheckBox.Checked || DnsUtils.TrySplit(s, out _, 2),
|
||||
s =>
|
||||
{
|
||||
if (UseCustomDNSCheckBox.Checked)
|
||||
Global.Settings.TUNTAP.DNS = DnsUtils.Split(s).ToList();
|
||||
Global.Settings.WinTUN.DNS = DnsUtils.Split(s).ToList();
|
||||
},
|
||||
DnsUtils.Join(Global.Settings.TUNTAP.DNS));
|
||||
DnsUtils.Join(Global.Settings.WinTUN.DNS));
|
||||
|
||||
BindCheckBox(ProxyDNSCheckBox, b => Global.Settings.TUNTAP.ProxyDNS = b, Global.Settings.TUNTAP.ProxyDNS);
|
||||
BindCheckBox(UseFakeDNSCheckBox, b => Global.Settings.TUNTAP.UseFakeDNS = b, Global.Settings.TUNTAP.UseFakeDNS);
|
||||
BindCheckBox(ProxyDNSCheckBox, b => Global.Settings.WinTUN.ProxyDNS = b, Global.Settings.WinTUN.ProxyDNS);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -235,13 +240,12 @@ namespace Netch.Forms
|
||||
private void SettingForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null);
|
||||
Task.Run(() => BeginInvoke(new Action(() => UseFakeDNSCheckBox.Visible = Flags.SupportFakeDns)));
|
||||
}
|
||||
|
||||
private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
if (UseCustomDNSCheckBox.Checked)
|
||||
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any() ? DnsUtils.Join(Global.Settings.TUNTAP.DNS) : "1.1.1.1";
|
||||
TUNTAPDNSTextBox.Text = Global.Settings.WinTUN.DNS.Any() ? DnsUtils.Join(Global.Settings.WinTUN.DNS) : "1.1.1.1";
|
||||
else
|
||||
TUNTAPDNSTextBox.Text = "AioDNS";
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ using System.Net.NetworkInformation;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public interface IAdapter
|
||||
public interface IAdapter
|
||||
{
|
||||
public abstract int Index { get; }
|
||||
string AdapterId { get; }
|
||||
|
||||
public abstract IPAddress Gateway { get; }
|
||||
int InterfaceIndex { get; }
|
||||
|
||||
public abstract NetworkInterface NetworkInterface { get; }
|
||||
IPAddress Gateway { get; }
|
||||
|
||||
NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace Netch.Models
|
||||
.First(ni => ni.Supports(NetworkInterfaceComponent.IPv4) &&
|
||||
ni.GetIPProperties().GetIPv4Properties().Index == pRoute.dwForwardIfIndex);
|
||||
|
||||
Index = (int) pRoute.dwForwardIfIndex;
|
||||
InterfaceIndex = (int) pRoute.dwForwardIfIndex;
|
||||
Gateway = new IPAddress(pRoute.dwForwardNextHop.S_un_b);
|
||||
_parametersRegistry =
|
||||
Registry.LocalMachine.OpenSubKey($@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{NetworkInterface.Id}", true)!;
|
||||
@@ -31,14 +31,16 @@ namespace Netch.Models
|
||||
if (logging)
|
||||
{
|
||||
Logging.Info($"出口 网关 地址:{Gateway}");
|
||||
Logging.Info($"出口适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {Index}");
|
||||
Logging.Info($"出口适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
|
||||
}
|
||||
}
|
||||
|
||||
public string AdapterId => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
/// 索引
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
public int InterfaceIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 网关
|
||||
@@ -47,7 +49,6 @@ namespace Netch.Models
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
|
||||
|
||||
public string DNS
|
||||
{
|
||||
get
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// TUN/TAP 适配器配置类
|
||||
/// </summary>
|
||||
public class TUNTAPConfig
|
||||
public class TUNConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 地址
|
||||
@@ -37,11 +37,6 @@ namespace Netch.Models
|
||||
/// 使用自定义 DNS 设置
|
||||
/// </summary>
|
||||
public bool UseCustomDNS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 使用Fake DNS
|
||||
/// </summary>
|
||||
public bool UseFakeDNS { get; set; } = false;
|
||||
}
|
||||
|
||||
public class KcpConfig
|
||||
@@ -280,7 +275,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// TUNTAP 适配器配置
|
||||
/// </summary>
|
||||
public TUNTAPConfig TUNTAP { get; set; } = new();
|
||||
public TUNConfig WinTUN { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 是否打开软件时更新订阅
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using Netch.Controllers;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class TapAdapter : IAdapter
|
||||
{
|
||||
public TapAdapter()
|
||||
{
|
||||
Index = -1;
|
||||
ComponentID = TUNTAP.GetComponentID() ?? throw new MessageException("TAP 适配器未安装");
|
||||
|
||||
// 根据 ComponentID 寻找 Tap适配器
|
||||
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.Id == ComponentID);
|
||||
Index = NetworkInterface.GetIPProperties().GetIPv4Properties().Index;
|
||||
Logging.Info($"TAP 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {Index}");
|
||||
}
|
||||
|
||||
public string ComponentID { get; }
|
||||
|
||||
public int Index { get; }
|
||||
|
||||
public IPAddress Gateway => IPAddress.Parse(Global.Settings.TUNTAP.Gateway);
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
}
|
||||
30
Netch/Models/TunAdapter.cs
Normal file
30
Netch/Models/TunAdapter.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class TunAdapter : IAdapter
|
||||
{
|
||||
private const string ComponentIdWintun = "wintun";
|
||||
|
||||
public TunAdapter()
|
||||
{
|
||||
AdapterId = AdapterUtils.GetAdapterId(ComponentIdWintun) ?? throw new Exception("wintun adapter not found");
|
||||
|
||||
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.Id == AdapterId);
|
||||
InterfaceIndex = NetworkInterface.GetIPProperties().GetIPv4Properties().Index;
|
||||
Logging.Info($"TAP 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
|
||||
}
|
||||
|
||||
public string AdapterId { get; set; }
|
||||
|
||||
public int InterfaceIndex { get; }
|
||||
|
||||
public IPAddress Gateway { get; } = IPAddress.Parse("100.64.0.1");
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
}
|
||||
@@ -73,10 +73,7 @@ namespace Netch.Servers.V2ray.Utils
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (Flags.SupportFakeDns && Global.Settings.TUNTAP.UseFakeDNS)
|
||||
directRuleObject.domain.Add("geosite:cn");
|
||||
else
|
||||
directRuleObject.ip.Add("geoip:cn");
|
||||
// directRuleObject.ip.Add("geoip:cn");
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
51
Netch/Utils/AdapterUtils.cs
Normal file
51
Netch/Utils/AdapterUtils.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class AdapterUtils
|
||||
{
|
||||
public const string NETWORK_KEY = @"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}";
|
||||
public const string ADAPTER_KEY = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}";
|
||||
|
||||
/// <summary>
|
||||
/// 获取 TUN/TAP 适配器名称
|
||||
/// </summary>
|
||||
/// <param name="componentId">适配器 ID</param>
|
||||
/// <returns>适配器名称</returns>
|
||||
public static string GetName(string componentId)
|
||||
{
|
||||
var registry = Registry.LocalMachine.OpenSubKey($"{NETWORK_KEY}\\{componentId}\\Connection");
|
||||
|
||||
return registry.GetValue("Name", "").ToString();
|
||||
}
|
||||
|
||||
public static string? GetAdapterId(params string[] componentIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var adaptersRegistry = Registry.LocalMachine.OpenSubKey(ADAPTER_KEY)!;
|
||||
|
||||
foreach (var keyName in adaptersRegistry.GetSubKeyNames().Where(s => s is not ("Configuration" or "Properties")))
|
||||
{
|
||||
var adapterRegistry = adaptersRegistry.OpenSubKey(keyName)!;
|
||||
var componentId = adapterRegistry.GetValue("ComponentId")?.ToString();
|
||||
if (componentId == null)
|
||||
continue;
|
||||
|
||||
if (componentIds.Contains(componentId))
|
||||
return (string) (adapterRegistry.GetValue("NetCfgInstanceId") ??
|
||||
throw new Exception("Tap adapter have no NetCfgInstanceId key"));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning(e.ToString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,16 +109,21 @@ namespace Netch.Utils
|
||||
|
||||
public static bool SkipServerController(Server server, Mode mode)
|
||||
{
|
||||
return mode.Type switch
|
||||
{
|
||||
0 => server switch
|
||||
{
|
||||
Socks5 => true,
|
||||
Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.RedirectorSS => true,
|
||||
_ => false
|
||||
},
|
||||
_ => false
|
||||
};
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 0:
|
||||
return server switch
|
||||
{
|
||||
Socks5 => true,
|
||||
Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.RedirectorSS => true,
|
||||
_ => false
|
||||
};
|
||||
case 1:
|
||||
case 2:
|
||||
return server is Socks5 ;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static IModeController? GetModeControllerByType(int type, out ushort? port, out string portName)
|
||||
@@ -133,7 +138,7 @@ namespace Netch.Utils
|
||||
return new NFController();
|
||||
case 1:
|
||||
case 2:
|
||||
return new TUNTAPController();
|
||||
return new TUNController();
|
||||
case 3:
|
||||
case 5:
|
||||
port = Global.Settings.HTTPLocalPort;
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32;
|
||||
using Netch.Controllers;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class TUNTAP
|
||||
{
|
||||
public static string TUNTAP_COMPONENT_ID_0901 = "tap0901";
|
||||
public static string TUNTAP_COMPONENT_ID_0801 = "tap0801";
|
||||
public static string NETWORK_KEY = @"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}";
|
||||
public static string ADAPTER_KEY = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}";
|
||||
|
||||
/// <summary>
|
||||
/// 获取 TUN/TAP 适配器 ID
|
||||
/// </summary>
|
||||
/// <returns>适配器 ID</returns>
|
||||
public static string? GetComponentID()
|
||||
{
|
||||
try
|
||||
{
|
||||
var adaptersRegistry = Registry.LocalMachine.OpenSubKey(ADAPTER_KEY)!;
|
||||
|
||||
foreach (var keyName in adaptersRegistry.GetSubKeyNames().Where(s => s is not ("Configuration" or "Properties")))
|
||||
{
|
||||
var adapterRegistry = adaptersRegistry.OpenSubKey(keyName)!;
|
||||
var componentId = adapterRegistry.GetValue("ComponentId")?.ToString();
|
||||
if (componentId == null)
|
||||
continue;
|
||||
|
||||
if (componentId == TUNTAP_COMPONENT_ID_0901 || componentId == TUNTAP_COMPONENT_ID_0801)
|
||||
return (string) (adapterRegistry.GetValue("NetCfgInstanceId") ??
|
||||
throw new Exception("Tap adapter have no NetCfgInstanceId key"));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning(e.ToString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 TUN/TAP 适配器名称
|
||||
/// </summary>
|
||||
/// <param name="componentId">适配器 ID</param>
|
||||
/// <returns>适配器名称</returns>
|
||||
public static string GetName(string componentId)
|
||||
{
|
||||
var registry = Registry.LocalMachine.OpenSubKey($"{NETWORK_KEY}\\{componentId}\\Connection");
|
||||
|
||||
return registry.GetValue("Name", "").ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建 TUN/TAP 适配器
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool Create()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载tap网卡
|
||||
/// </summary>
|
||||
public static void deltapall()
|
||||
{
|
||||
Logging.Info("卸载 TUN/TAP 适配器");
|
||||
var installProcess = new Process
|
||||
{StartInfo = {WindowStyle = ProcessWindowStyle.Hidden, FileName = Path.Combine("bin/tap-driver", "deltapall.bat")}};
|
||||
|
||||
installProcess.Start();
|
||||
installProcess.WaitForExit();
|
||||
installProcess.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安装tap网卡
|
||||
/// </summary>
|
||||
public static void AddTap()
|
||||
{
|
||||
Logging.Info("安装 TUN/TAP 适配器");
|
||||
//安装Tap Driver
|
||||
using var process = Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = Path.Combine("bin/tap-driver", "addtap.bat"),
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
})!;
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
Thread.Sleep(1000);
|
||||
if (GetComponentID() == null)
|
||||
throw new MessageException("TAP 驱动安装失败,找不到 ComponentID 注册表项");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,5 +222,38 @@ namespace Netch.Utils
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task ProcessRunHiddenAsync(string fileName, string? arguments = null, bool print = true)
|
||||
{
|
||||
var p = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = arguments,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
Verb = "runas",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine($"{fileName} {arguments}");
|
||||
#endif
|
||||
|
||||
p.Start();
|
||||
var output = await p.StandardOutput.ReadToEndAsync();
|
||||
var error = await p.StandardError.ReadToEndAsync();
|
||||
if (print)
|
||||
{
|
||||
Console.Write(output);
|
||||
Console.Write(error);
|
||||
}
|
||||
|
||||
p.WaitForExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
binaries
2
binaries
Submodule binaries updated: db78c29ec3...b22222857b
Reference in New Issue
Block a user