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); }
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); } }
// Enforce multicast defaults, especially TTL. static ServiceProfile() { // Make sure MulticastService is inited. MulticastService.ReferenceEquals(null, null); }