#include <IterativeLookup.h>
Protected Member Functions | |
| bool | accepts (int rpcId) |
| void | handleResponse (FindNodeResponse *msg) |
| void | handleTimeout (BaseCallMessage *msg, const TransportAddress &dest, int rpcId) |
| void | handleFailedNodeResponse (const NodeHandle &src, cPacket *findNodeExt, bool retry) |
| IterativePathLookup (IterativeLookup *lookup) | |
| virtual | ~IterativePathLookup () |
| int | add (const NodeHandle &handle, const NodeHandle &source=NodeHandle::UNSPECIFIED_NODE) |
| Adds a NodeHandle to next hops. | |
Protected Attributes | |
| IterativeLookup * | lookup |
| int | hops |
| int | step |
| int | pendingRpcs |
| bool | finished |
| bool | success |
| LookupVector | nextHops |
| std::map< TransportAddress, NodeHandle > | oldNextHops |
Private Member Functions | |
| void | sendRpc (int num, cPacket *FindNodeExt=NULL) |
| void | sendNewRpcAfterTimeout (cPacket *findNodeExt) |
Friends | |
| class | IterativeLookup |
Definition at line 263 of file IterativeLookup.h.
| IterativePathLookup::IterativePathLookup | ( | IterativeLookup * | lookup | ) | [protected] |
Definition at line 636 of file IterativeLookup.cc.
00637 { 00638 this->lookup = lookup; 00639 this->hops = 0; 00640 this->step = 0; 00641 this->pendingRpcs = 0; 00642 this->finished = false; 00643 this->success = false; 00644 00645 if (lookup->routingType == EXHAUSTIVE_ITERATIVE_ROUTING) { 00646 // need to add some extra space for backup nodes, if we have to 00647 // remove failed nodes from the nextHops vector 00648 this->nextHops = LookupVector(2*(lookup->config.redundantNodes), 00649 lookup); 00650 } else { 00651 this->nextHops = LookupVector((lookup->config.redundantNodes), 00652 lookup); 00653 } 00654 }
| IterativePathLookup::~IterativePathLookup | ( | ) | [protected, virtual] |
| bool IterativePathLookup::accepts | ( | int | rpcId | ) | [protected] |
Definition at line 659 of file IterativeLookup.cc.
Referenced by IterativeLookup::handleRpcResponse().
00660 { 00661 if (finished) { 00662 return false; 00663 } 00664 00665 // shall we use all responses, or only 00666 // the first one (rpcId == step)? 00667 if (lookup->config.useAllParallelResponses 00668 && lookup->config.merge) { 00669 00670 return true; 00671 } 00672 00673 return (rpcId == step); 00674 }
| int IterativePathLookup::add | ( | const NodeHandle & | handle, | |
| const NodeHandle & | source = NodeHandle::UNSPECIFIED_NODE | |||
| ) | [protected] |
Adds a NodeHandle to next hops.
Definition at line 1021 of file IterativeLookup.cc.
Referenced by IterativeLookup::start().
01022 { 01023 if (lookup->config.merge) { 01024 return nextHops.add(LookupEntry(handle, source, false)); 01025 } else { 01026 nextHops.push_back(LookupEntry(handle, source, false)); 01027 return (nextHops.size() - 1); 01028 } 01029 }
| void IterativePathLookup::handleFailedNodeResponse | ( | const NodeHandle & | src, | |
| cPacket * | findNodeExt, | |||
| bool | retry | |||
| ) | [protected] |
Definition at line 878 of file IterativeLookup.cc.
00880 { 00881 if (finished) { 00882 return; 00883 } 00884 00885 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00886 for (oldPos = oldNextHops.begin(); oldPos != oldNextHops.end(); oldPos++) { 00887 if ((! oldPos->second.isUnspecified()) && 00888 (oldPos->second == src)) break; 00889 } 00890 00891 if (oldPos == oldNextHops.end()) { 00892 return; 00893 } 00894 00895 std::map<TransportAddress, NodeHandle>::iterator oldSrcPos = 00896 oldNextHops.find(src); 00897 const NodeHandle* oldSrc = &NodeHandle::UNSPECIFIED_NODE; 00898 00899 if (oldSrcPos != oldNextHops.end()) { 00900 oldSrc = &(oldSrcPos->second); 00901 } 00902 00903 if (retry) { 00904 // FIXME: This is needed for a node to be asked again when detecting 00905 // a failed node. It could pose problems when parallel lookups and 00906 // failed node recovery are both needed at the same time! 00907 lookup->setVisited(src, false); 00908 00909 nextHops.add(LookupEntry(src, *oldSrc, false)); 00910 } 00911 00912 oldNextHops.erase(oldPos); 00913 00914 sendNewRpcAfterTimeout(findNodeExt); 00915 }
| void IterativePathLookup::handleResponse | ( | FindNodeResponse * | msg | ) | [protected] |
Definition at line 676 of file IterativeLookup.cc.
Referenced by IterativeLookup::handleRpcResponse().
00677 { 00678 if (finished) 00679 return; 00680 00681 const NodeHandle& source = msg->getSrcNode(); 00682 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00683 oldPos = oldNextHops.find(source); 00684 if (oldPos != oldNextHops.end()) oldNextHops.erase(oldPos); 00685 00686 // don't count local hops 00687 if (lookup->overlay->getThisNode() != source) { 00688 hops++; 00689 } 00690 00691 lookup->setVisited(source); 00692 00693 // if (source.getKey() == lookup->key) { 00694 // cout << "received response from destination for key " << lookup->key 00695 // << " with isSibling = " << msg->getSiblings() << endl; 00696 // } 00697 00698 step++; 00699 00700 // decrease pending rpcs 00701 pendingRpcs--; 00702 00703 if (msg->getClosestNodesArraySize() != 0) { 00704 // mode: merge or replace 00705 if (!lookup->config.merge) { 00706 nextHops.clear(); 00707 } 00708 } else { 00709 //cout << "findNode() returned 0 nodes!" << endl; 00710 } 00711 00712 int numNewRpcs = 0; 00713 00714 // add new next hops 00715 for (uint32_t i=0; i < msg->getClosestNodesArraySize(); i++) { 00716 const NodeHandle& handle = msg->getClosestNodes(i); 00717 00718 // add NodeHandle to next hops and siblings 00719 int pos = add(handle, source); 00720 00721 // only send new rpcs if we've learned about new nodes 00722 if ((pos >= 0) && (pos < lookup->config.redundantNodes)) { 00723 numNewRpcs++; 00724 } 00725 00726 // check if node was found 00727 if ((lookup->numSiblings == 0) && (handle.getKey() == lookup->key) 00728 && (!lookup->config.secure)) { 00729 00730 lookup->addSibling(handle); 00731 00732 finished = true; 00733 success = true; 00734 return; 00735 } else { 00736 if (lookup->numSiblings != 0 && !lookup->config.secure 00737 && (lookup->routingType != EXHAUSTIVE_ITERATIVE_ROUTING) 00738 && msg->getSiblings()) { 00739 00740 //cout << "adding sibling " << handle << endl; 00741 lookup->addSibling(handle); 00742 } 00743 } 00744 } 00745 00746 #if 0 00747 cout << "nextHops.size " << nextHops.size() 00748 << " find node response " << msg->getClosestNodesArraySize() 00749 << " config " << lookup->config.redundantNodes << endl; 00750 00751 cout << "looking for " << lookup->key << endl; 00752 00753 for (uint32_t i=0; i < msg->getClosestNodesArraySize(); i++) { 00754 cout << "find node " << msg->getClosestNodes(i) << endl; 00755 } 00756 00757 cout << "next Hops " << nextHops << endl; 00758 #endif 00759 00760 // check if sibling lookup is finished 00761 if ((lookup->routingType != EXHAUSTIVE_ITERATIVE_ROUTING) 00762 && msg->getSiblings() 00763 && msg->getClosestNodesArraySize() != 0 && 00764 lookup->numSiblings != 0 && !lookup->config.secure) { 00765 00766 finished = true; 00767 success = true; 00768 return; 00769 } 00770 00771 // extract find node extension object 00772 cPacket* findNodeExt = NULL; 00773 if (msg->hasObject("findNodeExt")) { 00774 findNodeExt = (cPacket*)msg->removeObject("findNodeExt"); 00775 } 00776 00777 // If config.newRpcOnEveryResponse is true, send a new RPC 00778 // even if there was no lookup progress 00779 if ((numNewRpcs == 0) && lookup->config.newRpcOnEveryResponse) { 00780 numNewRpcs = 1; 00781 } 00782 00783 // send next rpcs 00784 sendRpc(min(numNewRpcs, lookup->config.parallelRpcs), findNodeExt); 00785 00786 delete findNodeExt; 00787 }
| void IterativePathLookup::handleTimeout | ( | BaseCallMessage * | msg, | |
| const TransportAddress & | dest, | |||
| int | rpcId | |||
| ) | [protected] |
Definition at line 801 of file IterativeLookup.cc.
Referenced by IterativeLookup::handleRpcResponse(), and IterativeLookup::handleRpcTimeout().
00803 { 00804 if (finished) 00805 return; 00806 00807 EV << "[IterativePathLookup::handleTimeout()]\n" 00808 << " Timeout of RPC " << rpcId 00809 << endl; 00810 00811 //std::cout << lookup->overlay->getThisNode() << ": Path timeout for node" 00812 // << dest << endl; 00813 00814 // For exhaustive-iterative remove dead nodes from nextHops vector 00815 // (which is also our results vector) 00816 if ((lookup->routingType == EXHAUSTIVE_ITERATIVE_ROUTING) 00817 && lookup->getDead(dest)) { 00818 LookupVector::iterator it = nextHops.findIterator( 00819 (dynamic_cast<const NodeHandle&>(dest)).getKey()); 00820 if (it != nextHops.end()) { 00821 nextHops.erase(it); 00822 } 00823 } 00824 00825 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00826 oldPos = oldNextHops.find(dest); 00827 00828 // decrease pending rpcs 00829 pendingRpcs--; 00830 00831 cPacket* findNodeExt = NULL; 00832 if (msg && msg->hasObject("findNodeExt")) { 00833 findNodeExt = static_cast<cPacket*>( 00834 msg->removeObject("findNodeExt")); 00835 } 00836 00837 if (oldPos == oldNextHops.end() || (!lookup->config.failedNodeRpcs)) { 00838 sendNewRpcAfterTimeout(findNodeExt); 00839 delete findNodeExt; 00840 } else { 00841 if (oldPos->second.isUnspecified()) { 00842 // TODO: handleFailedNode should always be called for local 00843 // nodes, independant of config.failedNodeRpcs 00844 // Attention: currently this method is also called, 00845 // if a node responded and the path doesn't accept a message 00846 FindNodeCall* findNodeCall = dynamic_cast<FindNodeCall*>(msg); 00847 // answer was from local findNode() 00848 00849 if (findNodeCall && lookup->overlay->handleFailedNode(dest)) { 00850 NodeVector* retry = lookup->overlay->findNode( 00851 findNodeCall->getLookupKey(), -1, lookup->numSiblings, msg); 00852 00853 for (NodeVector::iterator i = retry->begin(); i != retry->end(); i++) { 00854 nextHops.add(LookupEntry(*i, NodeHandle::UNSPECIFIED_NODE, false)); 00855 } 00856 00857 delete retry; 00858 } 00859 00860 sendNewRpcAfterTimeout(findNodeExt); 00861 delete findNodeExt; 00862 00863 } else { 00864 FailedNodeCall* call = new FailedNodeCall("FailedNodeCall"); 00865 call->setFailedNode(dest); 00866 call->setBitLength(FAILEDNODECALL_L(call)); 00867 if (findNodeExt) { 00868 call->addObject(findNodeExt); 00869 call->addBitLength(findNodeExt->getBitLength()); 00870 } 00871 lookup->overlay->countFailedNodeCall(call); 00872 lookup->overlay->sendUdpRpcCall(oldPos->second, call, NULL, 00873 -1, 0, -1, lookup); 00874 } 00875 } 00876 }
| void IterativePathLookup::sendNewRpcAfterTimeout | ( | cPacket * | findNodeExt | ) | [private] |
Definition at line 789 of file IterativeLookup.cc.
Referenced by handleFailedNodeResponse(), and handleTimeout().
00790 { 00791 // two alternatives to react on a timeout 00792 if (lookup->config.newRpcOnEveryTimeout) { 00793 // always send one new RPC for every timeout 00794 sendRpc(1, findNodeExt); 00795 } else if (pendingRpcs == 0) { 00796 // wait until all RPCs have timed out and then send alpha new RPCs 00797 sendRpc(lookup->config.parallelRpcs, findNodeExt); 00798 } 00799 }
| void IterativePathLookup::sendRpc | ( | int | num, | |
| cPacket * | FindNodeExt = NULL | |||
| ) | [private] |
Definition at line 917 of file IterativeLookup.cc.
Referenced by handleResponse(), sendNewRpcAfterTimeout(), and IterativeLookup::start().
00918 { 00919 // path finished? yes -> quit 00920 if (finished) 00921 return; 00922 00923 // check for maximum hop count 00924 if (lookup->hopCountMax && (hops >= lookup->hopCountMax)) { 00925 EV << "[IterativePathLookup::sendRpc()]\n" 00926 << " Max hop count exceeded - lookup failed!" 00927 << endl; 00928 //cout << "[IterativePathLookup::sendRpc()]\n" 00929 // << " Max hop count exceeded - lookup failed!" 00930 // << endl; 00931 00932 finished = true; 00933 success = false; 00934 00935 return; 00936 } 00937 00938 // if strictParallelRpcs is true, limit concurrent in-flight requests 00939 // to config.parallelRpcs 00940 if (lookup->config.strictParallelRpcs) { 00941 num = min(num, lookup->config.parallelRpcs - pendingRpcs); 00942 } 00943 00944 // try all remaining nodes 00945 if ((num == 0) && (pendingRpcs == 0) 00946 && !lookup->config.finishOnFirstUnchanged) { 00947 num = lookup->config.parallelRpcs; 00948 //cout << "trying all remaining nodes (" 00949 // << lookup->numSiblings << ")" << endl; 00950 } 00951 00952 // send rpc messages 00953 LookupVector::iterator it = nextHops.begin(); 00954 int i = 0; 00955 for (LookupVector::iterator it = nextHops.begin(); 00956 ((num > 0) && (i < lookup->config.redundantNodes) 00957 && (it != nextHops.end())); it++, i++) { 00958 00959 // ignore nodes to which we've already sent an RPC 00960 if (it->alreadyUsed || lookup->getDead(it->handle)) continue; 00961 00962 // check if node has already been visited? no -> 00963 // TODO: doesn't work with Broose 00964 if ((!lookup->config.visitOnlyOnce) || (!lookup->getVisited(it->handle))) { 00965 // send rpc to node increase pending rpcs 00966 pendingRpcs++; 00967 num--; 00968 FindNodeCall* call = lookup->createFindNodeCall(findNodeExt); 00969 lookup->sendRpc(it->handle, call, this, step); 00970 oldNextHops[it->handle] = it->source; 00971 00972 //cout << "Sending RPC to " << it->handle 00973 // << " ( " << num << " more )" 00974 // << " thisNode = " << lookup->overlay->getThisNode().getKey() << endl; 00975 00976 // mark node as already used 00977 it->alreadyUsed = true; 00978 } else { 00979 //EV << "[IterativePathLookup::sendRpc()]\n" 00980 // << " Last next hop (" 00981 // << it->handle 00982 // << ") already visited." 00983 // << endl; 00984 00985 // std::cout << "visited:" << std::endl; 00986 // for (TransportAddress::Set::iterator it = lookup->visited.begin(); 00987 // it != lookup->visited.end(); it++) 00988 // std::cout << *it << std::endl; 00989 // 00990 // std::cout << "nextHops:" << std::endl; 00991 // for (NodePairVector::iterator it = nextHops.begin(); 00992 // it != nextHops.end(); it++) 00993 // std::cout << it->first << std::endl; 00994 } 00995 } 00996 00997 // no rpc sent, no pending rpcs? 00998 // -> failed for normal lookups 00999 // -> exhaustive lookups are always successful 01000 if (pendingRpcs == 0) { 01001 if (lookup->routingType == EXHAUSTIVE_ITERATIVE_ROUTING) { 01002 int i = 0; 01003 for (LookupVector::iterator it = nextHops.begin(); 01004 ((i < lookup->config.redundantNodes) 01005 && (it != nextHops.end())); it++, i++) { 01006 lookup->addSibling(it->handle); 01007 } 01008 01009 success = true; 01010 } else { 01011 success = false; 01012 //cout << "failed nextHops for key " << lookup->key << endl; 01013 //cout << nextHops << endl; 01014 } 01015 01016 finished = true; 01017 } 01018 //cout << endl; 01019 }
friend class IterativeLookup [friend] |
Definition at line 265 of file IterativeLookup.h.
bool IterativePathLookup::finished [protected] |
Definition at line 274 of file IterativeLookup.h.
Referenced by accepts(), handleFailedNodeResponse(), handleResponse(), IterativeLookup::handleRpcResponse(), IterativeLookup::handleRpcTimeout(), handleTimeout(), IterativePathLookup(), and sendRpc().
int IterativePathLookup::hops [protected] |
Definition at line 271 of file IterativeLookup.h.
Referenced by handleResponse(), IterativeLookup::handleRpcResponse(), IterativeLookup::handleRpcTimeout(), IterativePathLookup(), and sendRpc().
IterativeLookup* IterativePathLookup::lookup [protected] |
Definition at line 268 of file IterativeLookup.h.
Referenced by accepts(), add(), handleFailedNodeResponse(), handleResponse(), handleTimeout(), sendNewRpcAfterTimeout(), and sendRpc().
LookupVector IterativePathLookup::nextHops [protected] |
Definition at line 276 of file IterativeLookup.h.
Referenced by add(), handleFailedNodeResponse(), handleResponse(), handleTimeout(), IterativePathLookup(), and sendRpc().
std::map<TransportAddress, NodeHandle> IterativePathLookup::oldNextHops [protected] |
Definition at line 277 of file IterativeLookup.h.
Referenced by handleFailedNodeResponse(), handleResponse(), handleTimeout(), and sendRpc().
int IterativePathLookup::pendingRpcs [protected] |
Definition at line 273 of file IterativeLookup.h.
Referenced by handleResponse(), handleTimeout(), IterativePathLookup(), sendNewRpcAfterTimeout(), and sendRpc().
int IterativePathLookup::step [protected] |
Definition at line 272 of file IterativeLookup.h.
Referenced by accepts(), handleResponse(), IterativePathLookup(), and sendRpc().
bool IterativePathLookup::success [protected] |
Definition at line 275 of file IterativeLookup.h.
Referenced by handleResponse(), IterativeLookup::handleRpcResponse(), IterativeLookup::handleRpcTimeout(), IterativePathLookup(), and sendRpc().
1.5.8