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(); } } }