增加TTL模拟

This commit is contained in:
xljiulang 2021-06-16 19:32:57 +08:00
parent 46b7a9b01b
commit 8a5dcee4b2
6 changed files with 74 additions and 14 deletions

View File

@ -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<DnsHostedService>()
.AddGithubScanner(configuration);

View File

@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="DNS" Version="6.1.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -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<GithubRequestResolver> logger;
private readonly TimeSpan TTL = TimeSpan.FromMinutes(10d);
public GithubRequestResolver(
IGithubScanService githubScanService,
IMemoryCache memoryCache,
ILogger<GithubRequestResolver> 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<IResponse>(response);
}
/// <summary>
/// 模拟TTL
/// 如果ip可用则10分钟内返回缓存的ip防止客户端ip频繁切换
/// </summary>
/// <param name="domain"></param>
/// <param name="ttl"></param>
/// <returns></returns>
private IPAddress? GetGithubAddress(string domain, TimeSpan ttl)
{
if (domain.Contains("github", StringComparison.OrdinalIgnoreCase) == false)
{
return default;
}
var key = $"ttl:{domain}";
if (this.memoryCache.TryGetValue<IPAddress>(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;
}
}
}

View File

@ -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)

View File

@ -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<ScanOkLogMiddleware>()
.Use<StatisticsMiddleware>()
.Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Build();
this.resultScanDelegate = pipelineBuilder
@ -41,7 +40,7 @@ namespace FastGithub.Scanner
.Use<ScanOkLogMiddleware>()
.Use<StatisticsMiddleware>()
.Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>()
.Use<HttpsScanMiddleware>()
.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;
}
}
}

View File

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