Beispiel #1
0
        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();
            }
        }
Beispiel #4
0
        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();
            }
        }
Beispiel #5
0
        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();
            }
        }
Beispiel #6
0
        public void StartStop()
        {
            var mdns = new MulticastService();

            mdns.Start();
            mdns.Stop();
        }
Beispiel #7
0
        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();
            }
        }
Beispiel #8
0
        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();
            }
        }
Beispiel #10
0
        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();
            }
        }
Beispiel #11
0
        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();
            }
        }
Beispiel #12
0
        public void Disposable()
        {
            using (var mdns = new MulticastService())
            {
                Assert.IsNotNull(mdns);
            }

            using (var mdns = new MulticastService())
            {
                Assert.IsNotNull(mdns);
                mdns.Start();
            }
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #14
0
        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();
            }
        }
Beispiel #15
0
        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);
            }
        }
Beispiel #16
0
        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();
            }
        }
Beispiel #18
0
        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");
                }
        }
Beispiel #19
0
        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();
            }
        }
Beispiel #20
0
        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;
                });
            }
        }
Beispiel #21
0
        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();
            }
        }
Beispiel #22
0
        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();
            }
        }
Beispiel #23
0
        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();
            }
        }
Beispiel #24
0
        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();
            }
        }
Beispiel #25
0
        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);
            }
        }