private Node GetClosestPrecedingNode(NodeId key) { /* List of all remote peers*/ List<NodeId> mexthop_list = new List<NodeId>(); /* insert all successors into list */ mexthop_list.AddRange(m_successors); /* predecessor is appropriate only if it precedes the given id */ if (m_predecessors.Count > 0) foreach (NodeId pre in m_predecessors) if (key.ElementOfInterval(pre, m_local_node.Id, false)) mexthop_list.AddRange(m_predecessors); /* determine closest preceding reference of finger table */ Node closetPrecedingFinger = GetClosestPrecedingFinger(key); if (closetPrecedingFinger != null) mexthop_list.Add(closetPrecedingFinger.Id); Node closestNode = null; mexthop_list.Add(key); mexthop_list = removeDuplicates(mexthop_list); int sizeOfList = mexthop_list.Count; if (sizeOfList > 1) mexthop_list.Sort(); /* * The list item with one index lower than that of the key must be the * id of the closest predecessor or the key. */ int keyIndex = mexthop_list.IndexOf(key); /* * As all ids are located on a ring if the key is the first item in the * list we have to select the last item as predecessor with help of this * calculation. */ int index = (sizeOfList + (keyIndex - 1)) % sizeOfList; NodeId idOfClosestNode = mexthop_list[index]; closestNode = GetNode(idOfClosestNode); return closestNode; }
} // end AttachFingers /// <summary> /// Returns true if attaching Node should be added to finger table. /// </summary> /// <param name="testFinger">The attaching node</param> /// <param name="finger">The first Finger Table entry machting the attaching node.</param> /// <returns>Boolean</returns> public bool isFinger(NodeId testFinger, out FTableEntry finger) { foreach (FTableEntry ftEntry in FingerTable) { if (ftEntry.nodestate == NodeState.unknown) { if (ftEntry.Finger.ElementOfInterval(m_local_node.Id, testFinger, true)) { finger = ftEntry; return true; } } else { // is closer? if (testFinger.ElementOfInterval(ftEntry.Finger, ftEntry.Successor, false)) { finger = ftEntry; return true; } } } finger = null; return false; }
public Node FindNextHopTo(NodeId TargetId, bool fIncluding, bool fExludeMe) { /* Nodes of the connection table may be not part of the ring. So never * use them as via nodes */ foreach (ReloadConnectionTableInfoElement rce in m_flm.ConnectionTable) if (rce.NodeID != null && rce.NodeID == TargetId) return GetNode(rce.NodeID); /* Already in routing table? Route to destination directly then */ if (GotUpdatesFrom(TargetId)) return GetNode(TargetId); /* As Client always contact admitting peer and do not forward anything * as long as not having joined (bootstraps are an exception) */ if (m_ReloadConfig.IamClient) return m_ReloadConfig.AdmittingPeer; /* Now use any information available to find the hop nearest to * destination where we have ice candidates of or have an existing * connection to */ if (m_successors.Count == 0) return m_local_node; if (TargetId.ElementOfInterval(GetPredecessor(0).Id, m_local_node.Id, true)) return m_local_node; foreach (NodeId succ in m_successors) { if (TargetId.ElementOfInterval(m_local_node.Id, succ, false) || TargetId == succ) return GetNode(succ); } Node closestNode = GetClosestPrecedingNode(TargetId); return closestNode; //return FindNextHopTo(closestNode.Id, false , false); // watch out! NextHopId might be null //return GetNode(NextHopId); }