コード例 #1
0
ファイル: DhtNode.cs プロジェクト: willvin313/BitChatClient
        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.");
            }
        }
コード例 #2
0
        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);
        }