#include <BaseLookup.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, cMessage *findNodeExt, bool retry) |
BasePathLookup (BaseLookup *lookup) | |
virtual | ~BasePathLookup () |
virtual FindNodeCall * | createRpcMessage (cMessage *findNodeExt=NULL) |
Creates a find node call message. | |
void | add (const NodeHandle &handle, const NodeHandle &source=NodeHandle::UNSPECIFIED_NODE) |
Adds a NodeHandle to next hops. | |
Protected Attributes | |
BaseLookup * | lookup |
int | hops |
int | step |
int | pendingRpcs |
bool | finished |
bool | success |
NodePairVector | nextHops |
std::map < TransportAddress, NodeHandle > | oldNextHops |
Private Member Functions | |
void | sendRpc (int num, cMessage *FindNodeExt=NULL) |
Friends | |
class | BaseLookup |
BasePathLookup::BasePathLookup | ( | BaseLookup * | lookup | ) | [protected] |
00551 { 00552 this->lookup = lookup; 00553 this->hops = 0; 00554 this->step = 0; 00555 this->pendingRpcs = 0; 00556 this->finished = false; 00557 this->success = false; 00558 this->nextHops = NodePairVector( lookup->config.redundantNodes, lookup ); 00559 }
bool BasePathLookup::accepts | ( | int | rpcId | ) | [protected] |
void BasePathLookup::handleResponse | ( | FindNodeResponse * | msg | ) | [protected] |
00571 { 00572 if (finished) 00573 return; 00574 00575 const NodeHandle& source = msg->getSrcNode(); 00576 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00577 oldPos = oldNextHops.find(source); 00578 if (oldPos != oldNextHops.end()) oldNextHops.erase(oldPos); 00579 00580 // increase hops: FIXME don't count local hops 00581 if (lookup->overlay->getThisNode() != source) 00582 hops++; 00583 step++; 00584 00585 // decrease pending rpcs 00586 pendingRpcs--; 00587 00588 00589 if (msg->getClosestNodesArraySize() != 0) { 00590 // mode: merge or replace 00591 if (!lookup->config.merge) { 00592 nextHops.clear(); 00593 } 00594 } 00595 //else { 00596 //std::cout << "findNode() returned 0 nodes!!!!!!" << endl; 00597 //} 00598 00599 // add new next hops 00600 for ( uint i=0; i < msg->getClosestNodesArraySize(); i++ ) { 00601 const NodeHandle& handle = msg->getClosestNodes(i); 00602 00603 // add NodeHandle to next hops and siblings 00604 add( handle, source ); 00605 00606 // check if node was found 00607 if ((lookup->numSiblings == 0) && (handle.key == lookup->key) 00608 && (!lookup->config.secure)) { 00609 00610 lookup->addSibling( handle ); 00611 00612 // TODO: definition of hop count for iterative lookups is unclear 00613 // don't count local hops 00614 if (lookup->overlay->getThisNode() != msg->getSrcNode()) { 00615 // && (lookup->key != msg->getSrcNode().key)) { 00616 hops++; 00617 } 00618 finished = true; 00619 success = true; 00620 return; 00621 } else 00622 if (lookup->numSiblings != 0 && !lookup->config.secure && msg->getSiblings() ) 00623 lookup->addSibling( handle ); 00624 00625 } 00626 00627 // check if sibling lookup is finished 00628 if ( msg->getSiblings() && msg->getClosestNodesArraySize() != 0 && 00629 lookup->numSiblings != 0 && !lookup->config.secure ) { 00630 00631 finished = true; 00632 success = true; 00633 return; 00634 } 00635 00636 // extract find node extension object 00637 cMessage* findNodeExt = NULL; 00638 if (msg->hasObject("findNodeExt")) 00639 findNodeExt = (cMessage*)msg->removeObject("findNodeExt"); 00640 00641 // send next rpcs 00642 sendRpc( lookup->config.parallelRpcs, findNodeExt ); 00643 00644 // ... 00645 delete findNodeExt; 00646 }
void BasePathLookup::handleTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId | |||
) | [protected] |
00651 { 00652 if (finished) 00653 return; 00654 00655 EV << "[BasePathLookup::handleTimeout()]\n" 00656 << " Timeout of RPC " << rpcId 00657 << endl; 00658 00659 // std::cout << lookup->overlay->thisNode << ": Path timeout for node" 00660 // << dest << endl; 00661 00662 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00663 oldPos = oldNextHops.find(dest); 00664 00665 // decrease pending rpcs 00666 pendingRpcs--; 00667 00668 cMessage* findNodeExt = NULL; 00669 if (msg && msg->hasObject("findNodeExt")) { 00670 findNodeExt = static_cast<cMessage*>( 00671 msg->removeObject("findNodeExt")); 00672 } 00673 00674 if (oldPos == oldNextHops.end() || (!lookup->config.failedNodeRpcs)) { 00675 // last rpc? yes-> send next rpc 00676 if (pendingRpcs==0) sendRpc(1, findNodeExt); 00677 delete findNodeExt; 00678 } else { 00679 if (oldPos->second.isUnspecified()) { 00680 FindNodeCall* findNodeCall = dynamic_cast<FindNodeCall*>(msg); 00681 // answer was from local findNode() 00682 00683 if (findNodeCall && lookup->overlay->handleFailedNode(dest)) { 00684 NodeVector* retry = lookup->overlay->findNode( 00685 findNodeCall->getLookupKey(), -1, lookup->numSiblings, msg); 00686 00687 for (NodeVector::iterator i = retry->begin(); 00688 i != retry->end(); i++) { 00689 nextHops.add(std::pair<NodeHandle, NodeHandle>( 00690 *i, NodeHandle::UNSPECIFIED_NODE)); 00691 } 00692 00693 delete(retry); 00694 } 00695 if (pendingRpcs==0) { 00696 sendRpc(1, findNodeExt); 00697 } 00698 delete findNodeExt; 00699 } else { 00700 FailedNodeCall* call = new FailedNodeCall("FailedNodeCall"); 00701 call->setFailedNode(dest); 00702 call->setLength( FAILEDNODECALL_L(call) ); 00703 if (findNodeExt) { 00704 call->addObject(findNodeExt); 00705 call->addLength(findNodeExt->length()); 00706 } 00707 lookup->overlay->countFailedNodeCall( call ); 00708 lookup->overlay->sendUdpRpcCall(oldPos->second, call, 00709 -1, 0, -1, lookup); 00710 } 00711 } 00712 }
void BasePathLookup::handleFailedNodeResponse | ( | const NodeHandle & | src, | |
cMessage * | findNodeExt, | |||
bool | retry | |||
) | [protected] |
00716 { 00717 if (finished) { 00718 return; 00719 } 00720 00721 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00722 for (oldPos = oldNextHops.begin(); oldPos != oldNextHops.end(); oldPos++) { 00723 if ((! oldPos->second.isUnspecified()) && 00724 (oldPos->second == src)) break; 00725 } 00726 00727 if (oldPos == oldNextHops.end()) { 00728 return; 00729 } 00730 00731 std::map<TransportAddress, NodeHandle>::iterator oldSrcPos = 00732 oldNextHops.find(src); 00733 const NodeHandle* oldSrc = &NodeHandle::UNSPECIFIED_NODE; 00734 00735 if (oldSrcPos != oldNextHops.end()) { 00736 oldSrc = &(oldSrcPos->second); 00737 } 00738 00739 if (retry) { 00740 // FIXME: This is needed for a node to be asked again when detecting 00741 // a failed node. It could pose problems when parallel lookups and 00742 // failed node recovery are both needed at the same time! 00743 lookup->setVisited(src, false); 00744 00745 nextHops.add(std::pair<NodeHandle, NodeHandle>(src, *oldSrc)); 00746 } 00747 00748 oldNextHops.erase(oldPos); 00749 00750 // last rpc? yes-> send next rpc 00751 if (pendingRpcs == 0) { 00752 sendRpc(1, findNodeExt); 00753 } 00754 }
void BasePathLookup::sendRpc | ( | int | num, | |
cMessage * | FindNodeExt = NULL | |||
) | [private] |
00757 { 00758 // path finished? yes -> quit 00759 if (finished) 00760 return; 00761 00762 // check for maximum hop count 00763 if (lookup->hopCountMax && (hops >= lookup->hopCountMax)) { 00764 EV << "[BasePathLookup::sendRpc()]\n" 00765 << " Max hop count exceeded - lookup failed" 00766 << endl; 00767 00768 std::cout << "Hopcount exceeded!" << endl; 00769 finished = true; 00770 success = false; 00771 return; 00772 } 00773 00774 // send rpc messages 00775 while (num > 0 && nextHops.size() != 0) { 00776 // get top node pair 00777 const std::pair<NodeHandle, NodeHandle>& pair = nextHops.front(); 00778 00779 // check if node has already been visited? no -> 00780 // TODO: doesn't work with Broose 00781 if ( !lookup->getVisited(pair.first) ) { 00782 // send rpc to node increase pending rpcs 00783 pendingRpcs++; 00784 num--; 00785 FindNodeCall* call = createRpcMessage(findNodeExt); 00786 lookup->overlay->countFindNodeCall(call); 00787 lookup->sendRpc(pair.first, call, this, step); 00788 oldNextHops[pair.first] = pair.second; 00789 } else { 00790 EV << "[BasePathLookup::sendRpc()]\n" 00791 << " Last next hop (" 00792 << pair.first 00793 << ") already visited - lookup failed!\n" 00794 << " This occurs occasionally under churn!" 00795 << endl; 00796 00797 // std::cout << "visited:" << std::endl; 00798 // for (TransportAddress::Set::iterator it = lookup->visited.begin(); 00799 // it != lookup->visited.end(); it++) 00800 // std::cout << *it << std::endl; 00801 // 00802 // std::cout << "nextHops:" << std::endl; 00803 // for (NodePairVector::iterator it = nextHops.begin(); 00804 // it != nextHops.end(); it++) 00805 // std::cout << it->first << std::endl; 00806 } 00807 // delete first element and continue 00808 nextHops.erase( nextHops.begin() ); 00809 } 00810 00811 // no rpc sent and no pending rpcs? -> failed 00812 if ( pendingRpcs == 0 ) { 00813 // std::cout << "No more nodes...failing..." << endl; 00814 finished = true; 00815 success = false; 00816 } 00817 }
FindNodeCall * BasePathLookup::createRpcMessage | ( | cMessage * | findNodeExt = NULL |
) | [protected, virtual] |
Creates a find node call message.
This method can be overridden to add some additional state information to the FindNodeCall message.
findNodeExt | Pointer to a optional cMessage, that may contain overlay specific data to be attached to FindNode RPCs and BaseRouteMessages |
00820 { 00821 // create default find node call message 00822 FindNodeCall* call = new FindNodeCall( "FindNodeCall" ); 00823 call->setLookupKey( lookup->key ); 00824 call->setNumRedundantNodes(lookup->config.redundantNodes); 00825 call->setNumSiblings(lookup->numSiblings); 00826 call->setLength( FINDNODECALL_L(call) ); 00827 00828 // duplicate extension object 00829 if ( findNodeExt != NULL ) { 00830 call->addObject( (cObject*)findNodeExt->dup() ); 00831 call->addLength( findNodeExt->length() ); 00832 } 00833 00834 return call; 00835 }
void BasePathLookup::add | ( | const NodeHandle & | handle, | |
const NodeHandle & | source = NodeHandle::UNSPECIFIED_NODE | |||
) | [protected] |
friend class BaseLookup [friend] |
BaseLookup* BasePathLookup::lookup [protected] |
int BasePathLookup::hops [protected] |
int BasePathLookup::step [protected] |
int BasePathLookup::pendingRpcs [protected] |
bool BasePathLookup::finished [protected] |
bool BasePathLookup::success [protected] |
NodePairVector BasePathLookup::nextHops [protected] |
std::map<TransportAddress, NodeHandle> BasePathLookup::oldNextHops [protected] |