public void SendAnswer_TooBig() { var done = new ManualResetEvent(false); var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => done.Set(); mdns.Start(); try { 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.Answers.Add(new NULLRecord { Name = "foo.bar.org", Data = new byte[9000] }); ExceptionAssert.Throws <ArgumentOutOfRangeException>(() => { mdns.SendAnswer(answer); }); } finally { mdns.Stop(); } }
public void Discover_AllServices() { var service = new ServiceProfile("x", "_sdtest-2._udp", 1024); var done = new ManualResetEvent(false); var mdns = new MulticastService(); var sd = new ServiceDiscovery(mdns); mdns.NetworkInterfaceDiscovered += (s, e) => sd.QueryAllServices(); sd.ServiceDiscovered += (s, serviceName) => { if (serviceName == service.QualifiedServiceName) { done.Set(); } }; try { sd.Advertise(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "DNS-SD query timeout"); } finally { sd.Dispose(); mdns.Stop(); } }
public void Advertises_ServiceInstance_Address() { var service = new ServiceProfile("x2", "_sdtest-1._udp", 1024, new[] { IPAddress.Loopback }); var done = new ManualResetEvent(false); var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => mdns.SendQuery(service.HostName, DnsClass.IN, DnsType.A); mdns.AnswerReceived += (s, e) => { var msg = e.Message; if (msg.Answers.OfType <ARecord>().Any(p => p.Name == service.HostName)) { done.Set(); } }; try { using (var sd = new ServiceDiscovery(mdns)) { sd.Advertise(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "query timeout"); } } finally { mdns.Stop(); } }
public void Announce_ContainsResourceRecords() { var service = new ServiceProfile("z", "_sdtest-4._udp", 1024, new[] { IPAddress.Loopback }); var done = new ManualResetEvent(false); var mdns = new MulticastService(); mdns.AnswerReceived += (s, e) => { var msg = e.Message; foreach (var r in service.Resources) { if (!msg.Answers.Contains(r)) { return; } } done.Set(); }; try { using (var sd = new ServiceDiscovery(mdns)) { mdns.NetworkInterfaceDiscovered += (s, e) => sd.Announce(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(3)), "announce timeout"); } } finally { mdns.Stop(); } }
public void Announce_SentTwice() { var service = new ServiceProfile("z", "_sdtest-4._udp", 1024, new[] { IPAddress.Loopback }); var done = new ManualResetEvent(false); var nanswers = 0; var mdns = new MulticastService { IgnoreDuplicateMessages = false }; mdns.AnswerReceived += (s, e) => { var msg = e.Message; if (msg.Answers.OfType <PTRRecord>().Any(p => p.DomainName == service.FullyQualifiedName)) { if (++nanswers == 2) { done.Set(); } } }; try { using (var sd = new ServiceDiscovery(mdns)) { mdns.NetworkInterfaceDiscovered += (s, e) => sd.Announce(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(4)), "announce timeout"); } } finally { mdns.Stop(); } }
public void StartStop() { var mdns = new MulticastService(); mdns.Start(); mdns.Stop(); }
public void Unadvertise() { var service = new ServiceProfile("z", "_sdtest-7._udp", 1024); var done = new ManualResetEvent(false); var mdns = new MulticastService(); var sd = new ServiceDiscovery(mdns); mdns.NetworkInterfaceDiscovered += (s, e) => sd.QueryAllServices(); sd.ServiceInstanceShutdown += (s, e) => { if (e.ServiceInstanceName == service.FullyQualifiedName) { done.Set(); } }; try { sd.Advertise(service); mdns.Start(); sd.Unadvertise(service); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "goodbye timeout"); } finally { sd.Dispose(); mdns.Stop(); } }
public void SendQuery_TooBig() { var done = new ManualResetEvent(false); var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => done.Set(); mdns.Start(); try { Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "no nic"); var query = new Message(); query.Questions.Add(new Question { Name = "foo.bar.org" }); query.AdditionalRecords.Add(new NULLRecord { Name = "foo.bar.org", Data = new byte[9000] }); ExceptionAssert.Throws <ArgumentOutOfRangeException>(() => { mdns.SendQuery(query); }); } finally { mdns.Stop(); } }
public void Discover_ServiceInstance() { var service = new ServiceProfile("y", "_sdtest-2._udp", 1024); var done = new ManualResetEvent(false); var mdns = new MulticastService(); var sd = new ServiceDiscovery(mdns); mdns.NetworkInterfaceDiscovered += (s, e) => { sd.QueryServiceInstances(service.ServiceName); }; sd.ServiceInstanceDiscovered += (s, e) => { if (e.ServiceInstanceName == service.FullyQualifiedName) { Assert.IsNotNull(e.Message); done.Set(); } }; try { sd.Advertise(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "instance not found"); } finally { sd.Dispose(); mdns.Stop(); } }
public void SendQuery() { var ready = new ManualResetEvent(false); var done = new ManualResetEvent(false); Message msg = null; var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => ready.Set(); mdns.QueryReceived += (s, e) => { msg = e.Message; done.Set(); }; try { mdns.Start(); Assert.IsTrue(ready.WaitOne(TimeSpan.FromSeconds(1)), "ready timeout"); mdns.SendQuery("some-service.local"); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "query timeout"); Assert.AreEqual("some-service.local", msg.Questions.First().Name); Assert.AreEqual(Class.IN, msg.Questions.First().Class); } finally { mdns.Stop(); } }
public void Multiple_Services() { var service = Guid.NewGuid().ToString() + ".local"; var done = new ManualResetEvent(false); Message response = null; var a = new MulticastService(); a.QueryReceived += (s, e) => { var msg = e.Message; if (msg.Questions.Any(q => q.Name == service)) { var res = msg.CreateResponse(); var addresses = MulticastService.GetIPAddresses() .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork); foreach (var address in addresses) { res.Answers.Add(new ARecord { Name = service, Address = address }); } a.SendAnswer(res); } }; var b = new MulticastService(); b.NetworkInterfaceDiscovered += (s, e) => b.SendQuery(service); b.AnswerReceived += (s, e) => { var msg = e.Message; if (msg.Answers.Any(ans => ans.Name == service)) { response = msg; done.Set(); } }; try { a.Start(); b.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "answer timeout"); Assert.IsNotNull(response); Assert.IsTrue(response.IsResponse); Assert.AreEqual(MessageStatus.NoError, response.Status); Assert.IsTrue(response.AA); Assert.AreNotEqual(0, response.Answers.Count); } finally { b.Stop(); a.Stop(); } }
public void Disposable() { using (var mdns = new MulticastService()) { Assert.IsNotNull(mdns); } using (var mdns = new MulticastService()) { Assert.IsNotNull(mdns); mdns.Start(); } }
public async Task ReceiveLegacyUnicastAnswer() { var service = Guid.NewGuid().ToString() + ".local"; var ready = new ManualResetEvent(false); var query = new Message(); query.Questions.Add(new Question { Name = service, Type = DnsType.A }); var packet = query.ToByteArray(); var client = new UdpClient(); using (var mdns = new MulticastService()) { mdns.NetworkInterfaceDiscovered += (s, e) => ready.Set(); mdns.QueryReceived += (s, e) => { var msg = e.Message; if (msg.Questions.Any(q => q.Name == service)) { var res = msg.CreateResponse(); res.Answers.Add(new ARecord { Name = service, Address = IPAddress.Parse("127.1.1.1") }); mdns.SendAnswer(res, e); } }; 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); Assert.IsTrue(response.IsResponse); Assert.AreEqual(MessageStatus.NoError, response.Status); Assert.IsTrue(response.AA); Assert.AreEqual(1, response.Questions.Count); var a = (ARecord)response.Answers[0]; Assert.AreEqual(IPAddress.Parse("127.1.1.1"), a.Address); Assert.AreEqual(service, a.Name); Assert.AreEqual(TimeSpan.FromSeconds(10), a.TTL); } }
public void ReceiveAnswer() { var service = Guid.NewGuid().ToString() + ".local"; var done = new ManualResetEvent(false); Message response = null; var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => mdns.SendQuery(service); mdns.QueryReceived += (s, e) => { var msg = e.Message; if (msg.Questions.Any(q => q.Name == service)) { var res = msg.CreateResponse(); res.Answers.Add(new ARecord { Name = service, Address = IPAddress.Parse("127.1.1.1") }); mdns.SendAnswer(res); } }; mdns.AnswerReceived += (s, e) => { var msg = e.Message; if (msg.Answers.Any(a => a.Name == service)) { response = msg; done.Set(); } }; try { mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "answer timeout"); Assert.IsNotNull(response); Assert.IsTrue(response.IsResponse); Assert.AreEqual(MessageStatus.NoError, response.Status); Assert.IsTrue(response.AA); var a = (ARecord)response.Answers[0]; Assert.AreEqual(IPAddress.Parse("127.1.1.1"), a.Address); } finally { mdns.Stop(); } }
public async Task NoDuplicateResponse() { var service = Guid.NewGuid().ToString() + ".local"; using (var mdns = new MulticastService()) { var answerCount = 0; mdns.NetworkInterfaceDiscovered += (s, e) => { mdns.SendQuery(service); Thread.Sleep(250); mdns.SendQuery(service); }; mdns.QueryReceived += (s, e) => { var msg = e.Message; if (msg.Questions.Any(q => q.Name == service)) { var res = msg.CreateResponse(); res.Answers.Add(new ARecord { Name = service, Address = IPAddress.Parse("127.1.1.1") }); mdns.SendAnswer(res, checkDuplicate: false); } }; mdns.AnswerReceived += (s, e) => { var msg = e.Message; if (msg.Answers.Any(answer => answer.Name == service)) { ++answerCount; } ; }; mdns.Start(); await Task.Delay(2000); Assert.AreEqual(1, answerCount); mdns.SendQuery(service); await Task.Delay(2000); Assert.AreEqual(2, answerCount); } }
public void Discover_ServiceInstance_WithAnswersContainingAdditionRecords() { var service = new ServiceProfile("y", "_sdtest-2._udp", 1024, new[] { IPAddress.Parse("127.1.1.1") }); var done = new ManualResetEvent(false); using (var mdns = new MulticastService()) using (var sd = new ServiceDiscovery(mdns) { AnswersContainsAdditionalRecords = true }) { Message discovered = null; mdns.NetworkInterfaceDiscovered += (s, e) => { sd.QueryServiceInstances(service.ServiceName); }; sd.ServiceInstanceDiscovered += (s, e) => { if (e.ServiceInstanceName == service.FullyQualifiedName) { Assert.IsNotNull(e.Message); discovered = e.Message; done.Set(); } }; sd.Advertise(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(3)), "instance not found"); var additionalRecordsCount = 1 + // SRVRecord 1 + // TXTRecord 1; // AddressRecord var answersCount = additionalRecordsCount + 1; // PTRRecord Assert.AreEqual(0, discovered.AdditionalRecords.Count); Assert.AreEqual(answersCount, discovered.Answers.Count); } }
public void StartStop_SingleInterface() { var addresses = MulticastService.GetIPAddresses().ToArray(); foreach (var address in addresses) { string pattern = address.ToString(); if (pattern.Contains('.')) { pattern = pattern.Substring(0, pattern.LastIndexOf('.')) + ".0/24"; } var nic = MulticastService.GetNetworkInterfaceFromCIDR(pattern); var mdns = new MulticastService(nic); Assert.IsTrue(mdns.IsUsingSingleInterface); mdns.Start(); mdns.Stop(); } }
public void Multiple_Listeners() { var ready1 = new ManualResetEvent(false); var ready2 = new ManualResetEvent(false); using (var mdns1 = new MulticastService()) using (var mdns2 = new MulticastService()) { mdns1.NetworkInterfaceDiscovered += (s, e) => ready1.Set(); mdns1.Start(); mdns2.NetworkInterfaceDiscovered += (s, e) => ready2.Set(); mdns2.Start(); Assert.IsTrue(ready1.WaitOne(TimeSpan.FromSeconds(1)), "ready1 timeout"); Assert.IsTrue(ready2.WaitOne(TimeSpan.FromSeconds(1)), "ready2 timeout"); } }
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 <PTRRecord>().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 <PTRRecord>() .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(); } }
public void Resolve_NoAnswer() { var service = Guid.NewGuid().ToString() + ".local"; var query = new Message(); query.Questions.Add(new Question { Name = service, Type = DnsType.ANY }); var cancellation = new CancellationTokenSource(500); using (var mdns = new MulticastService()) { mdns.Start(); ExceptionAssert.Throws <TaskCanceledException>(() => { var _ = mdns.ResolveAsync(query, cancellation.Token).Result; }); } }
public void ReceiveErrorAnswer() { var service = Guid.NewGuid().ToString() + ".local"; var done = new ManualResetEvent(false); var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => mdns.SendQuery(service); mdns.QueryReceived += (s, e) => { var msg = e.Message; if (msg.Questions.Any(q => q.Name == service)) { var res = msg.CreateResponse(); res.Status = MessageStatus.Refused; res.Answers.Add(new ARecord { Name = service, Address = IPAddress.Parse("127.1.1.1") }); mdns.SendAnswer(res); } }; mdns.AnswerReceived += (s, e) => { var msg = e.Message; if (msg.Answers.Any(a => a.Name == service)) { done.Set(); } }; try { mdns.Start(); Assert.IsFalse(done.WaitOne(TimeSpan.FromSeconds(0.5)), "answer was not ignored"); } finally { mdns.Stop(); } }
public void Discover_ServiceInstance_WithAnswersContainingAdditionRecords() { var service = new ServiceProfile("y", "_sdtest-2._udp", 1024); var done = new ManualResetEvent(false); var mdns = new MulticastService(); var sd = new ServiceDiscovery(mdns) { AnswersContainsAdditionalRecords = true }; Message discovered = null; mdns.NetworkInterfaceDiscovered += (s, e) => { sd.QueryServiceInstances(service.ServiceName); }; sd.ServiceInstanceDiscovered += (s, e) => { if (e.ServiceInstanceName == service.FullyQualifiedName) { Assert.IsNotNull(e.Message); discovered = e.Message; done.Set(); } }; try { sd.Advertise(service); mdns.Start(); Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "instance not found"); Assert.AreEqual(0, discovered.AdditionalRecords.Count); Assert.IsTrue(discovered.Answers.Count > 1); } finally { sd.Dispose(); mdns.Stop(); } }
public void Nics() { var done = new ManualResetEvent(false); var mdns = new MulticastService(); IEnumerable <NetworkInterface> nics = null; mdns.NetworkInterfaceDiscovered += (s, e) => { nics = e.NetworkInterfaces; done.Set(); }; mdns.Start(); try { Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "timeout"); Assert.IsTrue(nics.Count() > 0); } finally { mdns.Stop(); } }
public void SendNonQuery() { var query = new Message { Opcode = MessageOperation.Status, QR = false }; var done = new ManualResetEvent(false); var mdns = new MulticastService(); mdns.NetworkInterfaceDiscovered += (s, e) => mdns.SendQuery(query); mdns.QueryReceived += (s, e) => done.Set(); try { mdns.Start(); Assert.IsFalse(done.WaitOne(TimeSpan.FromSeconds(0.5)), "query was not ignored"); } finally { mdns.Stop(); } }
public async Task Resolve() { var service = Guid.NewGuid().ToString() + ".local"; var query = new Message(); query.Questions.Add(new Question { Name = service, Type = DnsType.ANY }); var cancellation = new CancellationTokenSource(2000); using (var mdns = new MulticastService()) { mdns.QueryReceived += (s, e) => { var msg = e.Message; if (msg.Questions.Any(q => q.Name == service)) { var res = msg.CreateResponse(); res.Answers.Add(new ARecord { Name = service, Address = IPAddress.Parse("127.1.1.1") }); mdns.SendAnswer(res); } }; mdns.Start(); var response = await mdns.ResolveAsync(query, cancellation.Token); Assert.IsNotNull(response, "no response"); Assert.IsTrue(response.IsResponse); Assert.AreEqual(MessageStatus.NoError, response.Status); Assert.IsTrue(response.AA); var a = (ARecord)response.Answers[0]; Assert.AreEqual(IPAddress.Parse("127.1.1.1"), a.Address); } }