DnsHostedService.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using FastGithub.Configuration;
  2. using Microsoft.Extensions.Hosting;
  3. using Microsoft.Extensions.Logging;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  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 DnsHostedService : BackgroundService
  16. {
  17. private readonly DnsServer dnsServer;
  18. private readonly IEnumerable<IDnsValidator> dnsValidators;
  19. private readonly ILogger<DnsHostedService> logger;
  20. /// <summary>
  21. /// dns后台服务
  22. /// </summary>
  23. /// <param name="dnsServer"></param>
  24. /// <param name="dnsValidators"></param>
  25. /// <param name="options"></param>
  26. /// <param name="logger"></param>
  27. public DnsHostedService(
  28. DnsServer dnsServer,
  29. IEnumerable<IDnsValidator> dnsValidators,
  30. IOptionsMonitor<FastGithubOptions> options,
  31. ILogger<DnsHostedService> logger)
  32. {
  33. this.dnsServer = dnsServer;
  34. this.dnsValidators = dnsValidators;
  35. this.logger = logger;
  36. options.OnChange(opt =>
  37. {
  38. if (OperatingSystem.IsWindows())
  39. {
  40. SystemDnsUtil.DnsFlushResolverCache();
  41. }
  42. });
  43. }
  44. /// <summary>
  45. /// 启动dns
  46. /// </summary>
  47. /// <param name="cancellationToken"></param>
  48. /// <returns></returns>
  49. public override async Task StartAsync(CancellationToken cancellationToken)
  50. {
  51. this.dnsServer.Bind(IPAddress.Any, 53);
  52. this.logger.LogInformation("DNS服务启动成功");
  53. if (OperatingSystem.IsWindows())
  54. {
  55. try
  56. {
  57. SystemDnsUtil.DnsSetPrimitive(IPAddress.Loopback);
  58. SystemDnsUtil.DnsFlushResolverCache();
  59. this.logger.LogInformation($"设置为本机主DNS成功");
  60. }
  61. catch (Exception ex)
  62. {
  63. this.logger.LogWarning($"设置为本机主DNS为{IPAddress.Loopback}失败:{ex.Message}");
  64. }
  65. }
  66. else
  67. {
  68. this.logger.LogWarning($"不支持自动设置DNS,请根据你的系统平台情况修改主DNS为{IPAddress.Loopback}");
  69. }
  70. foreach (var item in this.dnsValidators)
  71. {
  72. await item.ValidateAsync();
  73. }
  74. await base.StartAsync(cancellationToken);
  75. }
  76. /// <summary>
  77. /// dns后台
  78. /// </summary>
  79. /// <param name="stoppingToken"></param>
  80. /// <returns></returns>
  81. protected override Task ExecuteAsync(CancellationToken stoppingToken)
  82. {
  83. return this.dnsServer.ListenAsync(stoppingToken);
  84. }
  85. /// <summary>
  86. /// 停止dns服务
  87. /// </summary>
  88. /// <param name="cancellationToken"></param>
  89. /// <returns></returns>
  90. public override Task StopAsync(CancellationToken cancellationToken)
  91. {
  92. this.dnsServer.Dispose();
  93. this.logger.LogInformation("DNS服务已停止");
  94. if (OperatingSystem.IsWindows())
  95. {
  96. try
  97. {
  98. SystemDnsUtil.DnsFlushResolverCache();
  99. SystemDnsUtil.DnsRemovePrimitive(IPAddress.Loopback);
  100. }
  101. catch (Exception ex)
  102. {
  103. this.logger.LogWarning($"恢复DNS记录失败:{ex.Message}");
  104. }
  105. }
  106. return base.StopAsync(cancellationToken);
  107. }
  108. }
  109. }