Skip to content

Instantly share code, notes, and snippets.

@djeikyb
Last active April 30, 2019 16:23
Show Gist options
  • Save djeikyb/d0c807d82d5b845084dde2b780e54200 to your computer and use it in GitHub Desktop.
Save djeikyb/d0c807d82d5b845084dde2b780e54200 to your computer and use it in GitHub Desktop.
dotnetcore dns lookup for srv records
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));
}
}
}
@djeikyb
Copy link
Author

djeikyb commented Apr 10, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment