Пример #1
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);
                }
            }
        }
Пример #2
0
        public bool AddContact(NodeContact contact)
        {
            KBucket currentBucket = this;

            while (true)
            {
                NodeContact[] contacts    = currentBucket._contacts;
                KBucket       leftBucket  = currentBucket._leftBucket;
                KBucket       rightBucket = currentBucket._rightBucket;

                lock (currentBucket)
                {
                    if ((contacts != null) || (leftBucket == null) || (rightBucket == null))
                    {
                        #region  add contact in this bucket

                        //search if contact already exists
                        for (int i = 0; i < contacts.Length; i++)
                        {
                            if (contact.Equals(contacts[i]))
                            {
                                return(false); //contact already exists
                            }
                        }

                        //try add contact
                        for (int i = 0; i < contacts.Length; i++)
                        {
                            if (contacts[i] == null)
                            {
                                contacts[i] = contact;
                                currentBucket._contactCount++;
                                currentBucket._lastChanged = DateTime.UtcNow;
                                return(true);
                            }
                        }

                        //k-bucket is full so contact was not added

                        //if current contact is not stale then find and replace with any existing stale contact
                        if (!contact.IsStale())
                        {
                            for (int i = 0; i < contacts.Length; i++)
                            {
                                if (contacts[i].IsStale())
                                {
                                    contacts[i] = contact;
                                    currentBucket._lastChanged = DateTime.UtcNow;
                                    return(true);
                                }
                            }
                        }

                        //no stale contact in this k-bucket to replace!
                        if (contacts[0].IsCurrentNode)
                        {
                            //split current bucket and add contact!
                            SplitBucket(currentBucket, contact);
                            return(true);
                        }
                        else
                        {
                            //k-bucket is full!
                            return(false);
                        }
                        #endregion
                    }
                }

                if ((leftBucket._bucketID & contact.NodeID) == leftBucket._bucketID)
                {
                    currentBucket = leftBucket;
                }
                else
                {
                    currentBucket = rightBucket;
                }
            }
        }
Пример #3
0
        public bool RemoveContact(NodeContact contact)
        {
            KBucket currentBucket = this;

            while (true)
            {
                NodeContact[] contacts    = currentBucket._contacts;
                KBucket       leftBucket  = currentBucket._leftBucket;
                KBucket       rightBucket = currentBucket._rightBucket;

                lock (currentBucket)
                {
                    if ((contacts != null) || (leftBucket == null) || (rightBucket == null))
                    {
                        #region remove contact from this bucket

                        if (currentBucket._contactCount <= DhtNode.KADEMLIA_K)
                        {
                            return(false); //k-bucket is not full and replacement cache is empty
                        }
                        bool contactRemoved = false;

                        for (int i = 0; i < contacts.Length; i++)
                        {
                            if (contact.Equals(contacts[i]))
                            {
                                if (contacts[i].IsStale())
                                {
                                    //remove stale contact
                                    contacts[i] = null;
                                    currentBucket._contactCount--;
                                    currentBucket._lastChanged = DateTime.UtcNow;
                                    contactRemoved             = true;
                                }

                                break;
                            }
                        }

                        if (!contactRemoved)
                        {
                            return(false); //contact was not found or was not stale
                        }
                        //check parent bucket contact count and join the parent bucket
                        if (currentBucket._parentBucket != null)
                        {
                            JoinBucket(currentBucket._parentBucket);
                        }

                        return(true);

                        #endregion
                    }
                }

                if ((leftBucket._bucketID & contact.NodeID) == leftBucket._bucketID)
                {
                    currentBucket = leftBucket;
                }
                else
                {
                    currentBucket = rightBucket;
                }
            }
        }
Пример #4
0
        public bool RemoveContact(NodeContact contact)
        {
            KBucket currentBucket = this;

            while (true)
            {
                NodeContact[] contacts;
                KBucket       leftBucket;
                KBucket       rightBucket;

                lock (currentBucket)
                {
                    contacts    = currentBucket._contacts;
                    leftBucket  = currentBucket._leftBucket;
                    rightBucket = currentBucket._rightBucket;

                    if (contacts != null)
                    {
                        #region remove contact from this bucket

                        if (currentBucket._contactCount <= DhtNode.KADEMLIA_K)
                        {
                            return(false); //k-bucket is not full and replacement cache is empty
                        }
                        for (int i = 0; i < contacts.Length; i++)
                        {
                            if (contact.Equals(contacts[i]))
                            {
                                if (contacts[i].IsStale())
                                {
                                    //remove stale contact
                                    contacts[i] = null;
                                    currentBucket._lastChanged = DateTime.UtcNow;

                                    KBucket bucket = currentBucket;
                                    do
                                    {
                                        Interlocked.Decrement(ref bucket._contactCount);
                                        bucket = bucket._parentBucket;
                                    }while (bucket != null);

                                    return(true);
                                }

                                break;
                            }
                        }

                        return(false); //contact was not found or was not stale

                        #endregion
                    }
                }

                if ((leftBucket._bucketID & contact.NodeID) == leftBucket._bucketID)
                {
                    currentBucket = leftBucket;
                }
                else
                {
                    currentBucket = rightBucket;
                }
            }
        }