private void ProcessTcpRequestAsync(object parameter) { Socket tcpSocket = parameter as Socket; DnsDatagram request = null; try { NetworkStream recvStream = new NetworkStream(tcpSocket); OffsetStream recvDatagramStream = new OffsetStream(recvStream, 0, 0); MemoryStream sendBufferStream = null; byte[] sendBuffer = null; ushort length; while (true) { //read dns datagram length { byte[] lengthBuffer = recvStream.ReadBytes(2); Array.Reverse(lengthBuffer, 0, 2); length = BitConverter.ToUInt16(lengthBuffer, 0); } //read dns datagram recvDatagramStream.Reset(0, length, 0); request = new DnsDatagram(recvDatagramStream); DnsDatagram response = ProcessQuery(request, tcpSocket.RemoteEndPoint); //send response if (response != null) { if (sendBufferStream == null) { sendBufferStream = new MemoryStream(64); } //write dns datagram sendBufferStream.Position = 0; response.WriteTo(sendBufferStream); //prepare final buffer length = Convert.ToUInt16(sendBufferStream.Position); if ((sendBuffer == null) || (sendBuffer.Length < length + 2)) { sendBuffer = new byte[length + 2]; } //copy datagram length byte[] lengthBuffer = BitConverter.GetBytes(length); sendBuffer[0] = lengthBuffer[1]; sendBuffer[1] = lengthBuffer[0]; //copy datagram sendBufferStream.Position = 0; sendBufferStream.Read(sendBuffer, 2, length); //send dns datagram tcpSocket.Send(sendBuffer, 0, length + 2, SocketFlags.None); LogManager queryLog = _queryLog; if (queryLog != null) { queryLog.Write(tcpSocket.RemoteEndPoint as IPEndPoint, true, request, response); } StatsManager stats = _stats; if (stats != null) { stats.Update(response, (tcpSocket.RemoteEndPoint as IPEndPoint).Address); } } } } catch (IOException) { //ignore IO exceptions } catch (Exception ex) { LogManager queryLog = _queryLog; if ((queryLog != null) && (request != null)) { queryLog.Write(tcpSocket.RemoteEndPoint as IPEndPoint, true, request, null); } LogManager log = _log; if (log != null) { log.Write(tcpSocket.RemoteEndPoint as IPEndPoint, ex); } } finally { if (tcpSocket != null) { tcpSocket.Dispose(); } } }
private void ProcessUdpRequestAsync(object parameter) { object[] parameters = parameter as object[]; EndPoint remoteEP = parameters[0] as EndPoint; DnsDatagram request = parameters[1] as DnsDatagram; try { DnsDatagram response = ProcessQuery(request, remoteEP); //send response if (response != null) { byte[] sendBuffer = new byte[512]; MemoryStream sendBufferStream = new MemoryStream(sendBuffer); try { response.WriteTo(sendBufferStream); } catch (NotSupportedException) { DnsHeader header = response.Header; response = new DnsDatagram(new DnsHeader(header.Identifier, true, header.OPCODE, header.AuthoritativeAnswer, true, header.RecursionDesired, header.RecursionAvailable, header.AuthenticData, header.CheckingDisabled, header.RCODE, header.QDCOUNT, 0, 0, 0), response.Question, null, null, null); sendBufferStream.Position = 0; response.WriteTo(sendBufferStream); } //send dns datagram _udpListener.SendTo(sendBuffer, 0, (int)sendBufferStream.Position, SocketFlags.None, remoteEP); LogManager queryLog = _queryLog; if (queryLog != null) { queryLog.Write(remoteEP as IPEndPoint, false, request, response); } StatsManager stats = _stats; if (stats != null) { stats.Update(response, (remoteEP as IPEndPoint).Address); } } } catch (Exception ex) { LogManager queryLog = _queryLog; if (queryLog != null) { queryLog.Write(remoteEP as IPEndPoint, false, request, null); } LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, ex); } } }