优化DnscryptProxy初始化逻辑
This commit is contained in:
parent
bec32d2e35
commit
d4f9172574
@ -25,16 +25,7 @@ namespace FastGithub.DomainResolve
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取监听的节点
|
/// 获取监听的节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IPEndPoint EndPoint { get; }
|
public IPEndPoint? LocalEndPoint { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// DnscryptProxy服务
|
|
||||||
/// </summary>
|
|
||||||
public DnscryptProxy()
|
|
||||||
{
|
|
||||||
var port = LocalMachine.GetAvailablePort(IPAddress.Loopback.AddressFamily, min: 5353);
|
|
||||||
this.EndPoint = new IPEndPoint(IPAddress.Loopback, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 启动dnscrypt-proxy
|
/// 启动dnscrypt-proxy
|
||||||
@ -44,7 +35,10 @@ namespace FastGithub.DomainResolve
|
|||||||
public async Task StartAsync(CancellationToken cancellationToken)
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tomlPath = Path.Combine(PATH, $"{NAME}.toml");
|
var tomlPath = Path.Combine(PATH, $"{NAME}.toml");
|
||||||
await TomlUtil.SetListensAsync(tomlPath, this.EndPoint, cancellationToken);
|
var port = LocalMachine.GetAvailablePort(IPAddress.Loopback.AddressFamily, min: 5353);
|
||||||
|
var localEndPoint = new IPEndPoint(IPAddress.Loopback, port);
|
||||||
|
|
||||||
|
await TomlUtil.SetListensAsync(tomlPath, localEndPoint, cancellationToken);
|
||||||
await TomlUtil.SetEdnsClientSubnetAsync(tomlPath, cancellationToken);
|
await TomlUtil.SetEdnsClientSubnetAsync(tomlPath, cancellationToken);
|
||||||
|
|
||||||
foreach (var process in Process.GetProcessesByName(NAME))
|
foreach (var process in Process.GetProcessesByName(NAME))
|
||||||
@ -64,6 +58,23 @@ namespace FastGithub.DomainResolve
|
|||||||
{
|
{
|
||||||
this.process = StartDnscryptProxy(string.Empty);
|
this.process = StartDnscryptProxy(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.process != null)
|
||||||
|
{
|
||||||
|
this.LocalEndPoint = localEndPoint;
|
||||||
|
this.process.EnableRaisingEvents = true;
|
||||||
|
this.process.Exited += Process_Exited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 进程退出时
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void Process_Exited(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.LocalEndPoint = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -81,6 +92,7 @@ namespace FastGithub.DomainResolve
|
|||||||
{
|
{
|
||||||
this.process.Kill();
|
this.process.Kill();
|
||||||
}
|
}
|
||||||
|
this.LocalEndPoint = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -53,16 +53,16 @@ namespace FastGithub.DomainResolve
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析域名
|
/// 解析域名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="endPoint"></param>
|
/// <param name="domain"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<IPAddress> ResolveAsync(DnsEndPoint endPoint, CancellationToken cancellationToken = default)
|
public async Task<IPAddress> ResolveAsync(DnsEndPoint domain, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var semaphore = this.semaphoreSlims.GetOrAdd(endPoint, _ => new SemaphoreSlim(1, 1));
|
var semaphore = this.semaphoreSlims.GetOrAdd(domain, _ => new SemaphoreSlim(1, 1));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await semaphore.WaitAsync(cancellationToken);
|
await semaphore.WaitAsync(cancellationToken);
|
||||||
return await this.LookupAsync(endPoint, cancellationToken);
|
return await this.LookupAsync(domain, cancellationToken);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -73,28 +73,31 @@ namespace FastGithub.DomainResolve
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找ip
|
/// 查找ip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target"></param>
|
/// <param name="domain"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<IPAddress> LookupAsync(DnsEndPoint target, CancellationToken cancellationToken)
|
private async Task<IPAddress> LookupAsync(DnsEndPoint domain, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (this.memoryCache.TryGetValue<IPAddress>(target, out var address))
|
if (this.memoryCache.TryGetValue<IPAddress>(domain, out var address))
|
||||||
{
|
{
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
var expiration = this.dnscryptExpiration;
|
var expiration = this.dnscryptExpiration;
|
||||||
address = await this.LookupCoreAsync(this.dnscryptProxy.EndPoint, target, cancellationToken);
|
if (this.dnscryptProxy.LocalEndPoint != null)
|
||||||
|
|
||||||
if (address == null)
|
|
||||||
{
|
{
|
||||||
expiration = this.fallbackExpiration;
|
address = await this.LookupCoreAsync(this.dnscryptProxy.LocalEndPoint, domain, cancellationToken);
|
||||||
address = await this.FallbackLookupAsync(target, cancellationToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address == null)
|
if (address == null)
|
||||||
{
|
{
|
||||||
throw new FastGithubException($"当前解析不到{target.Host}可用的ip,请刷新重试");
|
expiration = this.fallbackExpiration;
|
||||||
|
address = await this.FallbackLookupAsync(domain, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address == null)
|
||||||
|
{
|
||||||
|
throw new FastGithubException($"当前解析不到{domain.Host}可用的ip,请刷新重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 往往是被污染的dns
|
// 往往是被污染的dns
|
||||||
@ -103,22 +106,22 @@ namespace FastGithub.DomainResolve
|
|||||||
expiration = this.loopbackExpiration;
|
expiration = this.loopbackExpiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.LogInformation($"[{target.Host}->{address}]");
|
this.logger.LogInformation($"[{domain.Host}->{address}]");
|
||||||
this.memoryCache.Set(target, address, expiration);
|
this.memoryCache.Set(domain, address, expiration);
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 回退查找ip
|
/// 回退查找ip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target"></param>
|
/// <param name="domain"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<IPAddress?> FallbackLookupAsync(DnsEndPoint target, CancellationToken cancellationToken)
|
private async Task<IPAddress?> FallbackLookupAsync(DnsEndPoint domain, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
foreach (var dns in this.fastGithubConfig.FallbackDns)
|
foreach (var dns in this.fastGithubConfig.FallbackDns)
|
||||||
{
|
{
|
||||||
var address = await this.LookupCoreAsync(dns, target, cancellationToken);
|
var address = await this.LookupCoreAsync(dns, domain, cancellationToken);
|
||||||
if (address != null)
|
if (address != null)
|
||||||
{
|
{
|
||||||
return address;
|
return address;
|
||||||
@ -132,22 +135,22 @@ namespace FastGithub.DomainResolve
|
|||||||
/// 查找ip
|
/// 查找ip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dns"></param>
|
/// <param name="dns"></param>
|
||||||
/// <param name="target"></param>
|
/// <param name="domain"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<IPAddress?> LookupCoreAsync(IPEndPoint dns, DnsEndPoint target, CancellationToken cancellationToken)
|
private async Task<IPAddress?> LookupCoreAsync(IPEndPoint dns, DnsEndPoint domain, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var dnsClient = new DnsClient(dns);
|
var dnsClient = new DnsClient(dns);
|
||||||
using var timeoutTokenSource = new CancellationTokenSource(this.lookupTimeout);
|
using var timeoutTokenSource = new CancellationTokenSource(this.lookupTimeout);
|
||||||
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
|
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
|
||||||
var addresses = await dnsClient.Lookup(target.Host, RecordType.A, linkedTokenSource.Token);
|
var addresses = await dnsClient.Lookup(domain.Host, RecordType.A, linkedTokenSource.Token);
|
||||||
return await this.FindFastValueAsync(addresses, target.Port, cancellationToken);
|
return await this.FindFastValueAsync(addresses, domain.Port, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
this.logger.LogWarning($"dns({dns})无法解析{target.Host}:{ex.Message}");
|
this.logger.LogWarning($"dns({dns})无法解析{domain.Host}:{ex.Message}");
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,9 +12,9 @@ namespace FastGithub.DomainResolve
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析域名
|
/// 解析域名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target"></param>
|
/// <param name="domain"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IPAddress> ResolveAsync(DnsEndPoint target, CancellationToken cancellationToken = default);
|
Task<IPAddress> ResolveAsync(DnsEndPoint domain, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user