From 22846011bcee3fab01508f9264ca6da7917173be Mon Sep 17 00:00:00 2001 From: Nicholas Shi Date: Sat, 20 Jun 2026 09:07:54 -0400 Subject: [PATCH 1/3] Add MacOS fix for serving DHCP IP broadcast --- DnsServerCore/Dhcp/DhcpServer.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/DnsServerCore/Dhcp/DhcpServer.cs b/DnsServerCore/Dhcp/DhcpServer.cs index f63e31ee7..1a87129e3 100644 --- a/DnsServerCore/Dhcp/DhcpServer.cs +++ b/DnsServerCore/Dhcp/DhcpServer.cs @@ -261,7 +261,28 @@ private async Task ProcessDhcpRequestAsync(DhcpMessage request, IPEndPoint remot else udpSocket = udpListener; //no appropriate socket found so use default socket - await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.DontRoute, new IPEndPoint(IPAddress.Broadcast, 68)); //no routing for broadcast + if (OperatingSystem.IsMacOS()) + { + //macOS will not select an egress interface for the 255.255.255.255 limited broadcast when + //SocketFlags.DontRoute suppresses the route lookup, so the send fails with NetworkUnreachable. + //Pin the interface the request arrived on (IP_BOUND_IF), then send without DontRoute. + const int IPPROTO_IP = 0; + const int IP_BOUND_IF = 25; + + udpSocket.SetRawSocketOption(IPPROTO_IP, IP_BOUND_IF, BitConverter.GetBytes(ipPacketInformation.Interface)); + try + { + await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, 68)); //interface pinned above + } + finally + { + udpSocket.SetRawSocketOption(IPPROTO_IP, IP_BOUND_IF, BitConverter.GetBytes(0)); //clear binding on this shared socket + } + } + else + { + await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.DontRoute, new IPEndPoint(IPAddress.Broadcast, 68)); //no routing for broadcast + } } } } From 9652fea8852eb0ed7ef3a5307df599e10c88a42c Mon Sep 17 00:00:00 2001 From: Nicholas Shi Date: Sat, 20 Jun 2026 15:47:03 -0400 Subject: [PATCH 2/3] Remove setting socket options --- DnsServerCore/Dhcp/DhcpServer.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/DnsServerCore/Dhcp/DhcpServer.cs b/DnsServerCore/Dhcp/DhcpServer.cs index 1a87129e3..054f14638 100644 --- a/DnsServerCore/Dhcp/DhcpServer.cs +++ b/DnsServerCore/Dhcp/DhcpServer.cs @@ -263,21 +263,7 @@ private async Task ProcessDhcpRequestAsync(DhcpMessage request, IPEndPoint remot if (OperatingSystem.IsMacOS()) { - //macOS will not select an egress interface for the 255.255.255.255 limited broadcast when - //SocketFlags.DontRoute suppresses the route lookup, so the send fails with NetworkUnreachable. - //Pin the interface the request arrived on (IP_BOUND_IF), then send without DontRoute. - const int IPPROTO_IP = 0; - const int IP_BOUND_IF = 25; - - udpSocket.SetRawSocketOption(IPPROTO_IP, IP_BOUND_IF, BitConverter.GetBytes(ipPacketInformation.Interface)); - try - { - await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, 68)); //interface pinned above - } - finally - { - udpSocket.SetRawSocketOption(IPPROTO_IP, IP_BOUND_IF, BitConverter.GetBytes(0)); //clear binding on this shared socket - } + await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, 68)); //interface pinned above } else { From cc05af87e95180e591a02f341a9149ac4a7fbeb6 Mon Sep 17 00:00:00 2001 From: Nicholas Shi Date: Sat, 20 Jun 2026 15:49:00 -0400 Subject: [PATCH 3/3] Remove comment --- DnsServerCore/Dhcp/DhcpServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DnsServerCore/Dhcp/DhcpServer.cs b/DnsServerCore/Dhcp/DhcpServer.cs index 054f14638..e4e270acc 100644 --- a/DnsServerCore/Dhcp/DhcpServer.cs +++ b/DnsServerCore/Dhcp/DhcpServer.cs @@ -263,7 +263,7 @@ private async Task ProcessDhcpRequestAsync(DhcpMessage request, IPEndPoint remot if (OperatingSystem.IsMacOS()) { - await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, 68)); //interface pinned above + await udpSocket.SendToAsync(new ArraySegment(sendBuffer, 0, (int)sendBufferStream.Position), SocketFlags.None, new IPEndPoint(IPAddress.Broadcast, 68)); } else {