#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] |
00547 { 00548 this->lookup = lookup; 00549 this->hops = 0; 00550 this->step = 0; 00551 this->pendingRpcs = 0; 00552 this->finished = false; 00553 this->success = false; 00554 this->nextHops = NodePairVector( lookup->config.redundantNodes, lookup ); 00555 }
bool BasePathLookup::accepts | ( | int | rpcId | ) | [protected] |
void BasePathLookup::handleResponse | ( | FindNodeResponse * | msg | ) | [protected] |
00567 { 00568 if (finished) 00569 return; 00570 00571 const NodeHandle& source = msg->getSrcNode(); 00572 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00573 oldPos = oldNextHops.find(source); 00574 if (oldPos != oldNextHops.end()) oldNextHops.erase(oldPos); 00575 00576 // increase hops: FIXME don't count local hops 00577 if (lookup->overlay->getThisNode() != source) 00578 hops++; 00579 step++; 00580 00581 // decrease pending rpcs 00582 pendingRpcs--; 00583 00584 00585 if (msg->getClosestNodesArraySize() != 0) { 00586 // mode: merge or replace 00587 if (!lookup->config.merge) { 00588 nextHops.clear(); 00589 } 00590 } else { 00591 // std::cout << "findNode() returned 0 nodes!!!!!!" << endl; 00592 } 00593 00594 // add new next hops 00595 for ( uint i=0; i < msg->getClosestNodesArraySize(); i++ ) { 00596 const NodeHandle& handle = msg->getClosestNodes(i); 00597 00598 // add NodeHandle to next hops and siblings 00599 add( handle, source ); 00600 00601 // check if node was found 00602 if ((lookup->numSiblings == 0) && (handle.key == lookup->key) 00603 && (!lookup->config.secure)) { 00604 00605 lookup->addSibling( handle ); 00606 00607 // TODO: definition of hop count for iterative lookups is unclear 00608 // don't count local hops 00609 if (lookup->overlay->getThisNode() != msg->getSrcNode()) { 00610 // && (lookup->key != msg->getSrcNode().key)) { 00611 hops++; 00612 } 00613 finished = true; 00614 success = true; 00615 return; 00616 } else 00617 if (lookup->numSiblings != 0 && !lookup->config.secure && msg->getSiblings() ) 00618 lookup->addSibling( handle ); 00619 00620 } 00621 00622 // check if sibling lookup is finished 00623 if ( msg->getSiblings() && msg->getClosestNodesArraySize() != 0 && 00624 lookup->numSiblings != 0 && !lookup->config.secure ) { 00625 00626 finished = true; 00627 success = true; 00628 return; 00629 } 00630 00631 // extract find node extension object 00632 cMessage* findNodeExt = NULL; 00633 if (msg->hasObject("findNodeExt")) 00634 findNodeExt = (cMessage*)msg->removeObject("findNodeExt"); 00635 00636 // send next rpcs 00637 sendRpc( lookup->config.parallelRpcs, findNodeExt ); 00638 00639 // ... 00640 delete findNodeExt; 00641 }
void BasePathLookup::handleTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId | |||
) | [protected] |
00646 { 00647 if (finished) 00648 return; 00649 00650 EV << "[BasePathLookup::handleTimeout()]\n" 00651 << " Timeout of RPC " << rpcId 00652 << endl; 00653 00654 // std::cout << lookup->overlay->thisNode << ": Path timeout for node" 00655 // << dest << endl; 00656 00657 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00658 oldPos = oldNextHops.find(dest); 00659 00660 // decrease pending rpcs 00661 pendingRpcs--; 00662 00663 cMessage* findNodeExt = NULL; 00664 if (msg && msg->hasObject("findNodeExt")) { 00665 findNodeExt = static_cast<cMessage*>( 00666 msg->removeObject("findNodeExt")); 00667 } 00668 00669 if (oldPos == oldNextHops.end() || (!lookup->config.failedNodeRpcs)) 00670 { 00671 // last rpc? yes-> send next rpc 00672 if (pendingRpcs==0) sendRpc(1, findNodeExt); 00673 delete findNodeExt; 00674 } 00675 else 00676 { 00677 if (oldPos->second.isUnspecified()) 00678 { 00679 FindNodeCall* findNodeCall = dynamic_cast<FindNodeCall*>(msg); 00680 // answer was from local findNode() 00681 if (findNodeCall && lookup->overlay->handleFailedNode(dest)) 00682 { 00683 NodeVector* retry = lookup->overlay->findNode( 00684 findNodeCall->getLookupKey(), -1, 00685 lookup->numSiblings, msg); 00686 for (NodeVector::iterator i = retry->begin(); 00687 i != retry->end(); i++) 00688 nextHops.add(std::pair<NodeHandle, NodeHandle>( 00689 *i, NodeHandle::UNSPECIFIED_NODE)); 00690 delete(retry); 00691 } 00692 if (pendingRpcs==0) sendRpc(1, findNodeExt); 00693 delete findNodeExt; 00694 } 00695 else 00696 { 00697 FailedNodeCall* call = new FailedNodeCall("FailedNodeCall"); 00698 call->setFailedNode(dest); 00699 call->setLength( FAILEDNODECALL_L(call) ); 00700 if (findNodeExt) 00701 { 00702 call->addObject(findNodeExt); 00703 call->addLength(findNodeExt->length()); 00704 } 00705 lookup->overlay->countFailedNodeCall( call ); 00706 lookup->overlay->sendRpcMessage(oldPos->second, call, lookup); 00707 } 00708 } 00709 }
void BasePathLookup::handleFailedNodeResponse | ( | const NodeHandle & | src, | |
cMessage * | findNodeExt, | |||
bool | retry | |||
) | [protected] |
00713 { 00714 if (finished) return; 00715 00716 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00717 for (oldPos = oldNextHops.begin(); oldPos != oldNextHops.end(); oldPos++) 00718 if ((! oldPos->second.isUnspecified()) && 00719 (oldPos->second == src)) break; 00720 00721 if (oldPos == oldNextHops.end()) return; 00722 00723 std::map<TransportAddress, NodeHandle>::iterator oldSrcPos = 00724 oldNextHops.find(src); 00725 const NodeHandle* oldSrc = &NodeHandle::UNSPECIFIED_NODE; 00726 if (oldSrcPos != oldNextHops.end()) oldSrc = &(oldSrcPos->second); 00727 00728 if (retry) 00729 { 00730 nextHops.add(std::pair<NodeHandle, NodeHandle>(src, *oldSrc)); 00731 } 00732 00733 oldNextHops.erase(oldPos); 00734 00735 // last rpc? yes-> send next rpc 00736 if ( pendingRpcs == 0 ) 00737 sendRpc( 1, findNodeExt ); 00738 }
void BasePathLookup::sendRpc | ( | int | num, | |
cMessage * | FindNodeExt = NULL | |||
) | [private] |
00741 { 00742 // path finished? yes -> quit 00743 if (finished) 00744 return; 00745 00746 // check for maximum hop count 00747 if (lookup->hopCountMax && (hops >= lookup->hopCountMax)) { 00748 EV << "[BasePathLookup::sendRpc()]\n" 00749 << " Max hop count exceeded - lookup failed" 00750 << endl; 00751 00752 std::cout << "Hopcount exceeded!" << endl; 00753 finished = true; 00754 success = false; 00755 return; 00756 } 00757 00758 // send rpc messages 00759 00760 while ( num > 0 && nextHops.size() != 0 ) { 00761 00762 // get top node pair 00763 const std::pair<NodeHandle, NodeHandle>& pair = nextHops.front(); 00764 00765 // check if node has already been visited? no -> 00766 // TODO: doesn't work with Broose 00767 if ( !lookup->getVisited( pair.first ) ) { 00768 00769 // send rpc to node increase pending rpcs 00770 pendingRpcs++; 00771 num--; 00772 FindNodeCall* call = createRpcMessage( findNodeExt ); 00773 lookup->overlay->countFindNodeCall( call ); 00774 lookup->sendRpc( pair.first, call, this, step ); 00775 oldNextHops[pair.first] = pair.second; 00776 } 00777 00778 // delete first element and continue 00779 nextHops.erase( nextHops.begin() ); 00780 } 00781 00782 // no rpc sent and no pending rpcs? -> failed 00783 if ( pendingRpcs == 0 ) { 00784 // std::cout << "No more nodes...failing..." << endl; 00785 finished = true; 00786 success = false; 00787 } 00788 }
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 |
00791 { 00792 // create default find node call message 00793 FindNodeCall* call = new FindNodeCall( "FindNodeCall" ); 00794 call->setLookupKey( lookup->key ); 00795 call->setNumRedundantNodes(lookup->config.redundantNodes); 00796 call->setNumSiblings(lookup->numSiblings); 00797 call->setLength( FINDNODECALL_L(call) ); 00798 00799 // duplicate extension object 00800 if ( findNodeExt != NULL ) { 00801 call->addObject( (cObject*)findNodeExt->dup() ); 00802 call->addLength( findNodeExt->length() ); 00803 } 00804 00805 return call; 00806 }
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] |