public Task Start()
        {
            _mdns.QueryReceived += _mdns_QueryReceived;

            var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

            foreach (var network in networkInterfaces)
            {
                _logger.LogDebug(
                    $"Interface {network.Name}, Type {network.NetworkInterfaceType}, OP Status {network.OperationalStatus}, IP {network.GetIPProperties().UnicastAddresses.FirstOrDefault()}");
            }

            var weUseAddresses = MulticastService.GetIpAddresses();

            foreach (var ip in weUseAddresses)
            {
                _logger.LogDebug($"We use {ip}");
            }

            var startMessage = new Message();
            startMessage.AuthorityRecords.Add(new SRVRecord
            {
                Name = $"{_name}.{DnsHapDomain}",
                Port = _port,
                Target = $"{_hapId.Replace(":", "_")}.local"
            });

            var q = new Question
            {
                Type = DnsType.ANY,
                Name = $"{_name}.{DnsHapDomain}",
                QU = true,
                Class = DnsClass.IN
            };
            startMessage.Questions.Add(q);

            _mdns.Start();

#pragma warning disable 4014
            Task.Run(async () =>
            {
                _mdns.SendQuery(startMessage);
                await Task.Delay(1000);
                q.QU = false;
                _mdns.SendQuery(startMessage);
                await Task.Delay(1000);
                _mdns.SendQuery(startMessage);
                await Task.Delay(1000);
            }).ConfigureAwait(false);
#pragma warning restore 4014
            return Task.CompletedTask;
        }
        /// <summary>
        ///    Sends an unsolicited MDNS response describing the
        ///    service profile.
        /// </summary>
        /// <param name="profile">
        ///   The profile to describe.
        /// </param>
        /// <remarks>
        ///   Sends a MDNS response <see cref="Message"/> containing the pointer
        ///   and resource records of the <paramref name="profile"/>.
        ///   <para>
        ///   To provide increased robustness against packet loss,
        ///   two unsolicited responses are sent one second apart.
        ///   </para>
        /// </remarks>
        public void Announce(ServiceProfile profile)
        {
            var message = new Message {
                QR = true
            };

            // Add the shared records.
            var ptrRecord = new PTRRecord {
                Name = profile.QualifiedServiceName, DomainName = profile.FullyQualifiedName
            };

            message.Answers.Add(ptrRecord);

            // Add the resource records.
            profile.Resources.ForEach((resource) =>
            {
                message.Answers.Add(resource);
            });

            message.Questions.Add(new Question()
            {
                Name  = profile.ServiceName,
                Class = DnsClass.IN,
                Type  = DnsType.PTR
            });

            foreach (var ip in MulticastService.GetLinkLocalAddresses())
            {
                message.AdditionalRecords.Add(new ARecord()
                {
                    Class   = DnsClass.IN,
                    Type    = DnsType.A,
                    Name    = profile.ServiceName,
                    Address = ip,
                    TTL     = TimeSpan.FromSeconds(120)
                });
            }

            Mdns.Send(message, false);
            Task.Delay(1000).Wait();
            Mdns.Send(message, false);
        }
Example #3
0
        private void _mdns_QueryReceived(object sender, MessageEventArgs e)
        {
            if (e.Message.IsQuery &&
                (e.Message.Questions.Any(a => a.Name.Labels.Contains(HapName))) ||
                e.Message.Questions.Any(a => a.Name == ServiceDiscovery.ServiceName))
            {
                var localAddresses = MulticastService.GetIpAddresses();
                var dnsMessage     = GenerateQueryResponseMessage();

                foreach (var localAddress in localAddresses)
                {
                    if (localAddress.AddressFamily == AddressFamily.InterNetwork)
                    {
                        dnsMessage.Answers.Add(new ARecord
                        {
                            Name    = $"{_hapId.Replace(":", "_")}.local",
                            Address = localAddress,
                            Class   = DnsClass.IN,
                            Type    = DnsType.A,
                            TTL     = TimeSpan.FromMinutes(2)
                        });
                    }
                    else if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        dnsMessage.Answers.Add(new AAAARecord
                        {
                            Name    = $"{_hapId.Replace(":", "_")}.local",
                            Address = localAddress,
                            Class   = DnsClass.IN,
                            Type    = DnsType.AAAA,
                            TTL     = TimeSpan.FromMinutes(2)
                        });
                    }
                }

                _mdns.SendAnswer(dnsMessage, e);
            }
        }
Example #4
0
 // Enforce multicast defaults, especially TTL.
 static ServiceProfile()
 {
     // Make sure MulticastService is inited.
     MulticastService.ReferenceEquals(null, null);
 }