2
0

RequestResolver.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using DNS.Client.RequestResolver;
  2. using DNS.Protocol;
  3. using DNS.Protocol.ResourceRecords;
  4. using FastGithub.Configuration;
  5. using System;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace FastGithub.Dns
  11. {
  12. /// <summary>
  13. /// dns解析者
  14. /// </summary>
  15. sealed class RequestResolver : IRequestResolver
  16. {
  17. private readonly TimeSpan ttl = TimeSpan.FromMinutes(1d);
  18. private readonly FastGithubConfig fastGithubConfig;
  19. /// <summary>
  20. /// dns解析者
  21. /// </summary>
  22. /// <param name="fastGithubConfig"></param>
  23. public RequestResolver(FastGithubConfig fastGithubConfig)
  24. {
  25. this.fastGithubConfig = fastGithubConfig;
  26. }
  27. /// <summary>
  28. /// 解析域名
  29. /// </summary>
  30. /// <param name="request"></param>
  31. /// <param name="cancellationToken"></param>
  32. /// <returns></returns>
  33. public async Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
  34. {
  35. var response = Response.FromRequest(request);
  36. if (request is not RemoteEndPointRequest remoteEndPointRequest)
  37. {
  38. return response;
  39. }
  40. var question = request.Questions.FirstOrDefault();
  41. if (question == null || question.Type != RecordType.A)
  42. {
  43. return response;
  44. }
  45. // 解析匹配的域名指向本机ip
  46. var domain = question.Name;
  47. if (this.fastGithubConfig.IsMatch(domain.ToString()) == true)
  48. {
  49. var localAddress = remoteEndPointRequest.GetLocalIPAddress() ?? IPAddress.Loopback;
  50. var record = new IPAddressResourceRecord(domain, localAddress, this.ttl);
  51. response.AnswerRecords.Add(record);
  52. return response;
  53. }
  54. // 使用回退dns解析域名
  55. foreach (var dns in this.fastGithubConfig.FallbackDns)
  56. {
  57. try
  58. {
  59. var fallbackResolver = new UdpRequestResolver(dns);
  60. var fallbackResponse = await fallbackResolver.Resolve(request, cancellationToken);
  61. if (fallbackResponse != null && fallbackResponse.AnswerRecords.Count > 0)
  62. {
  63. return fallbackResponse;
  64. }
  65. }
  66. catch (Exception)
  67. {
  68. }
  69. }
  70. return response;
  71. }
  72. }
  73. }