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); } } }
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; } } }
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; } } }
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; } } }