using DNS.Client.RequestResolver; using DNS.Protocol; using DNS.Protocol.ResourceRecords; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; namespace FastGithub.Dns { /// /// 反向代理解析器 /// sealed class FastGihubResolver : IRequestResolver { private readonly IRequestResolver untrustedDnsResolver; private readonly IOptionsMonitor options; private readonly ILogger logger; /// /// github相关域名解析器 /// /// /// public FastGihubResolver( IOptionsMonitor options, ILogger logger) { this.options = options; this.logger = logger; this.untrustedDnsResolver = new UdpRequestResolver(options.CurrentValue.UntrustedDns.ToIPEndPoint()); } /// /// 解析域名 /// /// /// /// public async Task Resolve(IRequest request, CancellationToken cancellationToken = default) { var response = Response.FromRequest(request); if (request is not RemoteRequest remoteRequest) { return response; } var question = request.Questions.FirstOrDefault(); if (question == null || question.Type != RecordType.A) { return response; } var domain = question.Name; if (this.options.CurrentValue.IsMatch(domain.ToString()) == true) { var localAddress = remoteRequest.GetLocalAddress() ?? IPAddress.Loopback; var record = new IPAddressResourceRecord(domain, localAddress, TimeSpan.FromMinutes(1d)); this.logger.LogInformation($"[{domain}->{localAddress}]"); response.AnswerRecords.Add(record); return response; } return await this.untrustedDnsResolver.Resolve(request, cancellationToken); } } }