using FastGithub.Configuration; using System.Collections.Generic; using System.Net; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace FastGithub.DomainResolve { /// /// 域名解析器 /// sealed class DomainResolver : IDomainResolver { private readonly DnscryptProxy dnscryptProxy; private readonly FastGithubConfig fastGithubConfig; private readonly DnsClient dnsClient; /// /// 域名解析器 /// /// /// /// public DomainResolver( DnscryptProxy dnscryptProxy, FastGithubConfig fastGithubConfig, DnsClient dnsClient) { this.dnscryptProxy = dnscryptProxy; this.fastGithubConfig = fastGithubConfig; this.dnsClient = dnsClient; } /// /// 解析ip /// /// 域名 /// /// public async Task ResolveAsync(string domain, CancellationToken cancellationToken = default) { await foreach (var address in this.ResolveAllAsync(domain, cancellationToken)) { return address; } throw new FastGithubException($"解析不到{domain}的IP"); } /// /// 解析域名 /// /// 域名 /// /// public async IAsyncEnumerable ResolveAllAsync(string domain, [EnumeratorCancellation] CancellationToken cancellationToken) { var hashSet = new HashSet(); foreach (var dns in this.GetDnsServers()) { foreach (var address in await this.dnsClient.LookupAsync(dns, domain, cancellationToken)) { if (hashSet.Add(address) == true) { yield return address; } } } } /// /// 获取dns服务 /// /// private IEnumerable GetDnsServers() { var cryptDns = this.dnscryptProxy.LocalEndPoint; if (cryptDns != null) { yield return cryptDns; yield return cryptDns; } foreach (var fallbackDns in this.fastGithubConfig.FallbackDns) { yield return fallbackDns; } } } }