From f6554a3b217ccb3c19ffc90ac6674fcfd916da02 Mon Sep 17 00:00:00 2001 From: Aigio Liu Date: Sat, 16 Sep 2023 12:20:25 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20IDnsAnalysisService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Net/DnsAnalysisServiceImpl.cs | 24 +-- .../Net/DnsAnalysisServiceSwitchImpl.cs | 138 ++---------------- .../Net/DnsDohAnalysisService.cs | 121 +++++++-------- .../Net/IDnsAnalysisService.Constants.cs | 2 +- .../Services/Net/IDnsAnalysisService.cs | 19 +-- 5 files changed, 75 insertions(+), 229 deletions(-) diff --git a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceImpl.cs b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceImpl.cs index 390b781ae..4f68042ad 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceImpl.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceImpl.cs @@ -5,9 +5,9 @@ using static BD.WTTS.Services.IDnsAnalysisService; // ReSharper disable once CheckNamespace namespace BD.WTTS.Services.Implementation; -sealed class DnsAnalysisServiceImpl : IDnsAnalysisService +sealed class DnsAnalysisServiceImpl { - static readonly LookupClient lookupClient = new(); + readonly LookupClient lookupClient = new(); public async Task AnalysisHostnameTimeAsync(string url, CancellationToken cancellationToken = default) { @@ -24,7 +24,7 @@ sealed class DnsAnalysisServiceImpl : IDnsAnalysisService return 0; } - public static IEnumerable? GetPingHostNameData(string url) + public IEnumerable? GetPingHostNameData(string url) { if (!string.IsNullOrEmpty(url)) { @@ -119,11 +119,18 @@ sealed class DnsAnalysisServiceImpl : IDnsAnalysisService { Retries = 1, Timeout = TimeSpan.FromSeconds(1), - UseCache = false + UseCache = false, }; var client = new LookupClient(options); - var response = await client.QueryServerAsync(new[] { IPAddress.Parse(PrimaryDNS_IPV6_Ali) }, IPV6_TESTDOMAIN, QueryType.AAAA, QueryClass.IN); - if (response.Answers.AaaaRecords().Any(s => s.Address.Equals(IPAddress.Parse(IPV6_TESTDOMAIN_SUCCESS)))) + var response = await client.QueryServerAsync( + new[] { + IPAddress.Parse(PrimaryDNS_IPV6_Ali), + }, + IPV6_TESTDOMAIN, + QueryType.AAAA, + QueryClass.IN); + if (response.Answers.AaaaRecords().Any(s => + s.Address.Equals(IPAddress.Parse(IPV6_TESTDOMAIN_SUCCESS)))) { return true; } @@ -133,9 +140,4 @@ sealed class DnsAnalysisServiceImpl : IDnsAnalysisService } return false; } - - public Task GetHostIpv6AddresAsync() - { - return Task.FromResult(null); - } } \ No newline at end of file diff --git a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceSwitchImpl.cs b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceSwitchImpl.cs index 0797e6732..055f80212 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceSwitchImpl.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsAnalysisServiceSwitchImpl.cs @@ -3,8 +3,8 @@ namespace BD.WTTS.Services.Implementation; sealed class DnsAnalysisServiceSwitchImpl : IDnsAnalysisService { - readonly IDnsAnalysisService dnsAnalysisServiceImpl; - readonly IDnsAnalysisService dnsDohAnalysisService; + readonly DnsAnalysisServiceImpl dnsAnalysisServiceImpl; + readonly DnsDohAnalysisService dnsDohAnalysisService; readonly IReverseProxySettings settings; public DnsAnalysisServiceSwitchImpl( @@ -17,94 +17,17 @@ sealed class DnsAnalysisServiceSwitchImpl : IDnsAnalysisService this.dnsDohAnalysisService = dnsDohAnalysisService; } - public async Task PingHostnameAsync(string url) - { - long r; - if (settings.UseDoh) - { - r = await dnsAnalysisServiceImpl.PingHostnameAsync(url); - } - else - { - r = await dnsDohAnalysisService.PingHostnameAsync(url); - } - return r; - } - public async Task AnalysisHostnameTimeAsync(string url, CancellationToken cancellationToken = default) { int r; if (settings.UseDoh) { - var dohAddres = settings.CustomDohAddres; - if (!string.IsNullOrWhiteSpace(dohAddres)) - { - r = await dnsAnalysisServiceImpl.AnalysisHostnameTimeByDohAddresAsync(dohAddres, url, cancellationToken); - } - else - { - r = await dnsAnalysisServiceImpl.AnalysisHostnameTimeAsync(url, cancellationToken); - } + r = await dnsDohAnalysisService.DohAnalysisHostnameTimeAsync( + settings.CustomDohAddres, url, cancellationToken); } else { - r = await dnsDohAnalysisService.AnalysisHostnameTimeAsync(url, cancellationToken); - } - return r; - } - - public async Task AnalysisHostnameTimeByDohAddresAsync(string dohAddres, string url, CancellationToken cancellationToken = default) - { - int r; - if (settings.UseDoh) - { - r = await dnsAnalysisServiceImpl.AnalysisHostnameTimeByDohAddresAsync(dohAddres, url, cancellationToken); - } - else - { - r = await dnsDohAnalysisService.AnalysisHostnameTimeByDohAddresAsync(dohAddres, url, cancellationToken); - } - return r; - } - - public IAsyncEnumerable AnalysisDomainIpAsync(string hostNameOrAddress, bool isIPv6, CancellationToken cancellationToken = default) - { - IAsyncEnumerable r; - if (settings.UseDoh) - { - r = dnsAnalysisServiceImpl.AnalysisDomainIpAsync(hostNameOrAddress, isIPv6, cancellationToken); - } - else - { - r = dnsDohAnalysisService.AnalysisDomainIpAsync(hostNameOrAddress, isIPv6, cancellationToken); - } - return r; - } - - public IAsyncEnumerable AnalysisDomainIpAsync(string hostNameOrAddress, CancellationToken cancellationToken = default) - { - IAsyncEnumerable r; - if (settings.UseDoh) - { - r = dnsAnalysisServiceImpl.AnalysisDomainIpAsync(hostNameOrAddress, cancellationToken); - } - else - { - r = dnsDohAnalysisService.AnalysisDomainIpAsync(hostNameOrAddress, cancellationToken); - } - return r; - } - - public IAsyncEnumerable AnalysisDomainIpAsync(string hostNameOrAddress, IPAddress[]? dnsServers, CancellationToken cancellationToken = default) - { - IAsyncEnumerable r; - if (settings.UseDoh) - { - r = dnsAnalysisServiceImpl.AnalysisDomainIpAsync(hostNameOrAddress, dnsServers, cancellationToken); - } - else - { - r = dnsDohAnalysisService.AnalysisDomainIpAsync(hostNameOrAddress, dnsServers, cancellationToken); + r = await dnsAnalysisServiceImpl.AnalysisHostnameTimeAsync(url, cancellationToken); } return r; } @@ -114,68 +37,25 @@ sealed class DnsAnalysisServiceSwitchImpl : IDnsAnalysisService IAsyncEnumerable r; if (settings.UseDoh) { - r = dnsAnalysisServiceImpl.AnalysisDomainIpAsync(hostNameOrAddress, dnsServers, isIPv6, cancellationToken); + r = dnsDohAnalysisService.DohAnalysisDomainIpAsync(settings.CustomDohAddres, hostNameOrAddress, isIPv6, true, cancellationToken); } else { - r = dnsDohAnalysisService.AnalysisDomainIpAsync(hostNameOrAddress, dnsServers, isIPv6, cancellationToken); - } - return r; - } - public IAsyncEnumerable? DohAnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, bool isIPv6, CancellationToken cancellationToken = default) - { - IAsyncEnumerable? r; - if (settings.UseDoh) - { - r = dnsAnalysisServiceImpl.DohAnalysisDomainIpAsync(hostNameOrAddress, dnsServers, isIPv6, cancellationToken); - } - else - { - r = dnsDohAnalysisService.DohAnalysisDomainIpAsync(hostNameOrAddress, dnsServers, isIPv6, cancellationToken); + r = dnsAnalysisServiceImpl.AnalysisDomainIpAsync(hostNameOrAddress, dnsServers, isIPv6, cancellationToken); } return r; } public async Task GetHostByIPAddressAsync(IPAddress ip) { - string? r; - if (settings.UseDoh) - { - r = await dnsAnalysisServiceImpl.GetHostByIPAddressAsync(ip); - } - else - { - r = await dnsDohAnalysisService.GetHostByIPAddressAsync(ip); - } + var r = await dnsAnalysisServiceImpl.GetHostByIPAddressAsync(ip); return r; } public async Task GetIsIpv6SupportAsync() { - bool r; - if (settings.UseDoh) - { - r = await dnsAnalysisServiceImpl.GetIsIpv6SupportAsync(); - } - else - { - r = await dnsDohAnalysisService.GetIsIpv6SupportAsync(); - } - return r; - } - - public async Task GetHostIpv6AddresAsync() - { - IPAddress? r; - if (settings.UseDoh) - { - r = await dnsAnalysisServiceImpl.GetHostIpv6AddresAsync(); - } - else - { - r = await dnsDohAnalysisService.GetHostIpv6AddresAsync(); - } + var r = await dnsAnalysisServiceImpl.GetIsIpv6SupportAsync(); return r; } } diff --git a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsDohAnalysisService.cs b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsDohAnalysisService.cs index 3b0b0060e..3c4c70825 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsDohAnalysisService.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Net/DnsDohAnalysisService.cs @@ -7,13 +7,13 @@ using DnsQueryType = Ae.Dns.Protocol.Enums.DnsQueryType; // ReSharper disable once CheckNamespace namespace BD.WTTS.Services.Implementation; -sealed class DnsDohAnalysisService : GeneralHttpClientFactory, IDnsAnalysisService +sealed class DnsDohAnalysisService : GeneralHttpClientFactory { const string TAG = "DnsDohAnalysisS"; protected override string? DefaultClientName => TAG; - private readonly ConcurrentDictionary> Cache = new(); + private readonly ConcurrentDictionary<(Uri dohAddresUri, string hostNameOrAddressWithQueryType), List> Cache = new(); public DnsDohAnalysisService( ILoggerFactory loggerFactory, @@ -23,28 +23,32 @@ sealed class DnsDohAnalysisService : GeneralHttpClientFactory, IDnsAnalysisServi { } - const string DefaultDohAddres = Dnspod_DohAddres; + public const string DefaultDohAddres = Dnspod_DohAddres; - public async Task AnalysisHostnameTimeAsync(string url, CancellationToken cancellationToken = default) + static Uri GetDohAddres(string? dohAddres) { - var r = await AnalysisHostnameTimeByDohAddresAsync(DefaultDohAddres, url, cancellationToken); - return r; + if (string.IsNullOrWhiteSpace(dohAddres)) + return new Uri(DefaultDohAddres); + + Uri dohAddresUri; + try + { + dohAddresUri = new Uri(dohAddres); + } + catch + { + dohAddresUri = new Uri(DefaultDohAddres); + } + return dohAddresUri; } - public async Task AnalysisHostnameTimeByDohAddresAsync(string dohAddres, string url, CancellationToken cancellationToken = default) + public async Task DohAnalysisHostnameTimeAsync(string? dohAddres, string url, CancellationToken cancellationToken = default) { if (!string.IsNullOrEmpty(url)) { - const string clientName = TAG + "_" + nameof(AnalysisHostnameTimeAsync); + const string clientName = TAG + "_" + nameof(DohAnalysisHostnameTimeAsync); var client = CreateClient(clientName, HttpHandlerCategory.Default); - try - { - client.BaseAddress = new Uri(dohAddres); - } - catch - { - client.BaseAddress = new Uri(DefaultDohAddres); - } + client.BaseAddress = GetDohAddres(dohAddres); IDnsClient dnsClient = new DnsHttpClient(client); var queryType = DnsQueryType.A; @@ -57,55 +61,33 @@ sealed class DnsDohAnalysisService : GeneralHttpClientFactory, IDnsAnalysisServi return 0; } - /// - /// 解析域名 IP 地址 - /// - /// 要解析的主机名或 IP 地址 - /// - /// - /// - public IAsyncEnumerable AnalysisDomainIpAsync(string hostNameOrAddress, bool isIPv6, bool useCache = true, CancellationToken cancellationToken = default) - => DohAnalysisDomainIpAsync(hostNameOrAddress, default, isIPv6, useCache, cancellationToken); - - /// - /// 解析域名 IP 地址 - /// - /// 要解析的主机名或 IP 地址 - /// - /// - public IAsyncEnumerable AnalysisDomainIpAsync(string hostNameOrAddress, bool useCache = true, CancellationToken cancellationToken = default) - => DohAnalysisDomainIpAsync(hostNameOrAddress, default, default, useCache, cancellationToken); - - /// - /// 解析域名 IP 地址 - /// - /// 要解析的主机名或 IP 地址 - /// 自定义 DNS 服务器,可选的值有 , , , , - /// - /// - public IAsyncEnumerable AnalysisDomainIpAsync(string hostNameOrAddress, Uri[]? dnsServers, bool useCache = true, CancellationToken cancellationToken = default) - => DohAnalysisDomainIpAsync(hostNameOrAddress, dnsServers, default, useCache, cancellationToken); - /// /// DOH 解析域名 IP 地址 /// /// 要解析的主机名或 IP 地址 - /// 自定义 DNS 服务器,可选的值有 , , , , /// /// /// - public async IAsyncEnumerable DohAnalysisDomainIpAsync(string hostNameOrAddress, Uri[]? dotServers, bool isIPv6, bool useCache = true, [EnumeratorCancellation] CancellationToken cancellationToken = default) + public async IAsyncEnumerable DohAnalysisDomainIpAsync(string? dohAddres, string hostNameOrAddress, bool isIPv6, bool useCache = true, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var queryType = isIPv6 ? DnsQueryType.AAAA : DnsQueryType.A; + var dohAddresUri = GetDohAddres(dohAddres); - var current_dns_list = Enumerable.Empty(); + (Uri dohAddresUri, string hostNameOrAddressWithQueryType) cacheKey = useCache ? GetCacheKey() : default; + (Uri dohAddresUri, string hostNameOrAddressWithQueryType) GetCacheKey() + { + var hostNameOrAddressWithQueryType = string.Concat(hostNameOrAddress, ":", (short)queryType); + var cacheKey = (dohAddresUri, hostNameOrAddressWithQueryType); + return cacheKey; + } + + var current_dns_list = new List(); if (useCache) { - var cacheKey = string.Concat(hostNameOrAddress, ":", (short)queryType); if (Cache.TryGetValue(cacheKey, out var dns_list)) { current_dns_list = dns_list.Where(x => x.TimeToLive > DateTime.Now.ToUnixTimeSeconds()).ToList(); - Cache[cacheKey] = current_dns_list.ToList(); + Cache[cacheKey] = current_dns_list; foreach (var x in current_dns_list) { if (x.Resource is DnsIpAddressResource ipAddressResource) @@ -118,41 +100,38 @@ sealed class DnsDohAnalysisService : GeneralHttpClientFactory, IDnsAnalysisServi if (!current_dns_list.Any()) { - if (dotServers == null || dotServers.Length <= 0) - dotServers = new Uri[] { new Uri(DNS_Ali_DohAddres) }; try { var query = DnsQueryFactory.CreateQuery(hostNameOrAddress, queryType); - - IDnsClient dnsClient; HttpClient httpClient; - foreach (var dot_server in dotServers) - { - const string clientName = TAG + "_" + nameof(DohAnalysisDomainIpAsync); - httpClient = CreateClient(clientName, HttpHandlerCategory.Default); - httpClient.BaseAddress = dot_server; - dnsClient = new DnsHttpClient(httpClient); + const string clientName = TAG + "_" + nameof(DohAnalysisDomainIpAsync); + httpClient = CreateClient(clientName, HttpHandlerCategory.Default); + httpClient.BaseAddress = dohAddresUri; + using var dnsClient = new DnsHttpClient(httpClient); - var answer = await dnsClient.Query(query, cancellationToken); - if (useCache) - current_dns_list = current_dns_list.Concat(answer.Answers); - foreach (var x in answer.Answers) + var answer = await dnsClient.Query(query, cancellationToken); + if (useCache) + { + current_dns_list.AddRange(answer.Answers); + } + foreach (var x in answer.Answers) + { + if (x.Resource is DnsIpAddressResource ipAddressResource) { - if (x.Resource is DnsIpAddressResource ipAddressResource) - { - yield return ipAddressResource.IPAddress; - } + yield return ipAddressResource.IPAddress; } - dnsClient.Dispose(); } } finally { if (useCache) { - var cacheKey = string.Concat(hostNameOrAddress, ":", (short)queryType); Cache[cacheKey] = current_dns_list - .Select(item => { item.TimeToLive += (uint)DateTime.Now.ToUnixTimeSeconds(); return item; }) + .Select(item => + { + item.TimeToLive += (uint)DateTime.Now.ToUnixTimeSeconds(); + return item; + }) .ToList(); } } diff --git a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.Constants.cs b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.Constants.cs index 3b01e87ff..2dc9eb76f 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.Constants.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.Constants.cs @@ -21,7 +21,7 @@ public partial interface IDnsAnalysisService // 公共常量定义 const string DohAddres_360 = "https://doh.360.cn/dns-query"; const string TUNA_DohAddres = "https://101.6.6.6:8443/dns-query"; - protected const string PrimaryDNS_IPV6_Ali = "2400:3200::1"; + const string PrimaryDNS_IPV6_Ali = "2400:3200::1"; const string PrimaryDNS_Ali = "223.5.5.5"; const string SecondaryDNS_Ali = "223.6.6.6"; diff --git a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.cs b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.cs index aafae34d5..a5f03069a 100644 --- a/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.cs +++ b/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services/Net/IDnsAnalysisService.cs @@ -7,8 +7,8 @@ partial interface IDnsAnalysisService // 服务函数与 protected 定义 { protected const string TAG = "DnsAnalysisS"; - protected const string IPV6_TESTDOMAIN = "ipv6.rmbgame.net"; - protected const string IPV6_TESTDOMAIN_SUCCESS = PrimaryDNS_IPV6_Ali; + const string IPV6_TESTDOMAIN = "ipv6.rmbgame.net"; + const string IPV6_TESTDOMAIN_SUCCESS = PrimaryDNS_IPV6_Ali; async Task PingHostnameAsync(string url) { @@ -23,8 +23,6 @@ partial interface IDnsAnalysisService // 服务函数与 protected 定义 Task AnalysisHostnameTimeAsync(string url, CancellationToken cancellationToken = default); - Task AnalysisHostnameTimeByDohAddresAsync(string dohAddres, string url, CancellationToken cancellationToken = default) => AnalysisHostnameTimeAsync(url, cancellationToken); - /// /// 解析域名 IP 地址 /// @@ -76,19 +74,6 @@ partial interface IDnsAnalysisService // 服务函数与 protected 定义 } } - /// - /// DOH 解析域名 IP 地址 - /// - /// 要解析的主机名或 IP 地址 - /// 自定义 DNS 服务器,可选的值有 , , , , - /// - /// - /// - IAsyncEnumerable? DohAnalysisDomainIpAsync(string hostNameOrAddress, string? dnsServers, bool isIPv6, CancellationToken cancellationToken = default) - { - return null; - } - async Task GetHostByIPAddressAsync(IPAddress ip) { var hostEntry = await Dns.GetHostEntryAsync(ip);