Skip to content

Commit

Permalink
feat(ServiceDiscovery): use NameServer to resolve queries
Browse files Browse the repository at this point in the history
  • Loading branch information
richardschneider committed Jul 19, 2018
1 parent 3a912ab commit 7a7c9fe
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Spike/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)}");
};
Expand Down
2 changes: 1 addition & 1 deletion src/Mdns.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

<ItemGroup>
<PackageReference Include="Common.Logging" Version="3.4.1" />
<PackageReference Include="Makaretu.Dns" Version="0.13.0" />
<PackageReference Include="Makaretu.Dns" Version="0.13.1" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard14'">
Expand Down
55 changes: 26 additions & 29 deletions src/ServiceDiscovery.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Makaretu.Dns.Resolving;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
Expand All @@ -22,6 +23,11 @@ public class ServiceDiscovery : IDisposable
MulticastService mdns;
readonly bool ownsMdns;

NameServer localDomain = new NameServer {
Catalog = new Catalog(),
AnswerAllQuestions = true
};

List<ServiceProfile> profiles = new List<ServiceProfile>();

/// <summary>
Expand Down Expand Up @@ -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)
Expand All @@ -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

/// <inheritdoc />
protected virtual void Dispose(bool disposing)
Expand All @@ -134,7 +131,7 @@ public void Dispose()
{
Dispose(true);
}
#endregion
#endregion
}

}
2 changes: 1 addition & 1 deletion test/MulticastServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArgumentOutOfRangeException>(() => {
mdns.SendAnswer(answer);
});
Expand Down

0 comments on commit 7a7c9fe

Please # to comment.