using FastGithub.Configuration; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Runtime.InteropServices; using System.Runtime.Versioning; namespace FastGithub.Dns { /// /// 系统域名服务工具 /// static class SystemDnsUtil { /// /// www.baidu.com的ip /// private static readonly IPAddress www_baidu_com = IPAddress.Parse("183.232.231.172"); /// /// 刷新DNS缓存 /// [SupportedOSPlatform("windows")] [DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCache", SetLastError = true)] private static extern void DnsFlushResolverCache(); /// /// 刷新DNS缓存 /// public static void FlushResolverCache() { if (OperatingSystem.IsWindows()) { DnsFlushResolverCache(); } } /// /// 设置主dns /// /// /// public static void SetPrimitiveDns(IPAddress primitive) { var @interface = GetOutboundNetworkInterface(); if (@interface == null) { throw new FastGithubException($"找不到匹配的网络适配器来设置主DNS值:{primitive}"); } var dnsAddresses = @interface.GetIPProperties().DnsAddresses; if (primitive.Equals(dnsAddresses.FirstOrDefault()) == false) { var nameServers = dnsAddresses.Prepend(primitive); if (OperatingSystem.IsWindows()) { SetNameServers(@interface, nameServers); } else if (OperatingSystem.IsLinux()) { throw new FastGithubException($"不支持自动设置本机DNS,请手工添加{primitive}做为/etc/resolv.conf的第一条记录"); } else if (OperatingSystem.IsMacOS()) { throw new FastGithubException($"不支持自动设置本机DNS,请手工添加{primitive}做为连接网络的DNS的第一条记录"); } } } /// /// 移除主dns /// /// /// public static void RemovePrimitiveDns(IPAddress primitive) { var @interface = GetOutboundNetworkInterface(); if (@interface == null) { throw new FastGithubException($"找不到匹配的网络适配器来移除主DNS值:{primitive}"); } var dnsAddresses = @interface.GetIPProperties().DnsAddresses; if (primitive.Equals(dnsAddresses.FirstOrDefault())) { var nameServers = dnsAddresses.Skip(1); if (OperatingSystem.IsWindows()) { SetNameServers(@interface, nameServers); } } } /// /// 查找出口的网络适器 /// /// private static NetworkInterface? GetOutboundNetworkInterface() { var remoteEndPoint = new IPEndPoint(www_baidu_com, 443); var address = LocalMachine.GetLocalIPAddress(remoteEndPoint); if (address == null) { return default; } return NetworkInterface .GetAllNetworkInterfaces() .Where(item => item.GetIPProperties().UnicastAddresses.Any(a => a.Address.Equals(address))) .FirstOrDefault(); } /// /// 设置网口的dns /// /// /// [SupportedOSPlatform("windows")] private static void SetNameServers(NetworkInterface @interface, IEnumerable nameServers) { Netsh($@"interface ipv4 delete dns ""{@interface.Name}"" all"); foreach (var address in nameServers) { Netsh($@"interface ipv4 add dns ""{@interface.Name}"" {address} validate=no"); } static void Netsh(string arguments) { var netsh = new ProcessStartInfo { FileName = "netsh.exe", Arguments = arguments, CreateNoWindow = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden }; Process.Start(netsh)?.WaitForExit(); } } } }