diff --git a/FastGithub.DomainResolve/DnscryptProxy.cs b/FastGithub.DomainResolve/DnscryptProxy.cs
index a8f47c7..21889b8 100644
--- a/FastGithub.DomainResolve/DnscryptProxy.cs
+++ b/FastGithub.DomainResolve/DnscryptProxy.cs
@@ -25,16 +25,7 @@ namespace FastGithub.DomainResolve
///
/// 获取监听的节点
///
- public IPEndPoint EndPoint { get; }
-
- ///
- /// DnscryptProxy服务
- ///
- public DnscryptProxy()
- {
- var port = LocalMachine.GetAvailablePort(IPAddress.Loopback.AddressFamily, min: 5353);
- this.EndPoint = new IPEndPoint(IPAddress.Loopback, port);
- }
+ public IPEndPoint? LocalEndPoint { get; private set; }
///
/// 启动dnscrypt-proxy
@@ -44,7 +35,10 @@ namespace FastGithub.DomainResolve
public async Task StartAsync(CancellationToken cancellationToken)
{
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);
foreach (var process in Process.GetProcessesByName(NAME))
@@ -64,6 +58,23 @@ namespace FastGithub.DomainResolve
{
this.process = StartDnscryptProxy(string.Empty);
}
+
+ if (this.process != null)
+ {
+ this.LocalEndPoint = localEndPoint;
+ this.process.EnableRaisingEvents = true;
+ this.process.Exited += Process_Exited;
+ }
+ }
+
+ ///
+ /// 进程退出时
+ ///
+ ///
+ ///
+ private void Process_Exited(object? sender, EventArgs e)
+ {
+ this.LocalEndPoint = null;
}
///
@@ -81,6 +92,7 @@ namespace FastGithub.DomainResolve
{
this.process.Kill();
}
+ this.LocalEndPoint = null;
}
///
diff --git a/FastGithub.DomainResolve/DomainResolver.cs b/FastGithub.DomainResolve/DomainResolver.cs
index 60fdc06..2601817 100644
--- a/FastGithub.DomainResolve/DomainResolver.cs
+++ b/FastGithub.DomainResolve/DomainResolver.cs
@@ -53,16 +53,16 @@ namespace FastGithub.DomainResolve
///
/// 解析域名
///
- ///
+ ///
///
///
- public async Task ResolveAsync(DnsEndPoint endPoint, CancellationToken cancellationToken = default)
+ public async Task 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
{
await semaphore.WaitAsync(cancellationToken);
- return await this.LookupAsync(endPoint, cancellationToken);
+ return await this.LookupAsync(domain, cancellationToken);
}
finally
{
@@ -73,28 +73,31 @@ namespace FastGithub.DomainResolve
///
/// 查找ip
///
- ///
+ ///
///
///
- private async Task LookupAsync(DnsEndPoint target, CancellationToken cancellationToken)
+ private async Task LookupAsync(DnsEndPoint domain, CancellationToken cancellationToken)
{
- if (this.memoryCache.TryGetValue(target, out var address))
+ if (this.memoryCache.TryGetValue(domain, out var address))
{
return address;
}
var expiration = this.dnscryptExpiration;
- address = await this.LookupCoreAsync(this.dnscryptProxy.EndPoint, target, cancellationToken);
-
- if (address == null)
+ if (this.dnscryptProxy.LocalEndPoint != null)
{
- expiration = this.fallbackExpiration;
- address = await this.FallbackLookupAsync(target, cancellationToken);
+ address = await this.LookupCoreAsync(this.dnscryptProxy.LocalEndPoint, domain, cancellationToken);
}
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
@@ -103,22 +106,22 @@ namespace FastGithub.DomainResolve
expiration = this.loopbackExpiration;
}
- this.logger.LogInformation($"[{target.Host}->{address}]");
- this.memoryCache.Set(target, address, expiration);
+ this.logger.LogInformation($"[{domain.Host}->{address}]");
+ this.memoryCache.Set(domain, address, expiration);
return address;
}
///
/// 回退查找ip
///
- ///
+ ///
///
///
- private async Task FallbackLookupAsync(DnsEndPoint target, CancellationToken cancellationToken)
+ private async Task FallbackLookupAsync(DnsEndPoint domain, CancellationToken cancellationToken)
{
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)
{
return address;
@@ -132,22 +135,22 @@ namespace FastGithub.DomainResolve
/// 查找ip
///
///
- ///
+ ///
///
///
- private async Task LookupCoreAsync(IPEndPoint dns, DnsEndPoint target, CancellationToken cancellationToken)
+ private async Task LookupCoreAsync(IPEndPoint dns, DnsEndPoint domain, CancellationToken cancellationToken)
{
try
{
var dnsClient = new DnsClient(dns);
using var timeoutTokenSource = new CancellationTokenSource(this.lookupTimeout);
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
- var addresses = await dnsClient.Lookup(target.Host, RecordType.A, linkedTokenSource.Token);
- return await this.FindFastValueAsync(addresses, target.Port, cancellationToken);
+ var addresses = await dnsClient.Lookup(domain.Host, RecordType.A, linkedTokenSource.Token);
+ return await this.FindFastValueAsync(addresses, domain.Port, cancellationToken);
}
catch (Exception ex)
{
- this.logger.LogWarning($"dns({dns})无法解析{target.Host}:{ex.Message}");
+ this.logger.LogWarning($"dns({dns})无法解析{domain.Host}:{ex.Message}");
return default;
}
}
diff --git a/FastGithub.DomainResolve/IDomainResolver.cs b/FastGithub.DomainResolve/IDomainResolver.cs
index 5e5a257..801a187 100644
--- a/FastGithub.DomainResolve/IDomainResolver.cs
+++ b/FastGithub.DomainResolve/IDomainResolver.cs
@@ -12,9 +12,9 @@ namespace FastGithub.DomainResolve
///
/// 解析域名
///
- ///
+ ///
///
///
- Task ResolveAsync(DnsEndPoint target, CancellationToken cancellationToken = default);
+ Task ResolveAsync(DnsEndPoint domain, CancellationToken cancellationToken = default);
}
}
\ No newline at end of file