using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Unosquare.Swan.Exceptions;
namespace Unosquare.Swan.Networking {
///
/// DnsClient public methods.
///
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 IList 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 = this.Resolve(domain, type);
List ips = response.AnswerRecords
.Where(r => r.Type == type)
.Cast()
.Select(r => r.IPAddress)
.ToList();
if(ips.Count == 0) {
throw new DnsQueryException(response, "No matching records");
}
return ips;
}
public String Reverse(IPAddress ip) {
if(ip == null) {
throw new ArgumentNullException(nameof(ip));
}
DnsClientResponse response = this.Resolve(DnsDomain.PointerName(ip), DnsRecordType.PTR);
IDnsResourceRecord ptr = response.AnswerRecords.FirstOrDefault(r => r.Type == DnsRecordType.PTR);
if(ptr == null) {
throw new DnsQueryException(response, "No matching records");
}
return ((DnsPointerResourceRecord)ptr).PointerDomainName.ToString();
}
public DnsClientResponse Resolve(String domain, DnsRecordType type) => this.Resolve(new DnsDomain(domain), type);
public 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();
}
}
}