From 7a7c9fea53c4e3f0dc22345d79cdf53e5d0b59ad Mon Sep 17 00:00:00 2001 From: Richard Schneider Date: Thu, 19 Jul 2018 15:06:37 +1200 Subject: [PATCH] feat(ServiceDiscovery): use NameServer to resolve queries --- Spike/Program.cs | 4 +-- src/Mdns.csproj | 2 +- src/ServiceDiscovery.cs | 55 +++++++++++++++++------------------- test/MulticastServiceTest.cs | 2 +- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/Spike/Program.cs b/Spike/Program.cs index 1a44b7f..3e9c30d 100644 --- a/Spike/Program.cs +++ b/Spike/Program.cs @@ -34,13 +34,13 @@ static void Main(string[] args) mdns.QueryReceived += (s, e) => { var names = e.Message.Questions - .Select(q => q.Name); + .Select(q => q.Name + " " + q.Type); Console.WriteLine($"got a query for {String.Join(", ", names)}"); }; mdns.AnswerReceived += (s, e) => { var names = e.Message.Answers - .Select(q => q.Name) + .Select(q => q.Name + " " + q.Type) .Distinct(); Console.WriteLine($"got answer for {String.Join(", ", names)}"); }; diff --git a/src/Mdns.csproj b/src/Mdns.csproj index 3acc962..fe41ad1 100644 --- a/src/Mdns.csproj +++ b/src/Mdns.csproj @@ -31,7 +31,7 @@ - + diff --git a/src/ServiceDiscovery.cs b/src/ServiceDiscovery.cs index 8d4d28f..93fc6db 100644 --- a/src/ServiceDiscovery.cs +++ b/src/ServiceDiscovery.cs @@ -1,4 +1,5 @@ -using System; +using Makaretu.Dns.Resolving; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -22,6 +23,11 @@ public class ServiceDiscovery : IDisposable MulticastService mdns; readonly bool ownsMdns; + NameServer localDomain = new NameServer { + Catalog = new Catalog(), + AnswerAllQuestions = true + }; + List profiles = new List(); /// @@ -63,6 +69,19 @@ public ServiceDiscovery(MulticastService mdns) public void Advertise(ServiceProfile service) { profiles.Add(service); + + var catalog = localDomain.Catalog; + catalog.Add( + new PTRRecord { Name = ServiceName, DomainName = service.QualifiedServiceName }, + authoritative: true); + catalog.Add( + new PTRRecord { Name = service.QualifiedServiceName, DomainName = service.FullyQualifiedName }, + authoritative: true); + + foreach (var r in service.Resources) + { + catalog.Add(r, authoritative: true); + } } void OnAnswer(object sender, MessageEventArgs e) @@ -78,38 +97,16 @@ void OnAnswer(object sender, MessageEventArgs e) void OnQuery(object sender, MessageEventArgs e) { var request = e.Message; - var response = request.CreateResponse(); - - // If a SD meta-query, then respond with all advertised service names. - if (request.Questions.Any(q => DnsObject.NamesEquals(q.Name, ServiceName) && q.Type == DnsType.PTR)) - { - var ptrs = profiles - .Select(p => p.QualifiedServiceName) - .Distinct() - .Select(s => new PTRRecord { Name = ServiceName, DomainName = s }); - response.Answers.AddRange(ptrs); - } - - // If a query for a service, then respond with a PTR to server. - var servicePtrs = request.Questions - .Where(q => q.Type == DnsType.PTR || q.Type == DnsType.ANY) - .SelectMany(q => profiles.Where(p => DnsObject.NamesEquals(q.Name, p.QualifiedServiceName))) - .Select(p => new PTRRecord { Name = p.QualifiedServiceName, DomainName = p.FullyQualifiedName }); - response.Answers.AddRange(servicePtrs); - - // If a query for the service instance, the respond with all details. - var resources = request.Questions - .SelectMany(q => profiles.Where(p => DnsObject.NamesEquals(q.Name, p.FullyQualifiedName))) - .SelectMany(p => p.Resources); - response.Answers.AddRange(resources); - - if (response.Answers.Count > 0) + var response = localDomain.ResolveAsync(request).Result; + if (response.Status == MessageStatus.NoError) { + response.AdditionalRecords.Clear(); mdns.SendAnswer(response); + Console.WriteLine($"Response time {(DateTime.Now - request.CreationTime).TotalMilliseconds}ms"); } } - #region IDisposable Support +#region IDisposable Support /// protected virtual void Dispose(bool disposing) @@ -134,7 +131,7 @@ public void Dispose() { Dispose(true); } - #endregion +#endregion } } diff --git a/test/MulticastServiceTest.cs b/test/MulticastServiceTest.cs index 9893c82..b340baf 100644 --- a/test/MulticastServiceTest.cs +++ b/test/MulticastServiceTest.cs @@ -227,7 +227,7 @@ public void SendAnswer_TooBig() Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "no nic"); var answer = new Message(); answer.Answers.Add(new ARecord { Name = "foo.bar.org", Address = IPAddress.Loopback }); - answer.AdditionalRecords.Add(new NULLRecord { Name = "foo.bar.org", Data = new byte[9000] }); + answer.Answers.Add(new NULLRecord { Name = "foo.bar.org", Data = new byte[9000] }); ExceptionAssert.Throws(() => { mdns.SendAnswer(answer); });