From 8a5dcee4b218ec8cd72252cdde0241a33a92bf82 Mon Sep 17 00:00:00 2001 From: xljiulang <366193849@qq.com> Date: Wed, 16 Jun 2021 19:32:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0TTL=E6=A8=A1=E6=8B=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DnsServiceCollectionExtensions.cs | 3 +- FastGithub.Dns/FastGithub.Dns.csproj | 1 + FastGithub.Dns/GithubRequestResolver.cs | 45 +++++++++++++++++-- FastGithub.Scanner/GithubContextCollection.cs | 12 +++++ FastGithub.Scanner/GithubScanService.cs | 17 ++++--- FastGithub.Scanner/IGithubScanService.cs | 10 +++-- 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/FastGithub.Dns/DnsServiceCollectionExtensions.cs b/FastGithub.Dns/DnsServiceCollectionExtensions.cs index f8353a8..d0d9385 100644 --- a/FastGithub.Dns/DnsServiceCollectionExtensions.cs +++ b/FastGithub.Dns/DnsServiceCollectionExtensions.cs @@ -18,7 +18,8 @@ namespace FastGithub public static IServiceCollection AddGithubDns(this IServiceCollection services, IConfiguration configuration) { var assembly = typeof(DnsServiceCollectionExtensions).Assembly; - return services + return services + .AddMemoryCache() .AddServiceAndOptions(assembly, configuration) .AddHostedService() .AddGithubScanner(configuration); diff --git a/FastGithub.Dns/FastGithub.Dns.csproj b/FastGithub.Dns/FastGithub.Dns.csproj index 33f532d..ffa588f 100644 --- a/FastGithub.Dns/FastGithub.Dns.csproj +++ b/FastGithub.Dns/FastGithub.Dns.csproj @@ -7,6 +7,7 @@ + diff --git a/FastGithub.Dns/GithubRequestResolver.cs b/FastGithub.Dns/GithubRequestResolver.cs index 98e8c66..fcbac57 100644 --- a/FastGithub.Dns/GithubRequestResolver.cs +++ b/FastGithub.Dns/GithubRequestResolver.cs @@ -2,9 +2,12 @@ using DNS.Protocol; using DNS.Protocol.ResourceRecords; using FastGithub.Scanner; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using System; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; @@ -14,13 +17,17 @@ namespace FastGithub.Dns sealed class GithubRequestResolver : IRequestResolver { private readonly IGithubScanService githubScanService; + private readonly IMemoryCache memoryCache; private readonly ILogger logger; + private readonly TimeSpan TTL = TimeSpan.FromMinutes(10d); public GithubRequestResolver( IGithubScanService githubScanService, + IMemoryCache memoryCache, ILogger logger) { this.githubScanService = githubScanService; + this.memoryCache = memoryCache; this.logger = logger; } @@ -32,11 +39,11 @@ namespace FastGithub.Dns if (question != null && question.Type == RecordType.A) { var domain = question.Name.ToString(); - var fastAddress = this.githubScanService.FindFastAddress(domain); + var address = this.GetGithubAddress(domain, TTL); - if (fastAddress != null) + if (address != null) { - var record = new IPAddressResourceRecord(question.Name, fastAddress); + var record = new IPAddressResourceRecord(question.Name, address); response.AnswerRecords.Add(record); this.logger.LogInformation(record.ToString()); } @@ -44,5 +51,37 @@ namespace FastGithub.Dns return Task.FromResult(response); } + + /// + /// 模拟TTL + /// 如果ip可用,则10分钟内返回缓存的ip,防止客户端ip频繁切换 + /// + /// + /// + /// + private IPAddress? GetGithubAddress(string domain, TimeSpan ttl) + { + if (domain.Contains("github", StringComparison.OrdinalIgnoreCase) == false) + { + return default; + } + + var key = $"ttl:{domain}"; + if (this.memoryCache.TryGetValue(key, out var address)) + { + if (this.githubScanService.IsAvailable(domain, address)) + { + return address; + } + this.memoryCache.Remove(key); + } + + address = this.githubScanService.FindBestAddress(domain); + if (address != null) + { + this.memoryCache.Set(key, address, ttl); + } + return address; + } } } diff --git a/FastGithub.Scanner/GithubContextCollection.cs b/FastGithub.Scanner/GithubContextCollection.cs index 81ecee5..648c44a 100644 --- a/FastGithub.Scanner/GithubContextCollection.cs +++ b/FastGithub.Scanner/GithubContextCollection.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; @@ -22,6 +23,17 @@ namespace FastGithub.Scanner } } + + public bool TryGet(string domain, IPAddress address, [MaybeNullWhen(false)] out GithubContext context) + { + lock (this.syncRoot) + { + var target = new GithubContext(domain, address); + context = this.contextList.Find(item => item.Equals(target)); + return context != null; + } + } + public GithubContext[] ToArray() { lock (this.syncRoot) diff --git a/FastGithub.Scanner/GithubScanService.cs b/FastGithub.Scanner/GithubScanService.cs index c74e9d7..9446363 100644 --- a/FastGithub.Scanner/GithubScanService.cs +++ b/FastGithub.Scanner/GithubScanService.cs @@ -1,7 +1,6 @@ using FastGithub.Scanner.Middlewares; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using System; using System.Linq; using System.Net; using System.Threading; @@ -33,7 +32,7 @@ namespace FastGithub.Scanner .Use() .Use() .Use() - .Use() + .Use() .Build(); this.resultScanDelegate = pipelineBuilder @@ -41,7 +40,7 @@ namespace FastGithub.Scanner .Use() .Use() .Use() - .Use() + .Use() .Build(); } @@ -80,11 +79,15 @@ namespace FastGithub.Scanner this.logger.LogInformation("结果扫描结束"); } - public IPAddress? FindFastAddress(string domain) + public IPAddress? FindBestAddress(string domain) { - return domain.Contains("github", StringComparison.OrdinalIgnoreCase) - ? this.results.FindBestAddress(domain) - : default; + return this.results.FindBestAddress(domain); + } + + + public bool IsAvailable(string domain, IPAddress address) + { + return this.results.TryGet(domain, address, out var context) && context.Available; } } } diff --git a/FastGithub.Scanner/IGithubScanService.cs b/FastGithub.Scanner/IGithubScanService.cs index 44553a3..50b2a35 100644 --- a/FastGithub.Scanner/IGithubScanService.cs +++ b/FastGithub.Scanner/IGithubScanService.cs @@ -6,8 +6,12 @@ namespace FastGithub.Scanner { public interface IGithubScanService { - Task ScanAllAsync(CancellationToken cancellationToken = default); - Task ScanResultAsync(); - IPAddress? FindFastAddress(string domain); + Task ScanAllAsync(CancellationToken cancellationToken); + + Task ScanResultAsync(); + + bool IsAvailable(string domain, IPAddress address); + + IPAddress? FindBestAddress(string domain); } } \ No newline at end of file