using DNS.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace FastGithub.Scanner.DomainAddressProviders
{
///
/// 公共dns的域名与ip关系提供者
///
[Service(ServiceLifetime.Singleton, ServiceType = typeof(IDomainAddressProvider))]
sealed class PublicDnsProvider : IDomainAddressProvider
{
private readonly IOptionsMonitor options;
private readonly ILogger logger;
///
/// 公共dns的域名与ip关系提供者
///
///
///
public PublicDnsProvider(
IOptionsMonitor options,
ILogger logger)
{
this.options = options;
this.logger = logger;
}
///
/// 创建域名与ip的关系
///
///
public async Task> CreateDomainAddressesAsync()
{
var setting = this.options.CurrentValue.DominAddressProviders.PublicDnsProvider;
if (setting.Enable == false)
{
return Enumerable.Empty();
}
var result = new HashSet();
foreach (var dns in setting.Dnss)
{
var domainAddresses = await this.LookupAsync(dns, setting.Domains);
foreach (var item in domainAddresses)
{
result.Add(item);
}
}
return result;
}
///
/// 反查ip
///
/// dns服务器
/// 域名
///
private async Task> LookupAsync(string dns, IEnumerable domains)
{
var client = new DnsClient(dns);
var result = new List();
foreach (var domain in domains)
{
try
{
var addresses = await client.Lookup(domain);
foreach (var address in addresses)
{
if (address.AddressFamily == AddressFamily.InterNetwork)
{
result.Add(new DomainAddress(domain, address));
}
}
}
catch (Exception)
{
this.logger.LogWarning($"dns({dns})无法解析{domain}");
}
}
return result;
}
}
}