using DNS.Server; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Net; using System.Threading; using System.Threading.Tasks; namespace FastGithub.Dns { /// /// dns后台服务 /// sealed class DnsHostedService : BackgroundService { private readonly DnsServer dnsServer; private readonly IOptions options; private readonly ILogger logger; private IPAddress[]? dnsAddresses; /// /// dns后台服务 /// /// /// /// public DnsHostedService( GithubRequestResolver githubRequestResolver, IOptions options, ILogger logger) { this.dnsServer = new DnsServer(githubRequestResolver, options.Value.UpStream); this.dnsServer.Listening += DnsServer_Listening; this.dnsServer.Errored += DnsServer_Errored; this.options = options; this.logger = logger; } /// /// 监听后 /// /// /// private void DnsServer_Listening(object? sender, EventArgs e) { this.logger.LogInformation("dns服务启动成功"); this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, this.options.Value.UpStream); } /// /// dns异常 /// /// /// private void DnsServer_Errored(object? sender, DnsServer.ErroredEventArgs e) { if (e.Exception is not OperationCanceledException) { this.logger.LogError($"dns服务异常:{e.Exception.Message}"); } } /// /// 启动dns /// /// /// protected async override Task ExecuteAsync(CancellationToken stoppingToken) { try { await this.dnsServer.Listen(); } catch (Exception ex) { this.logger.LogWarning($"dns服务启动失败:{ex.Message}"); } } /// /// 停止dns服务 /// /// /// public override Task StopAsync(CancellationToken cancellationToken) { this.dnsServer.Dispose(); this.logger.LogInformation("dns服务已终止"); if (this.dnsAddresses != null) { this.SetNameServers(this.dnsAddresses); } return Task.CompletedTask; } /// /// 设置dns /// /// /// private IPAddress[]? SetNameServers(params IPAddress[] nameServers) { if (this.options.Value.SetToLocalMachine && OperatingSystem.IsWindows()) { try { var results = NameServiceUtil.SetNameServers(nameServers); this.logger.LogInformation($"设置本机dns成功"); return results; } catch (Exception ex) { this.logger.LogWarning($"设置本机dns失败:{ex.Message}"); } } return default; } } }