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) { FixMemoryStream sendBufferStream = new FixMemoryStream(512); try { response.WriteTo(sendBufferStream); } catch (EndOfStreamException) { 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(sendBufferStream.Buffer, 0, (int)sendBufferStream.Position, SocketFlags.None, remoteEP); LogManager queryLog = _queryLog; if (queryLog != null) { queryLog.Write((IPEndPoint)remoteEP, false, request, response); } } } catch (Exception ex) { LogManager queryLog = _queryLog; if (queryLog != null) { queryLog.Write((IPEndPoint)remoteEP, false, request, null); } LogManager log = _log; if (log != null) { log.Write((IPEndPoint)remoteEP, ex); } } }
private void ReadResponsePacketsAsync(object parameter) { Socket udpClient = parameter as Socket; EndPoint remoteEP; FixMemoryStream recvStream = new FixMemoryStream(BUFFER_MAX_SIZE); byte[] bufferRecv = recvStream.Buffer; int bytesRecv; if (udpClient.AddressFamily == AddressFamily.InterNetwork) { remoteEP = new IPEndPoint(IPAddress.Any, 0); } else { remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); } try { while (true) { bytesRecv = udpClient.ReceiveFrom(bufferRecv, ref remoteEP); if (bytesRecv > 0) { recvStream.SetLength(bytesRecv); recvStream.Position = 0; IPEndPoint remoteNodeEP = remoteEP as IPEndPoint; if (NetUtilities.IsIPv4MappedIPv6Address(remoteNodeEP.Address)) { remoteNodeEP = new IPEndPoint(NetUtilities.ConvertFromIPv4MappedIPv6Address(remoteNodeEP.Address), remoteNodeEP.Port); } try { DhtRpcPacket response = new DhtRpcPacket(recvStream, remoteNodeEP.Address); ProcessPacket(response); } catch { } } } } catch (Exception ex) { Debug.Write("DhtClient.ReadResponsePacketsAsync", ex); } }
private void RecvDataAsync(object parameter) { Socket udpListener = parameter as Socket; EndPoint remoteEP = null; FixMemoryStream dataRecv = new FixMemoryStream(BUFFER_MAX_SIZE); int bytesRecv; if (udpListener.AddressFamily == AddressFamily.InterNetwork) { remoteEP = new IPEndPoint(IPAddress.Any, 0); } else { remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); } try { while (true) { //receive message from remote bytesRecv = udpListener.ReceiveFrom(dataRecv.Buffer, ref remoteEP); if (bytesRecv > 0) { IPAddress peerIP = (remoteEP as IPEndPoint).Address; if (NetUtilities.IsIPv4MappedIPv6Address(peerIP)) { peerIP = NetUtilities.ConvertFromIPv4MappedIPv6Address(peerIP); } dataRecv.Position = 0; dataRecv.SetLength(bytesRecv); try { ReceivedPacket(new DiscoveryPacket(dataRecv), peerIP); } catch (Exception ex) { Debug.Write("LocalPeerDiscovery.Listner.RecvDataAsync", ex); } } } } catch (Exception ex) { Debug.Write("LocalPeerDiscovery.Listner.RecvDataAsync", ex); } }
private void ReadQueryPacketsAsync(object parameter) { Socket udpListener = parameter as Socket; EndPoint remoteEP; FixMemoryStream recvBufferStream = new FixMemoryStream(BUFFER_MAX_SIZE); FixMemoryStream sendBufferStream = new FixMemoryStream(BUFFER_MAX_SIZE); int bytesRecv; if (udpListener.AddressFamily == AddressFamily.InterNetwork) { remoteEP = new IPEndPoint(IPAddress.Any, 0); } else { remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); } try { while (true) { bytesRecv = udpListener.ReceiveFrom(recvBufferStream.Buffer, ref remoteEP); if (bytesRecv > 0) { recvBufferStream.Position = 0; recvBufferStream.SetLength(bytesRecv); IPEndPoint remoteNodeEP = remoteEP as IPEndPoint; if (NetUtilities.IsIPv4MappedIPv6Address(remoteNodeEP.Address)) { remoteNodeEP = new IPEndPoint(NetUtilities.ConvertFromIPv4MappedIPv6Address(remoteNodeEP.Address), remoteNodeEP.Port); } try { DhtRpcPacket request = new DhtRpcPacket(recvBufferStream, remoteNodeEP.Address); DhtRpcPacket response = ProcessPacket(request); //send response if (response != null) { sendBufferStream.Position = 0; response.WriteTo(sendBufferStream); udpListener.SendTo(sendBufferStream.Buffer, 0, (int)sendBufferStream.Position, SocketFlags.None, remoteEP); } //if contact doesnt exists then add contact else update last seen time KBucket closestBucket = _routingTable.FindClosestBucket(request.SourceNode.NodeID); NodeContact contact = closestBucket.FindContactInCurrentBucket(request.SourceNode.NodeID); if (contact == null) { //check if the closest bucket can accomodate another contact if (!closestBucket.IsCurrentBucketFull(true)) { ThreadPool.QueueUserWorkItem(AddContactAfterPingAsync, request.SourceNode); } } else { contact.UpdateLastSeenTime(); } } catch { } } } } catch (Exception ex) { Debug.Write("DhtClient.ReadQueryPacketsAsync", ex); } }
private void ProcessTcpRequestAsync(object parameter) { Socket tcpSocket = parameter as Socket; DnsDatagram request = null; try { FixMemoryStream recvBufferStream = new FixMemoryStream(128); MemoryStream sendBufferStream = new MemoryStream(512); int bytesRecv; while (true) { //read dns datagram length bytesRecv = tcpSocket.Receive(recvBufferStream.Buffer, 0, 2, SocketFlags.None); if (bytesRecv < 1) { return; //do nothing } Array.Reverse(recvBufferStream.Buffer, 0, 2); short length = BitConverter.ToInt16(recvBufferStream.Buffer, 0); //read dns datagram int offset = 0; while (offset < length) { bytesRecv = tcpSocket.Receive(recvBufferStream.Buffer, offset, length, SocketFlags.None); if (bytesRecv < 1) { throw new SocketException(); } offset += bytesRecv; } bytesRecv = length; if (bytesRecv > 0) { recvBufferStream.Position = 0; recvBufferStream.SetLength(bytesRecv); request = new DnsDatagram(recvBufferStream); DnsDatagram response = ProcessQuery(request, tcpSocket.RemoteEndPoint); //send response if (response != null) { //write dns datagram sendBufferStream.Position = 0; response.WriteTo(sendBufferStream); //prepare final buffer byte[] lengthBytes = BitConverter.GetBytes(Convert.ToInt16(sendBufferStream.Position)); byte[] buffer = new byte[sendBufferStream.Position + 2]; //copy datagram length buffer[0] = lengthBytes[1]; buffer[1] = lengthBytes[0]; //copy datagram sendBufferStream.Position = 0; sendBufferStream.Read(buffer, 2, buffer.Length - 2); //send dns datagram tcpSocket.Send(buffer, 0, buffer.Length, SocketFlags.None); LogManager queryLog = _queryLog; if (queryLog != null) { queryLog.Write((IPEndPoint)tcpSocket.RemoteEndPoint, true, request, response); } } } } } catch (Exception ex) { LogManager queryLog = _queryLog; if ((queryLog != null) && (request != null)) { queryLog.Write((IPEndPoint)tcpSocket.RemoteEndPoint, true, request, null); } LogManager log = _log; if (log != null) { log.Write((IPEndPoint)tcpSocket.RemoteEndPoint, ex); } } finally { if (tcpSocket != null) { tcpSocket.Dispose(); } } }
private void ReadUdpQueryPacketsAsync(object parameter) { #region this code ignores ICMP port unreachable responses which creates SocketException in ReceiveFrom() if (Environment.OSVersion.Platform == PlatformID.Win32NT) { const uint IOC_IN = 0x80000000; const uint IOC_VENDOR = 0x18000000; const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; _udpListener.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); } #endregion EndPoint remoteEP = null; FixMemoryStream recvBufferStream = new FixMemoryStream(128); int bytesRecv; try { while (true) { if (_udpListener.AddressFamily == AddressFamily.InterNetwork) { remoteEP = new IPEndPoint(IPAddress.Any, 0); } else { remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); } try { bytesRecv = _udpListener.ReceiveFrom(recvBufferStream.Buffer, ref remoteEP); } catch (SocketException ex) { switch (ex.SocketErrorCode) { case SocketError.ConnectionReset: case SocketError.HostUnreachable: bytesRecv = 0; break; default: throw; } } if (bytesRecv > 0) { recvBufferStream.Position = 0; recvBufferStream.SetLength(bytesRecv); try { ThreadPool.QueueUserWorkItem(ProcessUdpRequestAsync, new object[] { remoteEP, new DnsDatagram(recvBufferStream) }); } catch { } } } } catch (Exception ex) { LogManager log = _log; if (log != null) { log.Write((IPEndPoint)remoteEP, ex); } if (_state == ServiceState.Running) { throw; } } }