private void ProcessUdpRequestAsync(object parameter) { object[] parameters = parameter as object[]; Socket udpListener = parameters[0] as Socket; EndPoint remoteEP = parameters[1] as EndPoint; IPPacketInformation ipPacketInformation = (IPPacketInformation)parameters[2]; DhcpMessage request = parameters[3] as DhcpMessage; try { DhcpMessage response = ProcessDhcpMessage(request, remoteEP as IPEndPoint, ipPacketInformation); //send response if (response != null) { byte[] sendBuffer = new byte[1024]; MemoryStream sendBufferStream = new MemoryStream(sendBuffer); response.WriteTo(sendBufferStream); //send dns datagram if (!request.RelayAgentIpAddress.Equals(IPAddress.Any)) { //received request via relay agent so send unicast response to relay agent on port 67 udpListener.SendTo(sendBuffer, 0, (int)sendBufferStream.Position, SocketFlags.None, new IPEndPoint(request.RelayAgentIpAddress, 67)); } else if (!request.ClientIpAddress.Equals(IPAddress.Any)) { //client is already configured and renewing lease so send unicast response on port 68 udpListener.SendTo(sendBuffer, 0, (int)sendBufferStream.Position, SocketFlags.None, new IPEndPoint(request.ClientIpAddress, 68)); } else { //send response as broadcast on port 68 on appropriate interface bound socket if (!_udpListeners.TryGetValue(response.NextServerIpAddress, out Socket udpSocket)) { udpSocket = udpListener; //no appropriate socket found so use default socket } udpSocket.SendTo(sendBuffer, 0, (int)sendBufferStream.Position, SocketFlags.DontRoute, new IPEndPoint(IPAddress.Broadcast, 68)); //no routing for broadcast } } } catch (ObjectDisposedException) { //socket disposed } catch (Exception ex) { if ((_state == ServiceState.Stopping) || (_state == ServiceState.Stopped)) { return; //server stopping } LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, ex); } } }
private async Task ProcessDhcpRequestAsync(DhcpMessage request, IPEndPoint remoteEP, IPPacketInformation ipPacketInformation, Socket udpListener) { try { DhcpMessage response = await ProcessDhcpMessageAsync(request, remoteEP, ipPacketInformation); //send response if (response != null) { byte[] sendBuffer = new byte[1024]; MemoryStream sendBufferStream = new MemoryStream(sendBuffer); response.WriteTo(sendBufferStream); //send dns datagram if (!request.RelayAgentIpAddress.Equals(IPAddress.Any)) { //received request via relay agent so send unicast response to relay agent on port 67 await udpListener.SendToAsync(sendBuffer, 0, (int)sendBufferStream.Position, new IPEndPoint(request.RelayAgentIpAddress, 67)); } else if (!request.ClientIpAddress.Equals(IPAddress.Any)) { //client is already configured and renewing lease so send unicast response on port 68 await udpListener.SendToAsync(sendBuffer, 0, (int)sendBufferStream.Position, new IPEndPoint(request.ClientIpAddress, 68)); } else { Socket udpSocket; //send response as broadcast on port 68 on appropriate interface bound socket if (_udpListeners.TryGetValue(response.NextServerIpAddress, out UdpListener listener)) { udpSocket = listener.Socket; //found scope specific socket } else { udpSocket = udpListener; //no appropriate socket found so use default socket } await udpSocket.SendToAsync(sendBuffer, 0, (int)sendBufferStream.Position, new IPEndPoint(IPAddress.Broadcast, 68), SocketFlags.DontRoute); //no routing for broadcast } } } catch (ObjectDisposedException) { //socket disposed } catch (Exception ex) { if ((_state == ServiceState.Stopping) || (_state == ServiceState.Stopped)) { return; //server stopping } LogManager log = _log; if (log != null) { log.Write(remoteEP, ex); } } }