Esempio n. 1
0
        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.");
            }
        }
        public static DhtRpcPacket CreateFindPeersPacketQuery(NodeContact sourceNode, BinaryID networkID)
        {
            DhtRpcPacket packet = new DhtRpcPacket(GetRandomTransactionID(), sourceNode, RpcPacketType.Query, RpcQueryType.FIND_PEERS);

            packet._networkID = networkID;

            return(packet);
        }
        public static DhtRpcPacket CreateAnnouncePeerPacketResponse(int transactionID, NodeContact sourceNode, BinaryID networkID)
        {
            DhtRpcPacket packet = new DhtRpcPacket(transactionID, sourceNode, RpcPacketType.Response, RpcQueryType.ANNOUNCE_PEER);

            packet._networkID = networkID;

            return(packet);
        }
        public static DhtRpcPacket CreateFindNodePacketResponse(int transactionID, NodeContact sourceNode, BinaryID networkID, NodeContact[] contacts)
        {
            DhtRpcPacket packet = new DhtRpcPacket(transactionID, sourceNode, RpcPacketType.Response, RpcQueryType.FIND_NODE);

            packet._networkID = networkID;
            packet._contacts  = contacts;

            return(packet);
        }
        public static DhtRpcPacket CreateAnnouncePeerPacketQuery(NodeContact sourceNode, BinaryID networkID, ushort servicePort, BinaryID token)
        {
            DhtRpcPacket packet = new DhtRpcPacket(GetRandomTransactionID(), sourceNode, RpcPacketType.Query, RpcQueryType.ANNOUNCE_PEER);

            packet._networkID   = networkID;
            packet._servicePort = servicePort;
            packet._token       = token;

            return(packet);
        }
Esempio n. 6
0
        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();
                }
            }
        }
        public static DhtRpcPacket CreateFindPeersPacketResponse(int transactionID, NodeContact sourceNode, BinaryID networkID, NodeContact[] contacts, PeerEndPoint[] peers, BinaryID token)
        {
            DhtRpcPacket packet = new DhtRpcPacket(transactionID, sourceNode, RpcPacketType.Response, RpcQueryType.FIND_PEERS);

            packet._networkID = networkID;
            packet._contacts  = contacts;
            packet._peers     = peers;
            packet._token     = token;

            return(packet);
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
0
 public void AddNode(NodeContact contact)
 {
     if (!NetUtilities.IsPrivateIP(contact.NodeEP.Address) && (contact.NodeEP.AddressFamily == _currentNode.NodeEP.AddressFamily))
     {
         if (_routingTable.AddContact(contact))
         {
             ThreadPool.QueueUserWorkItem(delegate(object state)
             {
                 Query(DhtRpcPacket.CreatePingPacket(_currentNode), contact);
             });
         }
     }
 }
Esempio n. 10
0
        private NodeContact Ping(IPEndPoint nodeEP)
        {
            DhtRpcPacket response = Query(DhtRpcPacket.CreatePingPacketQuery(_currentNode), new NodeContact(null, nodeEP));

            if (response == null)
            {
                return(null);
            }
            else
            {
                return(response.SourceNode);
            }
        }
Esempio n. 11
0
        public byte[] ProcessPacket(byte[] dhtPacket, int offset, int count, IPAddress remoteNodeIP)
        {
            using (MemoryStream mS = new MemoryStream(dhtPacket, offset, count, false))
            {
                DhtRpcPacket response = ProcessPacket(new DhtRpcPacket(mS, remoteNodeIP));

                if (response == null)
                {
                    return(null);
                }

                return(response.ToArray());
            }
        }
Esempio n. 12
0
        private PeerEndPoint[] QueryAnnounce(NodeContact[] initialContacts, BinaryNumber networkID, ushort servicePort)
        {
            NodeContact[] contacts = QueryFindNode(initialContacts, networkID);

            if ((contacts == null) || (contacts.Length == 0))
            {
                return(null);
            }

            List <PeerEndPoint> peers = new List <PeerEndPoint>();

            lock (peers)
            {
                foreach (NodeContact contact in contacts)
                {
                    Thread t = new Thread(delegate(object state)
                    {
                        DhtRpcPacket response = Query(DhtRpcPacket.CreateAnnouncePeerPacketQuery(_currentNode, networkID, servicePort), contact);
                        if ((response != null) && (response.Type == DhtRpcType.ANNOUNCE_PEER) && (response.Peers.Length > 0))
                        {
                            lock (peers)
                            {
                                foreach (PeerEndPoint peer in response.Peers)
                                {
                                    if (!peers.Contains(peer))
                                    {
                                        peers.Add(peer);
                                    }
                                }

                                Monitor.Pulse(peers);
                            }
                        }
                    });

                    t.IsBackground = true;
                    t.Start();
                }

                if (Monitor.Wait(peers, QUERY_TIMEOUT))
                {
                    return(peers.ToArray());
                }

                return(null);
            }
        }
Esempio n. 13
0
        public void AcceptConnection(Stream s, IPAddress remoteNodeIP)
        {
            //set timeout
            s.WriteTimeout = QUERY_TIMEOUT;
            s.ReadTimeout  = QUERY_TIMEOUT;

            while (true)
            {
                DhtRpcPacket response = ProcessQuery(new DhtRpcPacket(s), remoteNodeIP);
                if (response == null)
                {
                    break;
                }

                response.WriteTo(s);
                s.Flush();
            }
        }
Esempio n. 14
0
        internal bool Ping(NodeContact contact)
        {
            DhtRpcPacket response = Query(DhtRpcPacket.CreatePingPacketQuery(_currentNode), contact);

            if (response == null)
            {
                return(false);
            }
            else
            {
                if (contact.Equals(response.SourceNode))
                {
                    return(true);
                }
                else
                {
                    contact.IncrementRpcFailCount();
                    return(false);
                }
            }
        }
Esempio n. 15
0
        private void QueryAnnounceAsync(object state)
        {
            try
            {
                object[] parameters = state as object[];

                NodeContact         contact   = parameters[0] as NodeContact;
                BinaryID            networkID = parameters[1] as BinaryID;
                List <PeerEndPoint> peers     = parameters[2] as List <PeerEndPoint>;
                ushort servicePort            = (ushort)parameters[3];

                DhtRpcPacket responsePacket = Query(DhtRpcPacket.CreateFindPeersPacketQuery(_currentNode, networkID), contact);

                if ((responsePacket != null) && (responsePacket.QueryType == RpcQueryType.FIND_PEERS))
                {
                    if (responsePacket.Peers.Length > 0)
                    {
                        lock (peers)
                        {
                            foreach (PeerEndPoint peer in responsePacket.Peers)
                            {
                                if (!peers.Contains(peer))
                                {
                                    peers.Add(peer);
                                }
                            }

                            //Monitor.Pulse(peers); //removed so that response from multiple nodes is collected till query times out
                        }
                    }

                    Query(DhtRpcPacket.CreateAnnouncePeerPacketQuery(_currentNode, networkID, servicePort, responsePacket.Token), contact);
                }
            }
            catch
            { }
        }
Esempio n. 16
0
        private void QueryFindAsync(object state)
        {
            try
            {
                object[] parameters = state as object[];

                object             lockObj           = parameters[0] as object;
                RpcQueryType       queryType         = (RpcQueryType)parameters[1];
                NodeContact        contact           = parameters[2] as NodeContact;
                BinaryID           nodeID            = parameters[3] as BinaryID;
                List <NodeContact> availableContacts = parameters[4] as List <NodeContact>;
                List <NodeContact> respondedContacts = parameters[5] as List <NodeContact>;
                List <NodeContact> failedContacts    = parameters[6] as List <NodeContact>;
                List <NodeContact> receivedContacts  = parameters[7] as List <NodeContact>;

                DhtRpcPacket responsePacket;

                if (queryType == RpcQueryType.FIND_NODE)
                {
                    responsePacket = Query(DhtRpcPacket.CreateFindNodePacketQuery(_currentNode, nodeID), contact);
                }
                else
                {
                    responsePacket = Query(DhtRpcPacket.CreateFindPeersPacketQuery(_currentNode, nodeID), contact);
                }

                if ((responsePacket == null) || (responsePacket.QueryType != queryType))
                {
                    //time out
                    //add contact to failed contacts
                    lock (failedContacts)
                    {
                        if (!failedContacts.Contains(contact))
                        {
                            failedContacts.Add(contact);
                        }
                    }

                    return;
                }

                //got reply!
                switch (queryType)
                {
                case RpcQueryType.FIND_NODE:
                    lock (receivedContacts)
                    {
                        lock (respondedContacts)
                        {
                            //add contact to responded contacts list
                            if (!respondedContacts.Contains(contact))
                            {
                                respondedContacts.Add(contact);
                            }

                            lock (failedContacts)
                            {
                                //add received contacts to received contacts list
                                foreach (NodeContact receivedContact in responsePacket.Contacts)
                                {
                                    if (!respondedContacts.Contains(receivedContact) && !failedContacts.Contains(receivedContact))
                                    {
                                        receivedContacts.Add(receivedContact);
                                    }
                                }
                            }
                        }

                        //add received contacts to available contacts list
                        lock (availableContacts)
                        {
                            foreach (NodeContact receivedContact in receivedContacts)
                            {
                                if (!availableContacts.Contains(receivedContact))
                                {
                                    availableContacts.Add(receivedContact);
                                }
                            }
                        }
                    }

                    if (responsePacket.Contacts.Length > 0)
                    {
                        //pulse only if the contact has sent next level contacts list
                        lock (lockObj)
                        {
                            Monitor.Pulse(lockObj);
                        }
                    }
                    break;

                case RpcQueryType.FIND_PEERS:
                    if (responsePacket.Peers.Length > 0)
                    {
                        List <PeerEndPoint> receivedPeers = parameters[8] as List <PeerEndPoint>;

                        lock (receivedPeers)
                        {
                            foreach (PeerEndPoint peer in responsePacket.Peers)
                            {
                                if (!receivedPeers.Contains(peer))
                                {
                                    receivedPeers.Add(peer);
                                }
                            }
                        }

                        lock (lockObj)
                        {
                            Monitor.Pulse(lockObj);
                        }
                    }
                    break;
                }
            }
            catch
            { }
        }
Esempio n. 17
0
        private object QueryFind(NodeContact[] initialContacts, BinaryNumber nodeID, DhtRpcType queryType)
        {
            if (initialContacts.Length < 1)
            {
                return(null);
            }

            List <NodeContact>  seenContacts = new List <NodeContact>(initialContacts);
            List <NodeContact>  learnedNotQueriedContacts = new List <NodeContact>(initialContacts);
            List <NodeContact>  respondedContacts         = new List <NodeContact>();
            List <PeerEndPoint> receivedPeers             = null;
            int  alpha      = KADEMLIA_ALPHA;
            bool finalRound = false;
            bool checkTerminationCondition = false;

            if (queryType == DhtRpcType.FIND_PEERS)
            {
                receivedPeers = new List <PeerEndPoint>();
            }

            NodeContact previousClosestSeenContact = KBucket.SelectClosestContacts(seenContacts, nodeID, 1)[0];

            while (true)
            {
                NodeContact[] alphaContacts;

                //pick alpha contacts to query from learned contacts
                lock (learnedNotQueriedContacts)
                {
                    alphaContacts = KBucket.SelectClosestContacts(learnedNotQueriedContacts, nodeID, alpha);

                    //remove selected alpha contacts from learned not queries contacts list
                    foreach (NodeContact alphaContact in alphaContacts)
                    {
                        learnedNotQueriedContacts.Remove(alphaContact);
                    }
                }

                if (alphaContacts.Length < 1)
                {
                    checkTerminationCondition = true;
                }
                else
                {
                    object lockObj = new object();

                    lock (lockObj)
                    {
                        //query each alpha contact async
                        foreach (NodeContact alphaContact in alphaContacts)
                        {
                            Thread t = new Thread(delegate(object state)
                            {
                                DhtRpcPacket response;

                                if (queryType == DhtRpcType.FIND_NODE)
                                {
                                    response = Query(DhtRpcPacket.CreateFindNodePacketQuery(_currentNode, nodeID), alphaContact);
                                }
                                else
                                {
                                    response = Query(DhtRpcPacket.CreateFindPeersPacketQuery(_currentNode, nodeID), alphaContact);
                                }

                                if ((response == null) || (response.Type != queryType))
                                {
                                    //time out or error
                                    //ignore contact by removing from seen contacts list
                                    lock (seenContacts)
                                    {
                                        seenContacts.Remove(alphaContact);
                                    }

                                    return;
                                }

                                //got reply!
                                if ((queryType == DhtRpcType.FIND_PEERS) && (response.Peers.Length > 0))
                                {
                                    lock (receivedPeers)
                                    {
                                        foreach (PeerEndPoint peer in response.Peers)
                                        {
                                            if (!receivedPeers.Contains(peer))
                                            {
                                                receivedPeers.Add(peer);
                                            }
                                        }
                                    }
                                }

                                //add alpha contact to responded contacts list
                                lock (respondedContacts)
                                {
                                    if (!respondedContacts.Contains(alphaContact))
                                    {
                                        respondedContacts.Add(alphaContact);
                                    }
                                }

                                //add received contacts to learned contacts list
                                lock (seenContacts)
                                {
                                    lock (learnedNotQueriedContacts)
                                    {
                                        foreach (NodeContact contact in response.Contacts)
                                        {
                                            if (!seenContacts.Contains(contact))
                                            {
                                                seenContacts.Add(contact);
                                                learnedNotQueriedContacts.Add(contact);
                                            }
                                        }
                                    }
                                }

                                //no pulse for final round to wait for all k contacts to respond. this allows any failed node contact to be removed from seen contacts list during the wait.
                                lock (lockObj)
                                {
                                    Monitor.Pulse(lockObj);
                                }
                            });

                            t.IsBackground = true;
                            t.Start();
                        }

                        //wait for any of the node contact to return new contacts
                        if (Monitor.Wait(lockObj, QUERY_TIMEOUT))
                        {
                            //got reply or final round!

                            NodeContact currentClosestSeenContact;

                            lock (seenContacts)
                            {
                                currentClosestSeenContact = KBucket.SelectClosestContacts(seenContacts, nodeID, 1)[0];
                            }

                            BinaryNumber previousDistance = nodeID ^ previousClosestSeenContact.NodeID;
                            BinaryNumber currentDistance  = nodeID ^ currentClosestSeenContact.NodeID;

                            if (previousDistance <= currentDistance)
                            {
                                //current round failed to return a node contact any closer than the closest already seen
                                if (finalRound)
                                {
                                    //final round over, check for termination condition
                                    checkTerminationCondition = true;
                                }
                                else
                                {
                                    //resend query to k closest node not already queried
                                    finalRound = true;
                                    alpha      = KADEMLIA_K;
                                }
                            }
                            else
                            {
                                //current closest seen contact is closer than previous closest seen contact
                                previousClosestSeenContact = currentClosestSeenContact;
                                finalRound = false;
                                alpha      = KADEMLIA_ALPHA;
                            }
                        }
                    }
                }

                if (checkTerminationCondition)
                {
                    checkTerminationCondition = false; //reset

                    if (queryType == DhtRpcType.FIND_PEERS)
                    {
                        //check only in final round to get most peers
                        lock (receivedPeers)
                        {
                            if (receivedPeers.Count > 0)
                            {
                                return(receivedPeers.ToArray());
                            }

                            return(null);
                        }
                    }

                    //lookup terminates when k closest seen contacts have responded
                    NodeContact[] kClosestSeenContacts;

                    lock (seenContacts)
                    {
                        kClosestSeenContacts = KBucket.SelectClosestContacts(seenContacts, nodeID, KADEMLIA_K);
                    }

                    lock (respondedContacts)
                    {
                        bool success = true;

                        foreach (NodeContact contact in kClosestSeenContacts)
                        {
                            if (!respondedContacts.Contains(contact))
                            {
                                success = false;
                                break;
                            }
                        }

                        if (success)
                        {
                            return(kClosestSeenContacts);
                        }

                        if (alphaContacts.Length < 1)
                        {
                            return(KBucket.SelectClosestContacts(respondedContacts, nodeID, KADEMLIA_K));
                        }
                    }
                }
            }
        }
Esempio n. 18
0
        internal bool Ping(NodeContact contact)
        {
            DhtRpcPacket response = Query(DhtRpcPacket.CreatePingPacket(_currentNode), contact);

            return(response != null);
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
        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);
            }
        }
Esempio n. 21
0
        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);
                }
            }
        }