BootstrapList Class Reference

The BootstrapList module maintains a list of bootstrap node candidates. More...

#include <BootstrapList.h>

Inheritance diagram for BootstrapList:

BaseApp BaseRpc RpcListener

List of all members.

Public Member Functions

 BootstrapList ()
 ~BootstrapList ()
const TransportAddress getBootstrapNode ()
 Get a bootstrap node from the bootstrap list.
void locateBootstrapNode (const NodeHandle &node)
 Determine locality of a bootstrap node.
bool insertBootstrapCandidate (const NodeHandle &node, BootstrapNodePrioType prio=DNSSD)
 Inserts a new bootstrap candidate into the bootstrap list.
bool insertBootstrapCandidate (BootstrapNodeHandle &node)
void removeBootstrapCandidate (const TransportAddress &addr)
 Remove an unavailable bootstrap candidate from the bootstraplist.
void removeBootstrapNode (const NodeHandle &node)
void registerBootstrapNode (const NodeHandle &node)

Protected Member Functions

virtual void pingResponse (PingResponse *pingResponse, cPolymorphic *context, int rpcId, simtime_t rtt)
virtual void pingTimeout (PingCall *pingCall, const TransportAddress &dest, cPolymorphic *context, int rpcId)
virtual CompType getThisCompType ()
 Return the component type of this module.

Private Member Functions

virtual void initializeApp (int stage)
 initializes derived class-attributes
virtual void finishApp ()
 collects statistical data of derived app
void handleTimerEvent (cMessage *msg)
void handleBootstrapListTimerExpired ()
 Periodic maintenance method for the bootstrap list.
void handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.
void handleLookupResponse (LookupResponse *msg)
 Handle the response for a lookup rpc.

Private Attributes

BootstrapNodeSet bootstrapList
cMessage * timerMsg
 self-message for periodic maintenance
ZeroconfConnectorzeroconfConnector
 pointer to the ZeroconfConnector module
bool mergeOverlayPartitions
 if true, detect and merge overlay partitions
bool maintainList
 maintain a list of bootstrap candidates and check them periodically

Static Private Attributes

static const int timerInterval = 10
 the interval of the maintenance timer in seconds


Detailed Description

The BootstrapList module maintains a list of bootstrap node candidates.

The BootstrapList module maintains a list of bootstrap node candidates received from various sources (GlobalNodeList for simulations and ZeroconfConnector for SingleHostUnderlay). This list is also used to detect overlay partitions and triggers the merging process.

Author:
Bin Zheng, Ingmar Baumgart
See also:
BootstrapList

Definition at line 53 of file BootstrapList.h.


Constructor & Destructor Documentation

BootstrapList::BootstrapList (  ) 

Definition at line 59 of file BootstrapList.cc.

00060 {
00061     zeroconfConnector = NULL;
00062     timerMsg = NULL;
00063 }

BootstrapList::~BootstrapList (  ) 

Definition at line 66 of file BootstrapList.cc.

00067 {
00068     cancelAndDelete(timerMsg);
00069 }


Member Function Documentation

void BootstrapList::finishApp (  )  [private, virtual]

collects statistical data of derived app

Reimplemented from BaseApp.

Definition at line 371 of file BootstrapList.cc.

00372 {
00373     // dump the list of bootstrap nodes into the local cache only when
00374     // using SingleHostUnderlayConfigurator
00375     if (zeroconfConnector) {
00376         ofstream nodeListFile("nodelist.dat", ios::out|ios::trunc);
00377         if (!nodeListFile) {
00378             std::cerr << "nodelist.dat could not be opened" << endl;
00379         } else {
00380             for (BootstrapNodeSet::iterator iter = bootstrapList.begin();
00381                  iter != bootstrapList.end(); iter++) {
00382                 nodeListFile << iter->second->getAddress().str() << ' '
00383                              << iter->second->getPort() << ' '
00384                              << iter->second->getKey().toString(16) << '\n';
00385             }
00386             nodeListFile.close();
00387         }
00388     }
00389 
00390     // delete all bootstrap nodes and clear the list
00391     for (BootstrapNodeSet::iterator iter = bootstrapList.begin();
00392          iter != bootstrapList.end(); iter++) {
00393         delete iter->second;
00394     }
00395 
00396     bootstrapList.clear();
00397 }

const TransportAddress BootstrapList::getBootstrapNode (  ) 

Get a bootstrap node from the bootstrap list.

If not using SingleHostUnderlayConfigurator and the list is empty, return a node by asking the GlobalNodeList.

Definition at line 231 of file BootstrapList.cc.

Referenced by BasePastry::baseChangeState(), Gia::changeState(), oversim::Chord::changeState(), Broose::changeState(), Vast::handleJoin(), Quon::handleJoin(), and Kademlia::joinOverlay().

00232 {
00233     if (!maintainList) {
00234         // TODO: add a parameter to return malicious bootstrap nodes also
00235         // return overlay->globalNodeList->getRandomNode(0, true, PARAMETER);
00236         return overlay->globalNodeList->getBootstrapNode();
00237     } else {
00238         const NodeHandle *bootstrapNode = &NodeHandle::UNSPECIFIED_NODE;
00239         int i, j = 0;
00240 
00241         // pick a random node from the list
00242         if (!bootstrapList.empty()) {
00243             i = intrand(bootstrapList.size());
00244             BootstrapNodeSet::iterator iter = bootstrapList.begin();
00245 
00246             while (j < i) {
00247                 iter++;
00248                 j++;
00249             }
00250 
00251             bootstrapNode = (NodeHandle *)iter->second;
00252         } else {
00253             // if the list empty, get a bootstrap node from GlobalNodeList
00254             if (!zeroconfConnector)
00255                 bootstrapNode = &overlay->globalNodeList->
00256                         getBootstrapNode(overlay->getThisNode());
00257         }
00258         return *bootstrapNode;
00259     }
00260 }

virtual CompType BootstrapList::getThisCompType (  )  [inline, protected, virtual]

Return the component type of this module.

This method is overloaded by BaseOverlay/BaseApp and returns the appropriate component type of this module.

Returns:
the component type of this module

Reimplemented from BaseApp.

Definition at line 110 of file BootstrapList.h.

00110 { return BOOTSTRAPLIST_COMP; };

void BootstrapList::handleBootstrapListTimerExpired (  )  [private]

Periodic maintenance method for the bootstrap list.

Definition at line 134 of file BootstrapList.cc.

Referenced by handleTimerEvent().

00135 {
00136     simtime_t current = simTime();
00137     BootstrapNodeHandle *node;
00138     BootstrapNodeSet::iterator iter;
00139 
00140     for (iter = bootstrapList.begin(); iter != bootstrapList.end(); iter++) {
00141         node = iter->second;
00142         if (timerInterval <= SIMTIME_DBL(current - node->getLastPing())) {
00143             pingNode(*node);
00144         }
00145     }
00146 }

void BootstrapList::handleLookupResponse ( LookupResponse msg  )  [private]

Handle the response for a lookup rpc.

This is used to detected foreign overlay partitions

Parameters:
msg The lookup response message

Definition at line 166 of file BootstrapList.cc.

Referenced by handleRpcResponse().

00167 {
00168     EV << "[BootstrapList::handleLookupResponse() @ "
00169        << overlay->getThisNode().getAddress()
00170        << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00171        << "    Lookup response for key " << msg->getKey()<< " : ";
00172 
00173     if (msg->getIsValid()) {
00174         for (uint32_t i=0; i<msg->getSiblingsArraySize(); i++) {
00175             if (msg->getSiblings(i).getKey() == msg->getKey()) {
00176                 EV << "Key " << msg->getSiblings(i)
00177                    << "belongs to a local node." << endl;
00178                 return;
00179             }
00180         }
00181 
00182         EV << "New partition discovered, going to join." << endl;
00183         BootstrapNodeSet::iterator iter;
00184         for (iter = bootstrapList.begin(); iter != bootstrapList.end(); iter++) {
00185             if (iter->second->getKey() == msg->getKey())
00186                 overlay->joinForeignPartition(*iter->second);
00187         }
00188 
00189     } else {
00190         EV << "failed" << endl;
00191     }
00192 
00193     return;
00194 }

void BootstrapList::handleRpcResponse ( BaseResponseMessage msg,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [private, virtual]

This method is called if an RPC response has been received.

Parameters:
msg The response message.
context Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

Definition at line 149 of file BootstrapList.cc.

00152 {
00153     RPC_SWITCH_START(msg)
00154     RPC_ON_RESPONSE(Lookup) {
00155         handleLookupResponse(_LookupResponse);
00156         EV << "[BootstrapList::handleRpcResponse() @ "
00157            << overlay->getThisNode().getAddress()
00158            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00159            << "    Lookup RPC Response received: id=" << rpcId << "\n"
00160            << "    msg=" << *_LookupResponse << " rtt=" << rtt
00161            << endl;
00162     }
00163     RPC_SWITCH_END( )
00164 }

void BootstrapList::handleTimerEvent ( cMessage *  msg  )  [private, virtual]

Reimplemented from BaseRpc.

Definition at line 123 of file BootstrapList.cc.

00124 {
00125     if (msg == timerMsg) {
00126         handleBootstrapListTimerExpired();
00127         scheduleAt(simTime() + timerInterval, msg);
00128     } else {
00129         throw cRuntimeError("BootstrapList::handleTimerEvent(): "
00130                              "Received unknown self-message!");
00131     }
00132 }

void BootstrapList::initializeApp ( int  stage  )  [private, virtual]

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

Definition at line 72 of file BootstrapList.cc.

00073 {
00074     if (stage != MIN_STAGE_APP) {
00075         return;
00076     }
00077 
00078     mergeOverlayPartitions = par("mergeOverlayPartitions");
00079     maintainList = par("maintainList");
00080 
00081     if (getParentModule()->getParentModule()->getSubmodule("zeroconfConnector", 0)) {
00082         zeroconfConnector = check_and_cast<ZeroconfConnector *>(getParentModule()->
00083                 getParentModule()->getSubmodule("zeroconfConnector", 0));
00084         if (!zeroconfConnector->isEnabled()) {
00085             zeroconfConnector = NULL;
00086         }
00087     }
00088 
00089     // load local cache list only when using SingleHostUnderlayConfigurator
00090     if (zeroconfConnector) {
00091         ifstream nodeListFile("nodelist.dat", ios::in);
00092         if (!nodeListFile) {
00093             EV << "[BootstrapList::initializeApp() @ " << overlay->getThisNode().getAddress()
00094                << " (" << overlay->getThisNode().getKey() << ")]\n"
00095                << "    nodelist.dat not found"
00096                << endl;
00097         } else {
00098             char address[16];
00099             int port;
00100             string key;
00101             BootstrapNodeHandle *node;
00102 
00103             while (nodeListFile >> address >> port >> key) {
00104                 node = new BootstrapNodeHandle(OverlayKey(key, 16),
00105                                                IPvXAddress(address), port,
00106                                                CACHE);
00107                 if (node)
00108                     insertBootstrapCandidate(*node);
00109             }
00110             nodeListFile.close();
00111         }
00112     }
00113 
00114     WATCH_UNORDERED_MAP(bootstrapList);
00115 
00116     if (maintainList) {
00117         timerMsg = new cMessage("BootstrapListTimer");
00118         scheduleAt(simTime() + timerInterval, timerMsg);
00119     }
00120 }

bool BootstrapList::insertBootstrapCandidate ( BootstrapNodeHandle node  ) 

Definition at line 307 of file BootstrapList.cc.

00308 {
00309     Enter_Method_Silent();
00310 
00311     BootstrapNodeSet::iterator iter;
00312 
00313     node.setLastPing(simTime());
00314 
00315     // if node already in the list, update its lastPing and nodePrio fields
00316     if ((iter = bootstrapList.find(node)) != bootstrapList.end()) {
00317         iter->second->setLastPing(node.getLastPing());
00318         iter->second->setNodePrio(node.getNodePrio());
00319 
00320         return true;
00321     }
00322 
00323     bootstrapList.insert(NodePair(node, &node));
00324     locateBootstrapNode(node);
00325 
00326     return false;
00327 }

bool BootstrapList::insertBootstrapCandidate ( const NodeHandle node,
BootstrapNodePrioType  prio = DNSSD 
)

Inserts a new bootstrap candidate into the bootstrap list.

Parameters:
node the bootstrap candidate
prio priority of the bootstrap node
Returns:
true, if bootstrap node is already in the list

Definition at line 280 of file BootstrapList.cc.

Referenced by initializeApp(), and GlobalNodeList::mergeBootstrapNodes().

00282 {
00283     Enter_Method_Silent();
00284 
00285     BootstrapNodeSet::iterator iter;
00286     BootstrapNodeHandle *bootstrapNode;
00287 
00288     // if node already in the list, update its lastPing and nodePrio fields
00289     if ((iter = bootstrapList.find(node)) != bootstrapList.end()) {
00290         iter->second->setLastPing(simTime());
00291         iter->second->setNodePrio(prio);
00292 
00293         return true;
00294     }
00295 
00296     if ((bootstrapNode = new BootstrapNodeHandle(node, prio))) {
00297         bootstrapNode->setLastPing(simTime());
00298         bootstrapList.insert(NodePair(*bootstrapNode, bootstrapNode));
00299     }
00300 
00301     locateBootstrapNode(node);
00302 
00303     return false;
00304 }

void BootstrapList::locateBootstrapNode ( const NodeHandle node  ) 

Determine locality of a bootstrap node.

Parameters:
node the newly discovered bootstrap node

Definition at line 263 of file BootstrapList.cc.

Referenced by insertBootstrapCandidate().

00264 {
00265     Enter_Method_Silent();
00266 
00267     if ((overlay->getState() == BaseOverlay::READY) && (!node.isUnspecified())
00268             && mergeOverlayPartitions) {
00269        LookupCall* call = new LookupCall();
00270        call->setBitLength(0);
00271        call->setKey(node.getKey());
00272        call->setNumSiblings(overlay->getMaxNumSiblings());
00273        sendInternalRpcCall(OVERLAY_COMP, call);
00274     }
00275 
00276     return;
00277 }

void BootstrapList::pingResponse ( PingResponse pingResponse,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

Reimplemented from BaseRpc.

Definition at line 197 of file BootstrapList.cc.

00200 {
00201     NodeHandle &srcNode = pingResponse->getSrcNode();
00202     BootstrapNodeSet::iterator iter;
00203 
00204     EV << "[BootstrapList::pingResponse() @ " << overlay->getThisNode().getAddress()
00205            << " (" << overlay->getThisNode().getKey() << ")]\n"
00206            << "    Ping response from node " << srcNode
00207            << " with rtt " << rtt << endl;
00208 
00209     // update the lastPing field of the source node
00210     if (!srcNode.isUnspecified())
00211         if ((iter = bootstrapList.find(srcNode)) != bootstrapList.end())
00212             iter->second->setLastPing(simTime());
00213 
00214     return;
00215 }

void BootstrapList::pingTimeout ( PingCall pingCall,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId 
) [protected, virtual]

Reimplemented from BaseRpc.

Definition at line 218 of file BootstrapList.cc.

00222 {
00223     EV << "[BootstrapList::pingTimeout() @ " << overlay->getThisNode().getAddress()
00224        << " (" << overlay->getThisNode().getKey() << ")]\n"
00225        << "    Ping timeout for node " << dest << endl;
00226     // destination does not answer, remove it from the list
00227     removeBootstrapCandidate(dest);
00228 }

void BootstrapList::registerBootstrapNode ( const NodeHandle node  ) 

Definition at line 359 of file BootstrapList.cc.

Referenced by BaseOverlay::setOverlayReady().

00360 {
00361     globalNodeList->registerPeer(node);
00362 
00363     // at this point, we consider this node as booted and therefore have to
00364     // announce the boot service for it via zeroconfConnector
00365     if (zeroconfConnector) {
00366         zeroconfConnector->announceService(node);
00367     }
00368 }

void BootstrapList::removeBootstrapCandidate ( const TransportAddress addr  ) 

Remove an unavailable bootstrap candidate from the bootstraplist.

Parameters:
addr the address of the bootstrap candidate

Definition at line 330 of file BootstrapList.cc.

Referenced by pingTimeout().

00331 {
00332     BootstrapNodeSet::iterator iter;
00333     BootstrapNodeHandle* bootstrapNode;
00334 
00335     if (!addr.isUnspecified()) {
00336         if ((iter = bootstrapList.find(addr)) != bootstrapList.end()) {
00337             bootstrapNode = iter->second;
00338             bootstrapList.erase(iter);
00339             delete bootstrapNode;
00340         }
00341     }
00342 
00343     return;
00344 }

void BootstrapList::removeBootstrapNode ( const NodeHandle node  ) 

Definition at line 347 of file BootstrapList.cc.

Referenced by BasePastry::baseChangeState(), Gia::finishOverlay(), oversim::Chord::finishOverlay(), BasePastry::finishOverlay(), Kademlia::joinOverlay(), and BaseOverlay::setOverlayReady().

00348 {
00349     overlay->globalNodeList->removePeer(node);
00350     // at this point, we consider this node not being able to provide the
00351     // boot service anymore, therefore we have to revoke
00352     // the service via zeroconfConnector
00353     if (zeroconfConnector) {
00354         zeroconfConnector->revokeService();
00355     }
00356 }


Member Data Documentation

maintain a list of bootstrap candidates and check them periodically

Definition at line 147 of file BootstrapList.h.

Referenced by getBootstrapNode(), and initializeApp().

if true, detect and merge overlay partitions

Definition at line 146 of file BootstrapList.h.

Referenced by initializeApp(), and locateBootstrapNode().

const int BootstrapList::timerInterval = 10 [static, private]

the interval of the maintenance timer in seconds

Definition at line 142 of file BootstrapList.h.

Referenced by handleBootstrapListTimerExpired(), handleTimerEvent(), and initializeApp().

cMessage* BootstrapList::timerMsg [private]

self-message for periodic maintenance

Definition at line 144 of file BootstrapList.h.

Referenced by BootstrapList(), handleTimerEvent(), initializeApp(), and ~BootstrapList().


The documentation for this class was generated from the following files:

Generated on Tue Sep 8 17:26:57 2009 for OverSim by  doxygen 1.5.8