private DhtRpcPacket Query(DhtRpcPacket query, NodeContact contact) { if (_currentNode.NodeEP.AddressFamily != contact.NodeEP.AddressFamily) { return(null); } Stream s = null; try { s = _manager.GetConnectionStream(contact.NodeEP); //set timeout s.WriteTimeout = QUERY_TIMEOUT; s.ReadTimeout = QUERY_TIMEOUT; //send query query.WriteTo(s); s.Flush(); //read response DhtRpcPacket response = new DhtRpcPacket(s); //auto add contact or update last seen time { NodeContact bucketContact = _routingTable.FindContact(contact.NodeID); if (bucketContact == null) { contact.UpdateLastSeenTime(); _routingTable.AddContact(contact); } else { bucketContact.UpdateLastSeenTime(); } } return(response); } catch { contact.IncrementRpcFailCount(); return(null); } finally { if (s != null) { s.Dispose(); } } }
private DhtRpcPacket Query(DhtRpcPacket packet, NodeContact contact) { Transaction transaction = new Transaction(contact.NodeID, contact.NodeEP); try { lock (_transactions) { _transactions.Add(packet.TransactionID, transaction); } lock (transaction) { lock (_sendBufferStream) { _sendBufferStream.Position = 0; packet.WriteTo(_sendBufferStream); if (_proxyEnabled) { _manager.SendDhtPacket(contact.NodeEP, _sendBufferStream.Buffer, 0, (int)_sendBufferStream.Position); } else { _udpClient.SendTo(_sendBufferStream.Buffer, 0, (int)_sendBufferStream.Position, SocketFlags.None, contact.NodeEP); } } if (!Monitor.Wait(transaction, QUERY_TIMEOUT)) { contact.IncrementRpcFailCount(); return(null); } //auto add contact or update last seen time if (contact.NodeID == null) { contact = transaction.ResponsePacket.SourceNode; } KBucket closestBucket = _routingTable.FindClosestBucket(contact.NodeID); NodeContact bucketContact = closestBucket.FindContactInCurrentBucket(contact.NodeID); if (bucketContact == null) { closestBucket.AddContactInCurrentBucket(contact); } else { bucketContact.UpdateLastSeenTime(); } return(transaction.ResponsePacket); } } finally { lock (_transactions) { _transactions.Remove(packet.TransactionID); } } }
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); } }