123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- 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
- {
- /// <summary>
- /// 系统域名服务工具
- /// </summary>
- static class SystemDnsUtil
- {
- /// <summary>
- /// 刷新DNS缓存
- /// </summary>
- [SupportedOSPlatform("windows")]
- [DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCache", SetLastError = true)]
- private static extern void DnsFlushResolverCache();
- /// <summary>
- /// 刷新DNS缓存
- /// </summary>
- public static void FlushResolverCache()
- {
- if (OperatingSystem.IsWindows())
- {
- DnsFlushResolverCache();
- }
- }
- /// <summary>
- /// 设置为主dns
- /// </summary>
- /// <exception cref="FastGithubException"></exception>
- public static void SetAsPrimitiveDns()
- {
- var @interface = GetOutboundNetworkInterface();
- if (@interface == null)
- {
- throw new FastGithubException($"找不到匹配的网络适配器来设置主DNS");
- }
- var dnsAddresses = @interface.GetIPProperties().DnsAddresses;
- var firstRecord = dnsAddresses.FirstOrDefault();
- if (firstRecord == null || LocalMachine.ContainsIPAddress(firstRecord) == false)
- {
- var primitive = IPAddress.Loopback;
- 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的第一条记录");
- }
- }
- }
- /// <summary>
- /// 从主dns移除
- /// </summary>
- /// <exception cref="FastGithubException"></exception>
- public static void RemoveFromPrimitiveDns()
- {
- var @interface = GetOutboundNetworkInterface();
- if (@interface == null)
- {
- throw new FastGithubException($"找不到匹配的网络适配器来移除主DNS");
- }
- var dnsAddresses = @interface.GetIPProperties().DnsAddresses;
- var firstRecord = dnsAddresses.FirstOrDefault();
- if (firstRecord != null && LocalMachine.ContainsIPAddress(firstRecord))
- {
- var nameServers = dnsAddresses.Skip(1);
- if (OperatingSystem.IsWindows())
- {
- SetNameServers(@interface, nameServers);
- }
- else if (OperatingSystem.IsLinux())
- {
- throw new FastGithubException($"不支持自动移除本机主DNS,请手工移除/etc/resolv.conf的第一条记录");
- }
- else if (OperatingSystem.IsMacOS())
- {
- throw new FastGithubException($"不支持自动移除本机主DNS,请手工移除连接网络的DNS的第一条记录");
- }
- }
- }
- /// <summary>
- /// 查找出口的网络适器
- /// </summary>
- /// <returns></returns>
- private static NetworkInterface? GetOutboundNetworkInterface()
- {
- var remoteEndPoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 53);
- 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();
- }
- /// <summary>
- /// 设置网口的dns
- /// </summary>
- /// <param name="interface"></param>
- /// <param name="nameServers"></param>
- [SupportedOSPlatform("windows")]
- private static void SetNameServers(NetworkInterface @interface, IEnumerable<IPAddress> 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();
- }
- }
- }
- }
|