diff --git a/Netch/Controllers/TUNController.cs b/Netch/Controllers/TUNController.cs index 9d61ecb3..5ae3a559 100644 --- a/Netch/Controllers/TUNController.cs +++ b/Netch/Controllers/TUNController.cs @@ -26,6 +26,8 @@ namespace Netch.Controllers private IAdapter _tunAdapter = null!; private IPAddress _serverAddresses = null!; + private const string DummyDns = "6.6.6.6"; + public void Start(in Mode mode) { var server = MainController.Server!; @@ -88,10 +90,17 @@ namespace Netch.Controllers Init(); _tunAdapter = new TunAdapter(); + switch (mode.Type) + { + case 1 when Global.Settings.TUNTAP.ProxyDNS: + case 2: + _tunAdapter.NetworkInterface.SetDns(DummyDns); + break; + } NativeMethods.CreateUnicastIP(AddressFamily.InterNetwork, Global.Settings.TUNTAP.Address, - (byte)Utils.Utils.SubnetToCidr(Global.Settings.TUNTAP.Netmask), + (byte) Utils.Utils.SubnetToCidr(Global.Settings.TUNTAP.Netmask), _tunAdapter.InterfaceIndex); SetupRouteTable(mode); @@ -162,11 +171,15 @@ namespace Netch.Controllers if (Global.Settings.TUNTAP.ProxyDNS) { - Global.Logger.Info("代理 → 自定义 DNS"); - if (Global.Settings.TUNTAP.UseCustomDNS) - RouteAction(Action.Create, Global.Settings.TUNTAP.HijackDNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP); - else - RouteAction(Action.Create, $"{Global.Settings.AioDNS.OtherDNS}/32", RouteType.TUNTAP); + Global.Logger.Info("代理 → 占位 DNS"); + RouteAction(Action.Create, $"{DummyDns}/32", RouteType.TUNTAP); + + if (!Global.Settings.TUNTAP.UseCustomDNS) + { + Global.Logger.Info("代理 → AioDNS OtherDNS"); + var otherDns = Global.Settings.AioDNS.OtherDNS; + RouteAction(Action.Create, $"{otherDns[..otherDns.IndexOf(':')]}/32", RouteType.TUNTAP); + } } break; @@ -233,18 +246,18 @@ namespace Netch.Controllers return false; IAdapter adapter = routeType switch - { - RouteType.Outbound => _outboundAdapter, - RouteType.TUNTAP => _tunAdapter, - _ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null) - }; + { + RouteType.Outbound => _outboundAdapter, + RouteType.TUNTAP => _tunAdapter, + _ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null) + }; List ipList = routeType switch - { - RouteType.Outbound => _directIPs, - RouteType.TUNTAP => _proxyIPs, - _ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null) - }; + { + RouteType.Outbound => _directIPs, + RouteType.TUNTAP => _proxyIPs, + _ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null) + }; string gateway = adapter.Gateway.ToString(); var index = adapter.InterfaceIndex; @@ -255,13 +268,13 @@ namespace Netch.Controllers switch (action) { case Action.Create: - result = NativeMethods.CreateRoute(AddressFamily.InterNetwork, ip, (byte)cidr, gateway, index, metric); - if (result && record) + result = NativeMethods.CreateRoute(AddressFamily.InterNetwork, ip, (byte) cidr, gateway, index, metric); + if (record) ipList.Add(ipNetwork); break; case Action.Delete: - result = NativeMethods.DeleteRoute(AddressFamily.InterNetwork, ip, (byte)cidr, gateway, index, metric); + result = NativeMethods.DeleteRoute(AddressFamily.InterNetwork, ip, (byte) cidr, gateway, index, metric); break; default: throw new ArgumentOutOfRangeException(nameof(action), action, null); diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index 325d02cb..1a525705 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -44,6 +44,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Netch/Utils/NetworkInterfaceUtils.cs b/Netch/Utils/NetworkInterfaceUtils.cs new file mode 100644 index 00000000..70592707 --- /dev/null +++ b/Netch/Utils/NetworkInterfaceUtils.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; +using System.Management; +using System.Net.NetworkInformation; + +namespace Netch.Utils +{ + public static class NetworkInterfaceExtension + { + public static void SetDns(this NetworkInterface ni, string primaryDns, string? secondDns = null) + { + void VerifyDns(ref string s) + { + s = s.Trim(); + if (primaryDns.IsNullOrEmpty()) + throw new ArgumentException("DNS format invalid", nameof(primaryDns)); + } + + VerifyDns(ref primaryDns); + if (secondDns != null) + VerifyDns(ref primaryDns); + + var wmi = new ManagementClass("Win32_NetworkAdapterConfiguration"); + var mos = wmi.GetInstances().Cast(); + + var mo = mos.First(m => m["Description"].ToString() == ni.Description); + + var dns = new[] {primaryDns}; + if (secondDns != null) + dns = dns.Append(secondDns).ToArray(); + + var inPar = mo.GetMethodParameters("SetDNSServerSearchOrder"); + inPar["DNSServerSearchOrder"] = dns; + + mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null); + } + } +} \ No newline at end of file