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 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 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 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 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 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 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 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 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(); } }