From a080de6ca4d9332cf8eeabe73438f4618b3b4a85 Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Fri, 26 Mar 2021 17:50:57 +0800 Subject: [PATCH] replace eycorsican/go-tun2socks with aiocloud/tun2socks(WinTUN) --- .../{TUNTAPController.cs => TUNController.cs} | 176 ++++++++++-------- Netch/Flags.cs | 4 - Netch/Forms/MainForm.Designer.cs | 10 - Netch/Forms/MainForm.cs | 23 +-- Netch/Forms/SettingForm.Designer.cs | 17 +- Netch/Forms/SettingForm.cs | 34 ++-- Netch/Models/IAdapter.cs | 9 +- Netch/Models/OutboundAdapter.cs | 9 +- Netch/Models/Setting.cs | 9 +- Netch/Models/TapAdapter.cs | 30 --- Netch/Models/TunAdapter.cs | 30 +++ Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs | 5 +- Netch/Utils/AdapterUtils.cs | 51 +++++ Netch/Utils/ModeHelper.cs | 27 +-- Netch/Utils/TUNTAP.cs | 103 ---------- Netch/Utils/Utils.cs | 33 ++++ binaries | 2 +- 17 files changed, 262 insertions(+), 310 deletions(-) rename Netch/Controllers/{TUNTAPController.cs => TUNController.cs} (68%) delete mode 100644 Netch/Models/TapAdapter.cs create mode 100644 Netch/Models/TunAdapter.cs create mode 100644 Netch/Utils/AdapterUtils.cs delete mode 100644 Netch/Utils/TUNTAP.cs diff --git a/Netch/Controllers/TUNTAPController.cs b/Netch/Controllers/TUNController.cs similarity index 68% rename from Netch/Controllers/TUNTAPController.cs rename to Netch/Controllers/TUNController.cs index 084c5881..230c7cc6 100644 --- a/Netch/Controllers/TUNTAPController.cs +++ b/Netch/Controllers/TUNController.cs @@ -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 _directIPs = new(); @@ -26,9 +30,9 @@ namespace Netch.Controllers /// public DNSController DNSController = new(); - protected override IEnumerable StartedKeywords { get; set; } = new[] {"Running"}; + protected override IEnumerable StartedKeywords { get; set; } = new[] {"Started"}; - protected override IEnumerable StoppedKeywords { get; set; } = new[] {"failed", "invalid vconfig file"}; + protected override IEnumerable StoppedKeywords { get; set; } = new List(); 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 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 {"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 {"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; } - } - /// /// TUN/TAP停止 /// @@ -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(); } /// @@ -197,10 +161,16 @@ namespace Netch.Controllers /// 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 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 } } \ No newline at end of file diff --git a/Netch/Flags.cs b/Netch/Flags.cs index 1b5a445a..e6872ed7 100644 --- a/Netch/Flags.cs +++ b/Netch/Flags.cs @@ -7,10 +7,6 @@ namespace Netch { public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10; - private static readonly Lazy LazySupportFakeDns = new(() => new TUNTAPController().TestFakeDNS()); - - public static bool SupportFakeDns => LazySupportFakeDns.Value; - public static bool AlwaysShowNewVersionFound { get; set; } } } \ No newline at end of file diff --git a/Netch/Forms/MainForm.Designer.cs b/Netch/Forms/MainForm.Designer.cs index d8a8fa07..094641cc 100644 --- a/Netch/Forms/MainForm.Designer.cs +++ b/Netch/Forms/MainForm.Designer.cs @@ -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; diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index c7b973ca..dc5de0db 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -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; diff --git a/Netch/Forms/SettingForm.Designer.cs b/Netch/Forms/SettingForm.Designer.cs index c55a9c0f..6bc14419 100644 --- a/Netch/Forms/SettingForm.Designer.cs +++ b/Netch/Forms/SettingForm.Designer.cs @@ -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; diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index 20192e1d..93d85868 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -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"; } diff --git a/Netch/Models/IAdapter.cs b/Netch/Models/IAdapter.cs index f82dae8d..5f36fcfa 100644 --- a/Netch/Models/IAdapter.cs +++ b/Netch/Models/IAdapter.cs @@ -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; } } } \ No newline at end of file diff --git a/Netch/Models/OutboundAdapter.cs b/Netch/Models/OutboundAdapter.cs index 55f321fc..aea69f97 100644 --- a/Netch/Models/OutboundAdapter.cs +++ b/Netch/Models/OutboundAdapter.cs @@ -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(); + /// /// 索引 /// - public int Index { get; } + public int InterfaceIndex { get; } /// /// 网关 @@ -47,7 +49,6 @@ namespace Netch.Models public NetworkInterface NetworkInterface { get; } - public string DNS { get diff --git a/Netch/Models/Setting.cs b/Netch/Models/Setting.cs index 45840f38..7957dafa 100644 --- a/Netch/Models/Setting.cs +++ b/Netch/Models/Setting.cs @@ -6,7 +6,7 @@ namespace Netch.Models /// /// TUN/TAP 适配器配置类 /// - public class TUNTAPConfig + public class TUNConfig { /// /// 地址 @@ -37,11 +37,6 @@ namespace Netch.Models /// 使用自定义 DNS 设置 /// public bool UseCustomDNS { get; set; } = false; - - /// - /// 使用Fake DNS - /// - public bool UseFakeDNS { get; set; } = false; } public class KcpConfig @@ -280,7 +275,7 @@ namespace Netch.Models /// /// TUNTAP 适配器配置 /// - public TUNTAPConfig TUNTAP { get; set; } = new(); + public TUNConfig WinTUN { get; set; } = new(); /// /// 是否打开软件时更新订阅 diff --git a/Netch/Models/TapAdapter.cs b/Netch/Models/TapAdapter.cs deleted file mode 100644 index 196b789f..00000000 --- a/Netch/Models/TapAdapter.cs +++ /dev/null @@ -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; } - } -} \ No newline at end of file diff --git a/Netch/Models/TunAdapter.cs b/Netch/Models/TunAdapter.cs new file mode 100644 index 00000000..17c50bf5 --- /dev/null +++ b/Netch/Models/TunAdapter.cs @@ -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; } + } +} \ No newline at end of file diff --git a/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs b/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs index 5dfb7a7d..cdbb65f4 100644 --- a/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs +++ b/Netch/Servers/V2ray/Utils/V2rayConfigUtils.cs @@ -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: diff --git a/Netch/Utils/AdapterUtils.cs b/Netch/Utils/AdapterUtils.cs new file mode 100644 index 00000000..cb1b5df4 --- /dev/null +++ b/Netch/Utils/AdapterUtils.cs @@ -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}"; + + /// + /// 获取 TUN/TAP 适配器名称 + /// + /// 适配器 ID + /// 适配器名称 + 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; + } + } +} \ No newline at end of file diff --git a/Netch/Utils/ModeHelper.cs b/Netch/Utils/ModeHelper.cs index 11c47ff1..7cd750cd 100644 --- a/Netch/Utils/ModeHelper.cs +++ b/Netch/Utils/ModeHelper.cs @@ -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; diff --git a/Netch/Utils/TUNTAP.cs b/Netch/Utils/TUNTAP.cs deleted file mode 100644 index cce38550..00000000 --- a/Netch/Utils/TUNTAP.cs +++ /dev/null @@ -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}"; - - /// - /// 获取 TUN/TAP 适配器 ID - /// - /// 适配器 ID - 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; - } - - /// - /// 获取 TUN/TAP 适配器名称 - /// - /// 适配器 ID - /// 适配器名称 - public static string GetName(string componentId) - { - var registry = Registry.LocalMachine.OpenSubKey($"{NETWORK_KEY}\\{componentId}\\Connection"); - - return registry.GetValue("Name", "").ToString(); - } - - /// - /// 创建 TUN/TAP 适配器 - /// - /// - public static bool Create() - { - return false; - } - - /// - /// 卸载tap网卡 - /// - 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(); - } - - /// - /// 安装tap网卡 - /// - 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 注册表项"); - } - } -} \ No newline at end of file diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index 5bc6c944..eb771202 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -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(); + } } } \ No newline at end of file diff --git a/binaries b/binaries index db78c29e..b2222285 160000 --- a/binaries +++ b/binaries @@ -1 +1 @@ -Subproject commit db78c29ec3ab6920cb0abe12922fedc404ed85f9 +Subproject commit b22222857bc111d8c261642f4e38e83b615bd1ec