private DhtRpcPacket ProcessQuery(DhtRpcPacket query, IPAddress remoteNodeIP) { AddNode(new IPEndPoint(remoteNodeIP, query.SourceNodePort)); switch (query.Type) { case DhtRpcType.PING: return(DhtRpcPacket.CreatePingPacket(_currentNode)); case DhtRpcType.FIND_NODE: return(DhtRpcPacket.CreateFindNodePacketResponse(_currentNode, query.NetworkID, _routingTable.GetKClosestContacts(query.NetworkID))); case DhtRpcType.FIND_PEERS: PeerEndPoint[] peers = _currentNode.GetPeers(query.NetworkID); if (peers.Length == 0) { return(DhtRpcPacket.CreateFindPeersPacketResponse(_currentNode, query.NetworkID, _routingTable.GetKClosestContacts(query.NetworkID), peers)); } else { return(DhtRpcPacket.CreateFindPeersPacketResponse(_currentNode, query.NetworkID, new NodeContact[] { }, peers)); } case DhtRpcType.ANNOUNCE_PEER: _currentNode.StorePeer(query.NetworkID, new PeerEndPoint(remoteNodeIP, query.ServicePort)); return(DhtRpcPacket.CreateAnnouncePeerPacketResponse(_currentNode, query.NetworkID, _currentNode.GetPeers(query.NetworkID))); default: throw new Exception("Invalid DHT-RPC type."); } }
private DhtRpcPacket ProcessPacket(DhtRpcPacket packet) { switch (packet.PacketType) { case RpcPacketType.Query: #region Query DhtRpcPacket response = null; switch (packet.QueryType) { case RpcQueryType.PING: #region PING { response = DhtRpcPacket.CreatePingPacketResponse(packet.TransactionID, _currentNode); } #endregion break; case RpcQueryType.FIND_NODE: #region FIND_NODE { NodeContact[] contacts = _routingTable.GetKClosestContacts(packet.NetworkID); response = DhtRpcPacket.CreateFindNodePacketResponse(packet.TransactionID, _currentNode, packet.NetworkID, contacts); } #endregion break; case RpcQueryType.FIND_PEERS: #region GET_PEERS { PeerEndPoint[] peers = _currentNode.GetPeers(packet.NetworkID); NodeContact[] contacts; if (peers.Length < 1) { contacts = _routingTable.GetKClosestContacts(packet.NetworkID); } else { contacts = new NodeContact[] { } }; response = DhtRpcPacket.CreateFindPeersPacketResponse(packet.TransactionID, _currentNode, packet.NetworkID, contacts, peers, GetToken(packet.SourceNode.NodeEP.Address)); } #endregion break; case RpcQueryType.ANNOUNCE_PEER: #region ANNOUNCE_PEER { IPAddress remoteNodeIP = packet.SourceNode.NodeEP.Address; if (IsTokenValid(packet.Token, remoteNodeIP)) { _currentNode.StorePeer(packet.NetworkID, new PeerEndPoint(remoteNodeIP, packet.ServicePort)); } response = DhtRpcPacket.CreateAnnouncePeerPacketResponse(packet.TransactionID, _currentNode, packet.NetworkID); } #endregion break; } return(response); #endregion case RpcPacketType.Response: #region Response Transaction transaction = null; lock (_transactions) { if (_transactions.ContainsKey(packet.TransactionID)) { transaction = _transactions[packet.TransactionID]; } } if ((transaction != null) && ((transaction.RemoteNodeID == null) || transaction.RemoteNodeID.Equals(packet.SourceNode.NodeID)) && transaction.RemoteNodeEP.Equals(packet.SourceNode.NodeEP)) { lock (transaction) { transaction.ResponsePacket = packet; Monitor.Pulse(transaction); } } return(null); #endregion } return(null); }