using DNS.Client.RequestResolver; using DNS.Protocol; using DNS.Protocol.ResourceRecords; using FastGithub.Configuration; using Microsoft.Extensions.Logging; using System; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; namespace FastGithub.Dns { /// /// dns解析者 /// sealed class RequestResolver : IRequestResolver { private readonly TimeSpan ttl = TimeSpan.FromMinutes(1d); private readonly FastGithubConfig fastGithubConfig; /// /// dns解析者 /// /// public RequestResolver(FastGithubConfig fastGithubConfig) { this.fastGithubConfig = fastGithubConfig; } /// /// 解析域名 /// /// /// /// public async Task Resolve(IRequest request, CancellationToken cancellationToken = default) { var response = Response.FromRequest(request); if (request is not RemoteEndPointRequest remoteEndPointRequest) { return response; } var question = request.Questions.FirstOrDefault(); if (question == null || question.Type != RecordType.A) { return response; } // 解析匹配的域名指向本机ip var domain = question.Name; if (this.fastGithubConfig.IsMatch(domain.ToString()) == true) { var localAddress = remoteEndPointRequest.GetLocalIPAddress() ?? IPAddress.Loopback; var record = new IPAddressResourceRecord(domain, localAddress, this.ttl); response.AnswerRecords.Add(record); return response; } var fastResolver = new UdpRequestResolver(fastGithubConfig.FastDns); return await fastResolver.Resolve(request, cancellationToken); } } }