增加TTL模拟
This commit is contained in:
parent
46b7a9b01b
commit
8a5dcee4b2
@ -19,6 +19,7 @@ namespace FastGithub
|
|||||||
{
|
{
|
||||||
var assembly = typeof(DnsServiceCollectionExtensions).Assembly;
|
var assembly = typeof(DnsServiceCollectionExtensions).Assembly;
|
||||||
return services
|
return services
|
||||||
|
.AddMemoryCache()
|
||||||
.AddServiceAndOptions(assembly, configuration)
|
.AddServiceAndOptions(assembly, configuration)
|
||||||
.AddHostedService<DnsHostedService>()
|
.AddHostedService<DnsHostedService>()
|
||||||
.AddGithubScanner(configuration);
|
.AddGithubScanner(configuration);
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DNS" Version="6.1.0" />
|
<PackageReference Include="DNS" Version="6.1.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -2,9 +2,12 @@
|
|||||||
using DNS.Protocol;
|
using DNS.Protocol;
|
||||||
using DNS.Protocol.ResourceRecords;
|
using DNS.Protocol.ResourceRecords;
|
||||||
using FastGithub.Scanner;
|
using FastGithub.Scanner;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -14,13 +17,17 @@ namespace FastGithub.Dns
|
|||||||
sealed class GithubRequestResolver : IRequestResolver
|
sealed class GithubRequestResolver : IRequestResolver
|
||||||
{
|
{
|
||||||
private readonly IGithubScanService githubScanService;
|
private readonly IGithubScanService githubScanService;
|
||||||
|
private readonly IMemoryCache memoryCache;
|
||||||
private readonly ILogger<GithubRequestResolver> logger;
|
private readonly ILogger<GithubRequestResolver> logger;
|
||||||
|
private readonly TimeSpan TTL = TimeSpan.FromMinutes(10d);
|
||||||
|
|
||||||
public GithubRequestResolver(
|
public GithubRequestResolver(
|
||||||
IGithubScanService githubScanService,
|
IGithubScanService githubScanService,
|
||||||
|
IMemoryCache memoryCache,
|
||||||
ILogger<GithubRequestResolver> logger)
|
ILogger<GithubRequestResolver> logger)
|
||||||
{
|
{
|
||||||
this.githubScanService = githubScanService;
|
this.githubScanService = githubScanService;
|
||||||
|
this.memoryCache = memoryCache;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,11 +39,11 @@ namespace FastGithub.Dns
|
|||||||
if (question != null && question.Type == RecordType.A)
|
if (question != null && question.Type == RecordType.A)
|
||||||
{
|
{
|
||||||
var domain = question.Name.ToString();
|
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);
|
response.AnswerRecords.Add(record);
|
||||||
this.logger.LogInformation(record.ToString());
|
this.logger.LogInformation(record.ToString());
|
||||||
}
|
}
|
||||||
@ -44,5 +51,37 @@ namespace FastGithub.Dns
|
|||||||
|
|
||||||
return Task.FromResult<IResponse>(response);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
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()
|
public GithubContext[] ToArray()
|
||||||
{
|
{
|
||||||
lock (this.syncRoot)
|
lock (this.syncRoot)
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using FastGithub.Scanner.Middlewares;
|
using FastGithub.Scanner.Middlewares;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -80,11 +79,15 @@ namespace FastGithub.Scanner
|
|||||||
this.logger.LogInformation("结果扫描结束");
|
this.logger.LogInformation("结果扫描结束");
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPAddress? FindFastAddress(string domain)
|
public IPAddress? FindBestAddress(string domain)
|
||||||
{
|
{
|
||||||
return domain.Contains("github", StringComparison.OrdinalIgnoreCase)
|
return this.results.FindBestAddress(domain);
|
||||||
? this.results.FindBestAddress(domain)
|
}
|
||||||
: default;
|
|
||||||
|
|
||||||
|
public bool IsAvailable(string domain, IPAddress address)
|
||||||
|
{
|
||||||
|
return this.results.TryGet(domain, address, out var context) && context.Available;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,8 +6,12 @@ namespace FastGithub.Scanner
|
|||||||
{
|
{
|
||||||
public interface IGithubScanService
|
public interface IGithubScanService
|
||||||
{
|
{
|
||||||
Task ScanAllAsync(CancellationToken cancellationToken = default);
|
Task ScanAllAsync(CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task ScanResultAsync();
|
Task ScanResultAsync();
|
||||||
IPAddress? FindFastAddress(string domain);
|
|
||||||
|
bool IsAvailable(string domain, IPAddress address);
|
||||||
|
|
||||||
|
IPAddress? FindBestAddress(string domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user