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();
- }
- }
}
}