You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DnsBusiness.cs 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using ARSoft.Tools.Net.Dns;
  8. using Microsoft.Extensions.Options;
  9. using SiteStatus.Dbo;
  10. namespace SiteStatus.Business
  11. {
  12. public class DnsBusiness
  13. {
  14. public SettingsDbo Options { get; }
  15. public DnsBusiness(IOptions<SettingsDbo> options)
  16. {
  17. Options = options.Value;
  18. }
  19. public async Task<DnsZoneStatusDbo> GetZoneStatusAsync(string zone, IEnumerable<string> servers)
  20. {
  21. var dnsStatus = new DnsZoneStatusDbo
  22. {
  23. Zone = zone,
  24. ServerStatus = new List<DnsZoneServerStatusDbo>()
  25. };
  26. var cancellationTokenSource = new CancellationTokenSource();
  27. var list = new List<KeyValuePair<string, Task<List<SoaRecord>>>>();
  28. var tasks = new List<Task<List<SoaRecord>>>();
  29. foreach (var server in servers)
  30. {
  31. try
  32. {
  33. var resolver = new DnsStubResolver(new []{IPAddress.Parse(server)});
  34. var recordsTask = resolver.ResolveAsync<SoaRecord>(zone, RecordType.Soa, RecordClass.INet, cancellationTokenSource.Token);
  35. list.Add(new KeyValuePair<string, Task<List<SoaRecord>>>(server, recordsTask));
  36. tasks.Add(recordsTask);
  37. }
  38. catch (Exception)
  39. {
  40. tasks.Add(Task.FromResult<List<SoaRecord>>(null));
  41. }
  42. }
  43. try
  44. {
  45. var allTasks = Task.WhenAll(tasks.ToArray());
  46. if (await Task.WhenAny(allTasks, Task.Delay(Options.Dns.Resolve.Timeout)) == allTasks) {
  47. await allTasks;
  48. } else {
  49. cancellationTokenSource.Cancel();
  50. }
  51. }
  52. catch (Exception)
  53. {
  54. // Ignore, errors will be handled later
  55. }
  56. foreach (var recordResult in list)
  57. {
  58. try
  59. {
  60. var record = recordResult.Value.Result.FirstOrDefault();
  61. dnsStatus.ServerStatus.Add(new DnsZoneServerStatusDbo
  62. {
  63. Server = recordResult.Key,
  64. Soa = record?.ToString()
  65. });
  66. }
  67. catch (Exception)
  68. {
  69. dnsStatus.ServerStatus.Add(new DnsZoneServerStatusDbo
  70. {
  71. Server = recordResult.Key,
  72. Soa = null
  73. });
  74. }
  75. }
  76. return dnsStatus;
  77. }
  78. public DnsStatusDbo GetDnsStatus()
  79. {
  80. var allTasks = new Dictionary<SettingsDnsViewDbo, IList<Task<DnsZoneStatusDbo>>>();
  81. foreach (var view in Options.Dns.Views)
  82. {
  83. var servers = view.Servers.Select(server => server.Ip).ToList();
  84. var tasks = view.Zones.Select(zone => GetZoneStatusAsync(zone.Name, servers)).ToArray();
  85. allTasks.Add(view, tasks);
  86. }
  87. Task.WaitAll(allTasks.SelectMany(x => x.Value).ToArray());
  88. var status = new DnsStatusDbo
  89. {
  90. Views = allTasks.Select(pair =>
  91. {
  92. var results = pair.Value.Select(task => task.Result).ToList();
  93. return new DnsStatusViewDbo
  94. {
  95. Name = pair.Key.Name,
  96. Zones = results
  97. };
  98. }).ToList()
  99. };
  100. return status;
  101. }
  102. }
  103. }