BasePathLookup Class Reference

#include <BaseLookup.h>

List of all members.


Detailed Description

This class implements a path lookup.

Author:
Sebastian Mies

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

BaseLookuplookup
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

Constructor & Destructor Documentation

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 }

BasePathLookup::~BasePathLookup (  )  [protected, virtual]

00562 {}


Member Function Documentation

bool BasePathLookup::accepts ( int  rpcId  )  [protected]

00565 {
00566     bool accept = ( rpcId == step ) && !finished;
00567     return accept;
00568 }

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.

Parameters:
findNodeExt Pointer to a optional cMessage, that may contain overlay specific data to be attached to FindNode RPCs and BaseRouteMessages
Returns:
Pointer to a new FindNodeCall message.
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]

Adds a NodeHandle to next hops.

00838 {
00839     if ( lookup->config.merge )
00840         nextHops.add( std::pair<NodeHandle, NodeHandle>(handle, source) );
00841     else
00842         nextHops.push_back( std::pair<NodeHandle, NodeHandle>(handle, source) );
00843 }


Friends And Related Function Documentation

friend class BaseLookup [friend]


Member Data Documentation

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]


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:28 2008 for ITM OverSim by  doxygen 1.5.3