Skip to content

Commit

Permalink
Merge pull request #69 from richardschneider/issue-64
Browse files Browse the repository at this point in the history
Uncommon names
  • Loading branch information
richardschneider authored Jul 4, 2019
2 parents 879f86f + edf51a2 commit e53c5d9
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 27 deletions.
5 changes: 2 additions & 3 deletions src/Mdns.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
<Description>A simple Multicast Domain Name Service based on RFC 6762. Can be used as both a client (sending queries) or a server (responding to queries).</Description>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageReleaseNotes>https://github.com/richardschneider/net-mdns/releases</PackageReleaseNotes>
<Copyright>© 2018 Richard Schneider</Copyright>
<Copyright>© 2018-2019 Richard Schneider</Copyright>
<PackageTags>multicast mdns dns zeroconf</PackageTags>
<IncludeSymbols>True</IncludeSymbols>
<PackageLicenseUrl>https://github.com/richardschneider/net-mdns/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/richardschneider/net-mdns</PackageProjectUrl>
</PropertyGroup>

Expand All @@ -34,7 +33,7 @@
<ItemGroup>
<PackageReference Include="Common.Logging" Version="3.4.1" />
<PackageReference Include="IPNetwork2" Version="2.1.2" />
<PackageReference Include="Makaretu.Dns" Version="1.5.0" />
<PackageReference Include="Makaretu.Dns" Version="2.0.0" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard14'">
Expand Down
4 changes: 2 additions & 2 deletions src/MulticastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ void checkResponse(object s, MessageEventArgs e)
/// <exception cref="InvalidOperationException">
/// When the service has not started.
/// </exception>
public void SendQuery(string name, DnsClass klass = DnsClass.IN, DnsType type = DnsType.ANY)
public void SendQuery(DomainName name, DnsClass klass = DnsClass.IN, DnsType type = DnsType.ANY)
{
var msg = new Message
{
Expand Down Expand Up @@ -401,7 +401,7 @@ public void SendQuery(string name, DnsClass klass = DnsClass.IN, DnsType type =
/// <exception cref="InvalidOperationException">
/// When the service has not started.
/// </exception>
public void SendUnicastQuery(string name, DnsClass klass = DnsClass.IN, DnsType type = DnsType.ANY)
public void SendUnicastQuery(DomainName name, DnsClass klass = DnsClass.IN, DnsType type = DnsType.ANY)
{
var msg = new Message
{
Expand Down
37 changes: 27 additions & 10 deletions src/ServiceDiscovery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ namespace Makaretu.Dns
public class ServiceDiscovery : IDisposable
{
static readonly ILog log = LogManager.GetLogger(typeof(ServiceDiscovery));
static readonly DomainName LocalDomain = new DomainName("local");
static readonly DomainName SubName = new DomainName("_sub");

/// <summary>
/// The service discovery service name.
/// </summary>
/// <value>
/// The service name used to enumerate other services.
/// </value>
public const string ServiceName = "_services._dns-sd._udp.local";
public static readonly DomainName ServiceName = new DomainName("_services._dns-sd._udp.local");

readonly bool ownsMdns;
List<ServiceProfile> profiles = new List<ServiceProfile>();

Expand Down Expand Up @@ -101,7 +104,7 @@ public ServiceDiscovery(MulticastService mdns)
/// Use <see cref="QueryAllServices"/> to initiate a DNS-SD question.
/// </para>
/// </remarks>
public event EventHandler<string> ServiceDiscovered;
public event EventHandler<DomainName> ServiceDiscovered;

/// <summary>
/// Raised when a servive instance is discovered.
Expand Down Expand Up @@ -162,9 +165,9 @@ public void QueryUnicastAllServices()
/// When an answer is received the <see cref="ServiceInstanceDiscovered"/> event is raised.
/// </remarks>
/// <seealso cref="ServiceProfile.ServiceName"/>
public void QueryServiceInstances(string service)
public void QueryServiceInstances(DomainName service)
{
Mdns.SendQuery(service + ".local", type: DnsType.PTR);
Mdns.SendQuery(DomainName.Join(service, LocalDomain), type: DnsType.PTR);
}

/// <summary>
Expand All @@ -180,9 +183,14 @@ public void QueryServiceInstances(string service)
/// When an answer is received the <see cref="ServiceInstanceDiscovered"/> event is raised.
/// </remarks>
/// <seealso cref="ServiceProfile.ServiceName"/>
public void QueryServiceInstances(string service, string subtype)
public void QueryServiceInstances(DomainName service, string subtype)
{
Mdns.SendQuery($"{subtype}._sub.{service}.local", type: DnsType.PTR);
var name = DomainName.Join(
new DomainName(subtype),
SubName,
service,
LocalDomain);
Mdns.SendQuery(name, type: DnsType.PTR);
}

/// <summary>
Expand All @@ -196,9 +204,9 @@ public void QueryServiceInstances(string service, string subtype)
/// When an answer is received the <see cref="ServiceInstanceDiscovered"/> event is raised.
/// </remarks>
/// <seealso cref="ServiceProfile.ServiceName"/>
public void QueryUnicastServiceInstances(string service)
public void QueryUnicastServiceInstances(DomainName service)
{
Mdns.SendUnicastQuery(service + ".local", type: DnsType.PTR);
Mdns.SendUnicastQuery(DomainName.Join(service, LocalDomain), type: DnsType.PTR);
}

/// <summary>
Expand Down Expand Up @@ -231,7 +239,10 @@ public void Advertise(ServiceProfile service)
{
var ptr = new PTRRecord
{
Name = $"{subtype}._sub.{service.QualifiedServiceName}",
Name = DomainName.Join(
new DomainName(subtype),
SubName,
service.QualifiedServiceName),
DomainName = service.FullyQualifiedName
};
catalog.Add(ptr, authoritative: true);
Expand Down Expand Up @@ -289,9 +300,10 @@ void OnAnswer(object sender, MessageEventArgs e)
}

// Any DNS-SD answers?

var sd = msg.Answers
.OfType<PTRRecord>()
.Where(ptr => ptr.Name.EndsWith(".local"));
.Where(ptr => ptr.Name.IsSubdomainOf(LocalDomain));
foreach (var ptr in sd)
{
if (ptr.Name == ServiceName)
Expand Down Expand Up @@ -364,6 +376,11 @@ void OnQuery(object sender, MessageEventArgs e)
response.AdditionalRecords.Clear();
}

if (!response.Answers.Any(a => a.Name == ServiceName))
{
;
}

if (QU)
{
// TODO: Send a Unicast response if required.
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceInstanceDiscoveryEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ServiceInstanceDiscoveryEventArgs : MessageEventArgs
/// Typically of the form "<i>instance</i>._<i>service</i>._tcp.local".
/// </value>
/// <seealso cref="ServiceProfile.FullyQualifiedName"/>
public string ServiceInstanceName { get; set; }
public DomainName ServiceInstanceName { get; set; }
}
}

2 changes: 1 addition & 1 deletion src/ServiceInstanceShutdownEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ServiceInstanceShutdownEventArgs : MessageEventArgs
/// Typically of the form "<i>instance</i>._<i>service</i>._tcp.local".
/// </value>
/// <seealso cref="ServiceProfile.FullyQualifiedName"/>
public string ServiceInstanceName { get; set; }
public DomainName ServiceInstanceName { get; set; }
}
}

22 changes: 12 additions & 10 deletions src/ServiceProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,18 @@ public ServiceProfile()
/// <remarks>
/// The SRV, TXT and A/AAAA resoruce records are added to the <see cref="Resources"/>.
/// </remarks>
public ServiceProfile(string instanceName, string serviceName, ushort port, IEnumerable<IPAddress> addresses = null)
public ServiceProfile(DomainName instanceName, DomainName serviceName, ushort port, IEnumerable<IPAddress> addresses = null)
{
InstanceName = instanceName;
ServiceName = serviceName;
var fqn = FullyQualifiedName;

var simpleServiceName = ServiceName
var simpleServiceName = new DomainName(ServiceName.ToString()
.Replace("._tcp", "")
.Replace("._udp", "")
.TrimStart('_');
HostName = $"{InstanceName}.{simpleServiceName}.{Domain}";
.Trim('_')
.Replace("_", "-"));
HostName = DomainName.Join(InstanceName, simpleServiceName, Domain);
Resources.Add(new SRVRecord
{
Name = fqn,
Expand All @@ -85,7 +86,7 @@ public ServiceProfile(string instanceName, string serviceName, ushort port, IEnu
/// <value>
/// Always "local".
/// </value>
public string Domain { get; } = "local";
public DomainName Domain { get; } = "local";

/// <summary>
/// A unique name for the service.
Expand All @@ -101,23 +102,23 @@ public ServiceProfile(string instanceName, string serviceName, ushort port, IEnu
/// The second label is either "_tcp" (for application
/// protocols that run over TCP) or "_udp" (for all others).
/// </remarks>
public string ServiceName { get; set; }
public DomainName ServiceName { get; set; }

/// <summary>
/// A unique identifier for the service instance.
/// </summary>
/// <value>
/// Some unique value.
/// </value>
public string InstanceName { get; set; }
public DomainName InstanceName { get; set; }

/// <summary>
/// The service name and domain.
/// </summary>
/// <value>
/// Typically of the form "_<i>service</i>._tcp.local".
/// </value>
public string QualifiedServiceName => $"{ServiceName}.{Domain}";
public DomainName QualifiedServiceName => DomainName.Join(ServiceName, Domain);

/// <summary>
/// The fully qualified name of the instance's host.
Expand All @@ -126,15 +127,16 @@ public ServiceProfile(string instanceName, string serviceName, ushort port, IEnu
/// This can be used to query the address records (A and AAAA)
/// of the service instance.
/// </remarks>
public string HostName { get; set; }
public DomainName HostName { get; set; }

/// <summary>
/// The instance name, service name and domain.
/// </summary>
/// <value>
/// <see cref="InstanceName"/>.<see cref="ServiceName"/>.<see cref="Domain"/>
/// </value>
public string FullyQualifiedName => $"{InstanceName}.{QualifiedServiceName}";
public DomainName FullyQualifiedName =>
DomainName.Join(InstanceName, ServiceName, Domain);

/// <summary>
/// DNS resource records that are used to locate the service instance.
Expand Down
1 change: 1 addition & 0 deletions test/MulticastServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public async Task ReceiveLegacyUnicastAnswer()
mdns.Start();
Assert.IsTrue(ready.WaitOne(TimeSpan.FromSeconds(1)), "ready timeout");
await client.SendAsync(packet, packet.Length, "224.0.0.251", 5353);

var r = await client.ReceiveAsync();
var response = new Message();
response.Read(r.Buffer, 0, r.Buffer.Length);
Expand Down
10 changes: 10 additions & 0 deletions test/ServiceProfileTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,15 @@ public void Subtypes()
var service = new ServiceProfile("x", "_sdtest._udp", 1024);
Assert.AreEqual(0, service.Subtypes.Count);
}

[TestMethod]
public void HostName()
{
var service = new ServiceProfile("fred", "_foo._tcp", 1024);
Assert.AreEqual("fred.foo.local", service.HostName);

service = new ServiceProfile("fred", "_foo_bar._tcp", 1024);
Assert.AreEqual("fred.foo-bar.local", service.HostName);
}
}
}

0 comments on commit e53c5d9

Please sign in to comment.