Last active
April 30, 2019 16:23
-
-
Save djeikyb/d0c807d82d5b845084dde2b780e54200 to your computer and use it in GitHub Desktop.
dotnetcore dns lookup for srv records
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Threading.Tasks; | |
using DnsClient; | |
namespace | |
{ | |
public class DnsSrvClient | |
{ | |
public static async Task<IEnumerable<IPEndPoint>> Lookup(string host) | |
{ | |
var nameservers = NameServer.ResolveNameServers(skipIPv6SiteLocal: true, fallbackToGooglePublicDns: false); | |
var dns = new LookupClient(nameservers?.ToArray()); | |
var queryResponse = await dns.QueryAsync(host, QueryType.SRV); | |
var records = queryResponse.Answers.SrvRecords().ToList(); | |
if (records.Count == 0) | |
{ | |
throw new Exception($"no SRV records for {host}"); | |
} | |
var arecords = queryResponse.Additionals.ARecords().ToLookup(r => r.DomainName); | |
if (arecords.Count == 0) | |
{ | |
// my docker containers on macos (docker desktop 2.0.0.3) always hit this branch | |
var tasks = records.Select(srv => dns.QueryAsync(srv.Target, QueryType.A)); | |
var results = await Task.WhenAll(tasks.ToArray()); | |
arecords = results | |
.SelectMany(rs => rs.Answers.ARecords()) | |
.ToLookup(r => r.DomainName); | |
} | |
var topPriority = records | |
.OrderBy(srv => srv.Priority) | |
.ThenByDescending(srv => srv.Weight) | |
.GroupBy(srv => srv.Priority) | |
.First(); | |
return topPriority | |
.Where(srv => arecords.Contains(srv.Target)) | |
.Select(srv => new IPEndPoint(arecords[srv.Target].First().Address, srv.Port)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
uses https://github.com/MichaCo/DnsClient.NET
heed the warning though.. ideally an app would cache the list of results and rotate through them according to rfc 2782