#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] |
00511 { 00512 this->lookup = lookup; 00513 this->hops = 0; 00514 this->step = 0; 00515 this->pendingRpcs = 0; 00516 this->finished = false; 00517 this->success = false; 00518 this->nextHops = NodePairVector( lookup->config.redundantNodes, lookup ); 00519 }
bool BasePathLookup::accepts | ( | int | rpcId | ) | [protected] |
void BasePathLookup::handleResponse | ( | FindNodeResponse * | msg | ) | [protected] |
00531 { 00532 if (finished) 00533 return; 00534 00535 const NodeHandle& source = msg->getSrcNode(); 00536 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00537 oldPos = oldNextHops.find(source); 00538 if (oldPos != oldNextHops.end()) oldNextHops.erase(oldPos); 00539 00540 // increase hops: FIXME don't count local hops 00541 if (lookup->overlay->getThisNode() != source) 00542 hops++; 00543 step++; 00544 00545 // decrease pending rpcs 00546 pendingRpcs--; 00547 00548 // mode: merge or replace 00549 if (!lookup->config.merge) { 00550 nextHops.clear(); 00551 } 00552 00553 // add new next hops 00554 for ( uint i=0; i < msg->getClosestNodesArraySize(); i++ ) { 00555 const NodeHandle& handle = msg->getClosestNodes(i); 00556 00557 // add NodeHandle to next hops and siblings 00558 add( handle, source ); 00559 00560 // check if node was found 00561 if ((lookup->numSiblings == 0) && (handle.key == lookup->key) 00562 && (!lookup->config.secure)) { 00563 00564 lookup->addSibling( handle ); 00565 00566 // TODO: definition of hop count for iterative lookups is unclear 00567 // don't count local hops 00568 if (lookup->overlay->getThisNode() != msg->getSrcNode()) { 00569 // && (lookup->key != msg->getSrcNode().key)) { 00570 hops++; 00571 } 00572 finished = true; 00573 success = true; 00574 return; 00575 } else 00576 if (lookup->numSiblings != 0 && !lookup->config.secure && msg->getSiblings() ) 00577 lookup->addSibling( handle ); 00578 00579 } 00580 00581 // check if sibling lookup is finished 00582 if ( msg->getSiblings() && msg->getClosestNodesArraySize() != 0 && 00583 lookup->numSiblings != 0 && !lookup->config.secure ) { 00584 00585 finished = true; 00586 success = true; 00587 return; 00588 } 00589 00590 // extract find node extension object 00591 cMessage* findNodeExt = NULL; 00592 if (msg->hasObject("findNodeExt")) 00593 findNodeExt = (cMessage*)msg->removeObject("findNodeExt"); 00594 00595 // send next rpcs 00596 sendRpc( lookup->config.parallelRpcs, findNodeExt ); 00597 00598 // ... 00599 delete findNodeExt; 00600 }
void BasePathLookup::handleTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId | |||
) | [protected] |
00605 { 00606 if (finished) 00607 return; 00608 00609 EV << "BasePathLookup: Timeout of RPC " << rpcId << endl; 00610 00611 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00612 oldPos = oldNextHops.find(dest); 00613 00614 // decrease pending rpcs 00615 pendingRpcs--; 00616 00617 cMessage* findNodeExt = NULL; 00618 if (msg && msg->hasObject("findNodeExt")) { 00619 findNodeExt = static_cast<cMessage*>( 00620 msg->removeObject("findNodeExt")); 00621 } 00622 00623 if (oldPos == oldNextHops.end() || (!lookup->config.failedNodeRpcs)) 00624 { 00625 // last rpc? yes-> send next rpc 00626 if (pendingRpcs==0) sendRpc(1, findNodeExt); 00627 delete findNodeExt; 00628 } 00629 else 00630 { 00631 if (oldPos->second.isUnspecified()) 00632 { 00633 FindNodeCall* findNodeCall = dynamic_cast<FindNodeCall*>(msg); 00634 // answer was from local findNode() 00635 if (findNodeCall && lookup->overlay->handleFailedNode(dest)) 00636 { 00637 NodeVector* retry = lookup->overlay->findNode( 00638 findNodeCall->getLookupKey(), -1, 00639 lookup->numSiblings, msg); 00640 for (NodeVector::iterator i = retry->begin(); 00641 i != retry->end(); i++) 00642 nextHops.add(std::pair<NodeHandle, NodeHandle>( 00643 *i, NodeHandle::UNSPECIFIED_NODE)); 00644 delete(retry); 00645 } 00646 if (pendingRpcs==0) sendRpc(1, findNodeExt); 00647 delete findNodeExt; 00648 } 00649 else 00650 { 00651 FailedNodeCall* call = new FailedNodeCall("FailedNodeCall"); 00652 call->setFailedNode(dest); 00653 call->setLength( FAILEDNODECALL_L(call) ); 00654 if (findNodeExt) 00655 { 00656 call->addObject(findNodeExt); 00657 call->addLength(findNodeExt->length()); 00658 } 00659 lookup->overlay->countFailedNodeCall( call ); 00660 lookup->overlay->sendRpcMessage(oldPos->second, call, lookup); 00661 } 00662 } 00663 }
void BasePathLookup::handleFailedNodeResponse | ( | const NodeHandle & | src, | |
cMessage * | findNodeExt, | |||
bool | retry | |||
) | [protected] |
00667 { 00668 if (finished) return; 00669 00670 std::map<TransportAddress, NodeHandle>::iterator oldPos; 00671 for (oldPos = oldNextHops.begin(); oldPos != oldNextHops.end(); oldPos++) 00672 if ((! oldPos->second.isUnspecified()) && 00673 (oldPos->second == src)) break; 00674 00675 if (oldPos == oldNextHops.end()) return; 00676 00677 std::map<TransportAddress, NodeHandle>::iterator oldSrcPos = 00678 oldNextHops.find(src); 00679 const NodeHandle* oldSrc = &NodeHandle::UNSPECIFIED_NODE; 00680 if (oldSrcPos != oldNextHops.end()) oldSrc = &(oldSrcPos->second); 00681 00682 if (retry) 00683 { 00684 nextHops.add(std::pair<NodeHandle, NodeHandle>(src, *oldSrc)); 00685 } 00686 00687 oldNextHops.erase(oldPos); 00688 00689 // last rpc? yes-> send next rpc 00690 if ( pendingRpcs == 0 ) 00691 sendRpc( 1, findNodeExt ); 00692 }
void BasePathLookup::sendRpc | ( | int | num, | |
cMessage * | FindNodeExt = NULL | |||
) | [private] |
00695 { 00696 // path finished? yes -> quit 00697 if (finished) 00698 return; 00699 00700 // check for maximum hop count 00701 if (lookup->hopCountMax && (hops >= lookup->hopCountMax)) { 00702 EV << "BasePathLookup::sendRpc(): Max hop count exceeded - " 00703 << "lookup failed!" << endl; 00704 finished = true; 00705 success = false; 00706 return; 00707 } 00708 00709 // send rpc messages 00710 00711 while ( num > 0 && nextHops.size() != 0 ) { 00712 00713 // get top node pair 00714 const std::pair<NodeHandle, NodeHandle>& pair = nextHops.front(); 00715 00716 // check if node has already been visited? no -> 00717 // TODO: doesn't work with Broose 00718 if ( !lookup->getVisited( pair.first ) ) { 00719 00720 // send rpc to node increase pending rpcs 00721 pendingRpcs++; 00722 num--; 00723 FindNodeCall* call = createRpcMessage( findNodeExt ); 00724 lookup->overlay->countFindNodeCall( call ); 00725 lookup->sendRpc( pair.first, call, this, step ); 00726 oldNextHops[pair.first] = pair.second; 00727 } 00728 00729 // delete first element and continue 00730 nextHops.erase( nextHops.begin() ); 00731 } 00732 00733 // no rpc sent and no pending rpcs? -> failed 00734 if ( pendingRpcs == 0 ) { 00735 finished = true; 00736 success = false; 00737 } 00738 }
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 |
00741 { 00742 // create default find node call message 00743 FindNodeCall* call = new FindNodeCall( "FindNodeCall" ); 00744 call->setLookupKey( lookup->key ); 00745 call->setNumRedundantNodes(lookup->config.redundantNodes); 00746 call->setNumSiblings(lookup->numSiblings); 00747 call->setLength( FINDNODECALL_L(call) ); 00748 00749 // duplicate extension object 00750 if ( findNodeExt != NULL ) { 00751 call->addObject( (cObject*)findNodeExt->dup() ); 00752 call->addLength( findNodeExt->length() ); 00753 } 00754 00755 return call; 00756 }
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] |