diff --git a/README.md b/README.md
index 0ed1a18..af1dd29 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ service or service instance.
- CI on Circle (Debian GNU/Linux), Travis (Ubuntu Xenial and OSX) and AppVeyor (Windows Server 2016)
- Detects new and/or removed network interfaces
- Supports multicasting on multiple network interfaces
+- Supports reverse address mapping
- Handles legacy unicast queries, see #61
## Getting started
diff --git a/src/ServiceDiscovery.cs b/src/ServiceDiscovery.cs
index 31e533e..2347102 100644
--- a/src/ServiceDiscovery.cs
+++ b/src/ServiceDiscovery.cs
@@ -192,6 +192,10 @@ public void QueryUnicastServiceInstances(string service)
///
/// Any queries for the service or service instance will be answered with
/// information from the profile.
+ ///
+ /// Besides adding the profile's resource records to the PTR records are
+ /// created to support DNS-SD and reverse address mapping (DNS address lookup).
+ ///
///
public void Advertise(ServiceProfile service)
{
@@ -209,6 +213,8 @@ public void Advertise(ServiceProfile service)
{
catalog.Add(r, authoritative: true);
}
+
+ catalog.IncludeReverseLookupRecords();
}
///
@@ -255,7 +261,9 @@ void OnAnswer(object sender, MessageEventArgs e)
}
// Any DNS-SD answers?
- var sd = msg.Answers.OfType();
+ var sd = msg.Answers
+ .OfType()
+ .Where(ptr => ptr.Name.EndsWith(".local"));
foreach (var ptr in sd)
{
if (ptr.Name == ServiceName)
diff --git a/test/ServiceDiscoveryTest.cs b/test/ServiceDiscoveryTest.cs
index 144d1f2..d854e7f 100644
--- a/test/ServiceDiscoveryTest.cs
+++ b/test/ServiceDiscoveryTest.cs
@@ -321,5 +321,49 @@ public void Unadvertise()
mdns.Stop();
}
}
+ [TestMethod]
+ public void ReverseAddressMapping()
+ {
+ var service = new ServiceProfile("x9", "_sdtest-1._udp", 1024, new[] { IPAddress.Loopback, IPAddress.IPv6Loopback });
+ var arpaAddress = IPAddress.Loopback.GetArpaName();
+ var done = new ManualResetEvent(false);
+
+ var mdns = new MulticastService();
+ Message response = null;
+ mdns.NetworkInterfaceDiscovered += (s, e) =>
+ mdns.SendQuery(arpaAddress, DnsClass.IN, DnsType.PTR);
+ mdns.AnswerReceived += (s, e) =>
+ {
+ var msg = e.Message;
+ if (msg.Answers.OfType().Any(p => p.Name == arpaAddress))
+ {
+ response = msg;
+ done.Set();
+ }
+ };
+ try
+ {
+ using (var sd = new ServiceDiscovery(mdns))
+ {
+ sd.Advertise(service);
+ mdns.Start();
+ Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "query timeout");
+ var answers = response.Answers
+ .OfType()
+ .Where(ptr => service.HostName == ptr.DomainName);
+ foreach (var answer in answers)
+ {
+ Assert.AreEqual(arpaAddress, answer.Name);
+ Assert.IsTrue(answer.TTL > TimeSpan.Zero);
+ Assert.AreEqual(DnsClass.IN, answer.Class);
+ }
+ }
+ }
+ finally
+ {
+ mdns.Stop();
+ }
+ }
+
}
}