DnsClient.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using DNS.Client;
  2. using DNS.Client.RequestResolver;
  3. using DNS.Protocol;
  4. using DNS.Protocol.ResourceRecords;
  5. using System;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace FastGithub.DomainResolve
  11. {
  12. /// <summary>
  13. /// DNS客户端
  14. /// </summary>
  15. sealed class DnsClient
  16. {
  17. private readonly IPEndPoint dns;
  18. private readonly IRequestResolver resolver;
  19. private readonly TimeSpan timeout = TimeSpan.FromSeconds(5d);
  20. /// <summary>
  21. /// DNS客户端
  22. /// </summary>
  23. /// <param name="dns"></param>
  24. public DnsClient(IPEndPoint dns)
  25. {
  26. this.dns = dns;
  27. this.resolver = dns.Port == 53
  28. ? new TcpRequestResolver(dns)
  29. : new UdpRequestResolver(dns, new TcpRequestResolver(dns));
  30. }
  31. /// <summary>
  32. /// 解析域名
  33. /// </summary>
  34. /// <param name="domain"></param>
  35. /// <param name="cancellationToken"></param>
  36. /// <returns></returns>
  37. public async Task<IPAddress[]> LookupAsync(string domain, CancellationToken cancellationToken = default)
  38. {
  39. var request = new Request
  40. {
  41. RecursionDesired = true,
  42. OperationCode = OperationCode.Query
  43. };
  44. request.Questions.Add(new Question(new Domain(domain), RecordType.A));
  45. var clientRequest = new ClientRequest(this.resolver, request);
  46. using var timeoutTokenSource = new CancellationTokenSource(this.timeout);
  47. using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
  48. var response = await clientRequest.Resolve(linkedTokenSource.Token);
  49. return response.AnswerRecords.OfType<IPAddressResourceRecord>().Select(item => item.IPAddress).ToArray();
  50. }
  51. /// <summary>
  52. /// 转换为文本
  53. /// </summary>
  54. /// <returns></returns>
  55. public override string ToString()
  56. {
  57. return $"dns://{this.dns}";
  58. }
  59. }
  60. }