2019-12-08 21:23:54 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
#nullable enable
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Swan.Net.Dns {
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// DnsClient public methods.
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal partial class DnsClient {
|
|
|
|
|
private readonly IPEndPoint _dns;
|
|
|
|
|
private readonly IDnsRequestResolver _resolver;
|
|
|
|
|
|
|
|
|
|
public DnsClient(IPEndPoint dns, IDnsRequestResolver? resolver = null) {
|
|
|
|
|
this._dns = dns;
|
|
|
|
|
this._resolver = resolver ?? new DnsUdpRequestResolver(new DnsTcpRequestResolver());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DnsClient(IPAddress ip, Int32 port = Network.DnsDefaultPort, IDnsRequestResolver? resolver = null) : this(new IPEndPoint(ip, port), resolver) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DnsClientRequest Create(IDnsRequest? request = null) => new DnsClientRequest(this._dns, request, this._resolver);
|
|
|
|
|
|
|
|
|
|
public async Task<IList<IPAddress>> Lookup(String domain, DnsRecordType type = DnsRecordType.A) {
|
|
|
|
|
if(String.IsNullOrWhiteSpace(domain)) {
|
|
|
|
|
throw new ArgumentNullException(nameof(domain));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(type != DnsRecordType.A && type != DnsRecordType.AAAA) {
|
|
|
|
|
throw new ArgumentException("Invalid record type " + type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DnsClientResponse response = await this.Resolve(domain, type).ConfigureAwait(false);
|
|
|
|
|
List<IPAddress> ips = response.AnswerRecords.Where(r => r.Type == type).Cast<DnsIPAddressResourceRecord>().Select(r => r.IPAddress).ToList();
|
|
|
|
|
|
|
|
|
|
return ips.Count == 0 ? throw new DnsQueryException(response, "No matching records") : ips;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<String> Reverse(IPAddress ip) {
|
|
|
|
|
if(ip == null) {
|
|
|
|
|
throw new ArgumentNullException(nameof(ip));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DnsClientResponse response = await this.Resolve(DnsDomain.PointerName(ip), DnsRecordType.PTR);
|
|
|
|
|
IDnsResourceRecord ptr = response.AnswerRecords.FirstOrDefault(r => r.Type == DnsRecordType.PTR);
|
|
|
|
|
|
|
|
|
|
return ptr == null ? throw new DnsQueryException(response, "No matching records") : ((DnsPointerResourceRecord)ptr).PointerDomainName.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task<DnsClientResponse> Resolve(String domain, DnsRecordType type) => this.Resolve(new DnsDomain(domain), type);
|
|
|
|
|
|
|
|
|
|
public Task<DnsClientResponse> Resolve(DnsDomain domain, DnsRecordType type) {
|
|
|
|
|
DnsClientRequest request = this.Create();
|
|
|
|
|
DnsQuestion question = new DnsQuestion(domain, type);
|
|
|
|
|
|
|
|
|
|
request.Questions.Add(question);
|
|
|
|
|
request.OperationCode = DnsOperationCode.Query;
|
|
|
|
|
request.RecursionDesired = true;
|
|
|
|
|
|
|
|
|
|
return request.Resolve();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-04 18:57:18 +01:00
|
|
|
|
}
|