From 001452a3e509a165feaf2d39d99815c217fa5d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Thu, 16 Sep 2021 22:03:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0DnsClient=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.DomainResolve/DnsClient.cs | 66 ++++++++++++++++++++++ FastGithub.DomainResolve/DomainResolver.cs | 66 ++++------------------ 2 files changed, 77 insertions(+), 55 deletions(-) create mode 100644 FastGithub.DomainResolve/DnsClient.cs diff --git a/FastGithub.DomainResolve/DnsClient.cs b/FastGithub.DomainResolve/DnsClient.cs new file mode 100644 index 0000000..97ea09e --- /dev/null +++ b/FastGithub.DomainResolve/DnsClient.cs @@ -0,0 +1,66 @@ +using DNS.Client; +using DNS.Client.RequestResolver; +using DNS.Protocol; +using DNS.Protocol.ResourceRecords; +using System; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; + +namespace FastGithub.DomainResolve +{ + /// + /// DNS客户端 + /// + sealed class DnsClient + { + private readonly IPEndPoint dns; + private readonly IRequestResolver resolver; + private readonly TimeSpan timeout = TimeSpan.FromSeconds(5d); + + /// + /// DNS客户端 + /// + /// + /// + public DnsClient(IPEndPoint dns, bool forceTcp) + { + this.dns = dns; + this.resolver = forceTcp + ? new TcpRequestResolver(dns) + : new UdpRequestResolver(dns, new TcpRequestResolver(dns)); + } + + /// + /// 解析域名 + /// + /// + /// + /// + public async Task LookupAsync(string domain, CancellationToken cancellationToken = default) + { + var request = new Request + { + RecursionDesired = true, + OperationCode = OperationCode.Query + }; + request.Questions.Add(new Question(new Domain(domain), RecordType.A)); + var clientRequest = new ClientRequest(this.resolver, request); + + using var timeoutTokenSource = new CancellationTokenSource(this.timeout); + using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token); + var response = await clientRequest.Resolve(linkedTokenSource.Token); + return response.AnswerRecords.OfType().Select(item => item.IPAddress).ToArray(); + } + + /// + /// 转换为文本 + /// + /// + public override string ToString() + { + return this.dns.ToString(); + } + } +} diff --git a/FastGithub.DomainResolve/DomainResolver.cs b/FastGithub.DomainResolve/DomainResolver.cs index 7801c55..e34844f 100644 --- a/FastGithub.DomainResolve/DomainResolver.cs +++ b/FastGithub.DomainResolve/DomainResolver.cs @@ -1,8 +1,4 @@ -using DNS.Client; -using DNS.Client.RequestResolver; -using DNS.Protocol; -using DNS.Protocol.ResourceRecords; -using FastGithub.Configuration; +using FastGithub.Configuration; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -28,7 +24,6 @@ namespace FastGithub.DomainResolve private readonly DnscryptProxy dnscryptProxy; private readonly ILogger logger; - private readonly TimeSpan lookupTimeout = TimeSpan.FromSeconds(5d); private readonly TimeSpan connectTimeout = TimeSpan.FromSeconds(5d); private readonly TimeSpan disableIPExpiration = TimeSpan.FromMinutes(2d); @@ -151,8 +146,8 @@ namespace FastGithub.DomainResolve return null; } - var resolver = new RequestResolver(dns, forceTcp: false); - return await this.LookupAsync(resolver, domain, cancellationToken); + var dnsClient = new DnsClient(dns, forceTcp: false); + return await this.LookupAsync(dnsClient, domain, cancellationToken); } /// @@ -164,49 +159,38 @@ namespace FastGithub.DomainResolve /// private async Task LookupByFallbackAsync(DnsEndPoint domain, CancellationToken cancellationToken) { - var resolver = new RequestResolver(this.fallbackDns, forceTcp: true); - return await this.LookupAsync(resolver, domain, cancellationToken); + var dnsClient = new DnsClient(this.fallbackDns, forceTcp: true); + return await this.LookupAsync(dnsClient, domain, cancellationToken); } /// /// 查找ip /// - /// + /// /// /// /// - private async Task LookupAsync(IRequestResolver resolver, DnsEndPoint domain, CancellationToken cancellationToken) + private async Task LookupAsync(DnsClient dnsClient, DnsEndPoint domain, CancellationToken cancellationToken) { try { - var request = new Request - { - RecursionDesired = true, - OperationCode = OperationCode.Query - }; - request.Questions.Add(new Question(new Domain(domain.Host), RecordType.A)); - - using var timeoutTokenSource = new CancellationTokenSource(this.lookupTimeout); - using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token); - var response = await resolver.Resolve(request, linkedTokenSource.Token); - - var addresses = response.AnswerRecords.OfType().Select(item => item.IPAddress).ToArray(); + var addresses = await dnsClient.LookupAsync(domain.Host, cancellationToken); var address = await this.FindFastValueAsync(addresses, domain.Port, cancellationToken); if (address == null) { - this.logger.LogWarning($"dns({resolver})解析不到{domain.Host}可用的ip解析"); + this.logger.LogWarning($"dns({dnsClient})解析不到{domain.Host}可用的ip解析"); } else { - this.logger.LogInformation($"dns({resolver}): {domain.Host}->{address}"); + this.logger.LogInformation($"dns({dnsClient}): {domain.Host}->{address}"); } return address; } catch (Exception ex) { cancellationToken.ThrowIfCancellationRequested(); - this.logger.LogWarning($"dns({resolver})无法解析{domain.Host}:{ex.Message}"); + this.logger.LogWarning($"dns({dnsClient})无法解析{domain.Host}:{ex.Message}"); return default; } } @@ -274,33 +258,5 @@ namespace FastGithub.DomainResolve return default; } } - - /// - /// 请求解析器 - /// - private class RequestResolver : IRequestResolver - { - private readonly IPEndPoint dns; - private readonly IRequestResolver resolver; - - public RequestResolver(IPEndPoint dns, bool forceTcp) - { - this.dns = dns; - this.resolver = forceTcp - ? new TcpRequestResolver(dns) - : new UdpRequestResolver(dns, new TcpRequestResolver(dns)); - } - - public Task Resolve(IRequest request, CancellationToken cancellationToken = default) - { - var clientRequest = new ClientRequest(this.resolver, request); - return clientRequest.Resolve(cancellationToken); - } - - public override string ToString() - { - return this.dns.ToString(); - } - } } }