diff --git a/TinyDNS/MDNS.cs b/TinyDNS/MDNS.cs index ffad172..998d83e 100644 --- a/TinyDNS/MDNS.cs +++ b/TinyDNS/MDNS.cs @@ -11,6 +11,7 @@ // along with this program. If not, see . using System.Buffers; +using System.Collections.Concurrent; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; @@ -32,6 +33,7 @@ public class MDNS : IDisposable private Socket? listenerV4; private Socket? listenerV6; private readonly List senders = []; + private readonly ConcurrentDictionary multicastAddressV6Scoped = []; public delegate Task MessageEventHandler(DNSMessageEvent e); public event MessageEventHandler? AnswerReceived; @@ -441,7 +443,7 @@ private async Task SendMessage(Message msg) if (sender.AddressFamily == AddressFamily.InterNetwork) await sender.SendToAsync(buffer.Slice(0, len), SocketFlags.None, new IPEndPoint(MulticastAddress, PORT), stop.Token); else - await sender.SendToAsync(buffer.Slice(0, len), SocketFlags.None, new IPEndPoint(MulticastAddressV6, PORT), stop.Token); + await sender.SendToAsync(buffer.Slice(0, len), SocketFlags.None, new IPEndPoint(GetMulticastAddressV6(sender.LocalEndPoint), PORT), stop.Token); await Task.Delay(5); } }finally @@ -450,6 +452,15 @@ private async Task SendMessage(Message msg) } } + private IPAddress GetMulticastAddressV6(EndPoint? endPoint) + { + if (endPoint is not IPEndPoint { Address.IsIPv6LinkLocal: true } ip) + return MulticastAddressV6; + + Func factory = scope => new IPAddress(new byte[] { 0xFF, 0x02, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFB }, scope); + return multicastAddressV6Scoped.GetOrAdd(ip.Address.ScopeId, factory); + } + public void Stop() { stop.Cancel();