The BootstrapList module maintains a list of bootstrap node candidates. More...
#include <BootstrapList.h>
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 | |
ZeroconfConnector * | zeroconfConnector |
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 |
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.
Definition at line 53 of file BootstrapList.h.
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 }
void BootstrapList::finishApp | ( | ) | [private, virtual] |
collects statistical data of derived app
Reimplemented from BaseApp.
Definition at line 376 of file BootstrapList.cc.
00377 { 00378 // dump the list of bootstrap nodes into the local cache only when 00379 // using SingleHostUnderlayConfigurator 00380 if (zeroconfConnector) { 00381 ofstream nodeListFile("nodelist.dat", ios::out|ios::trunc); 00382 if (!nodeListFile) { 00383 std::cerr << "nodelist.dat could not be opened" << endl; 00384 } else { 00385 for (BootstrapNodeSet::iterator iter = bootstrapList.begin(); 00386 iter != bootstrapList.end(); iter++) { 00387 nodeListFile << iter->second->getAddress().str() << ' ' 00388 << iter->second->getPort() << ' ' 00389 << iter->second->getKey().toString(16) << '\n'; 00390 } 00391 nodeListFile.close(); 00392 } 00393 } 00394 00395 // delete all bootstrap nodes and clear the list 00396 for (BootstrapNodeSet::iterator iter = bootstrapList.begin(); 00397 iter != bootstrapList.end(); iter++) { 00398 delete iter->second; 00399 } 00400 00401 bootstrapList.clear(); 00402 }
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 236 of file BootstrapList.cc.
Referenced by BasePastry::baseChangeState(), Gia::changeState(), oversim::Chord::changeState(), Broose::changeState(), Vast::handleJoin(), Quon::handleJoin(), and Kademlia::joinOverlay().
00237 { 00238 if (!maintainList) { 00239 // TODO: add a parameter to return malicious bootstrap nodes also 00240 return overlay->globalNodeList->getRandomNode(0, true, true); 00241 // return overlay->globalNodeList->getBootstrapNode(); 00242 } else { 00243 const NodeHandle *bootstrapNode = &NodeHandle::UNSPECIFIED_NODE; 00244 int i, j = 0; 00245 00246 // pick a random node from the list 00247 if (!bootstrapList.empty()) { 00248 i = intrand(bootstrapList.size()); 00249 BootstrapNodeSet::iterator iter = bootstrapList.begin(); 00250 00251 while (j < i) { 00252 iter++; 00253 j++; 00254 } 00255 00256 bootstrapNode = (NodeHandle *)iter->second; 00257 } else { 00258 // if the list empty, get a bootstrap node from GlobalNodeList 00259 if (!zeroconfConnector) 00260 bootstrapNode = &overlay->globalNodeList-> 00261 getBootstrapNode(overlay->getThisNode()); 00262 } 00263 return *bootstrapNode; 00264 } 00265 }
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.
Reimplemented from BaseApp.
Definition at line 110 of file BootstrapList.h.
void BootstrapList::handleBootstrapListTimerExpired | ( | ) | [private] |
Periodic maintenance method for the bootstrap list.
Definition at line 139 of file BootstrapList.cc.
Referenced by handleTimerEvent().
00140 { 00141 simtime_t current = simTime(); 00142 BootstrapNodeHandle *node; 00143 BootstrapNodeSet::iterator iter; 00144 00145 for (iter = bootstrapList.begin(); iter != bootstrapList.end(); iter++) { 00146 node = iter->second; 00147 if (timerInterval <= SIMTIME_DBL(current - node->getLastPing())) { 00148 pingNode(*node); 00149 } 00150 } 00151 }
void BootstrapList::handleLookupResponse | ( | LookupResponse * | msg | ) | [private] |
Handle the response for a lookup rpc.
This is used to detected foreign overlay partitions
msg | The lookup response message |
Definition at line 171 of file BootstrapList.cc.
Referenced by handleRpcResponse().
00172 { 00173 EV << "[BootstrapList::handleLookupResponse() @ " 00174 << overlay->getThisNode().getAddress() 00175 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n" 00176 << " Lookup response for key " << msg->getKey()<< " : "; 00177 00178 if (msg->getIsValid()) { 00179 for (uint32_t i=0; i<msg->getSiblingsArraySize(); i++) { 00180 if (msg->getSiblings(i).getKey() == msg->getKey()) { 00181 EV << "Key " << msg->getSiblings(i) 00182 << "belongs to a local node." << endl; 00183 return; 00184 } 00185 } 00186 00187 EV << "New partition discovered, going to join." << endl; 00188 BootstrapNodeSet::iterator iter; 00189 for (iter = bootstrapList.begin(); iter != bootstrapList.end(); iter++) { 00190 if (iter->second->getKey() == msg->getKey()) 00191 overlay->joinForeignPartition(*iter->second); 00192 } 00193 00194 } else { 00195 EV << "failed" << endl; 00196 } 00197 00198 return; 00199 }
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.
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 154 of file BootstrapList.cc.
00157 { 00158 RPC_SWITCH_START(msg) 00159 RPC_ON_RESPONSE(Lookup) { 00160 handleLookupResponse(_LookupResponse); 00161 EV << "[BootstrapList::handleRpcResponse() @ " 00162 << overlay->getThisNode().getAddress() 00163 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n" 00164 << " Lookup RPC Response received: id=" << rpcId << "\n" 00165 << " msg=" << *_LookupResponse << " rtt=" << rtt 00166 << endl; 00167 } 00168 RPC_SWITCH_END( ) 00169 }
void BootstrapList::handleTimerEvent | ( | cMessage * | msg | ) | [private, virtual] |
Reimplemented from BaseRpc.
Definition at line 128 of file BootstrapList.cc.
00129 { 00130 if (msg == timerMsg) { 00131 handleBootstrapListTimerExpired(); 00132 scheduleAt(simTime() + timerInterval, msg); 00133 } else { 00134 throw cRuntimeError("BootstrapList::handleTimerEvent(): " 00135 "Received unknown self-message!"); 00136 } 00137 }
void BootstrapList::initializeApp | ( | int | stage | ) | [private, virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented from BaseApp.
Definition at line 72 of file BootstrapList.cc.
00073 { 00074 if (stage != MIN_STAGE_COMPONENTS) { 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 //TODO 00113 if (bootstrapList.size()) sendReadyMessage(); 00114 } 00115 } else { 00116 sendReadyMessage(); 00117 } 00118 00119 WATCH_UNORDERED_MAP(bootstrapList); 00120 00121 if (maintainList) { 00122 timerMsg = new cMessage("BootstrapListTimer"); 00123 scheduleAt(simTime() + timerInterval, timerMsg); 00124 } 00125 }
bool BootstrapList::insertBootstrapCandidate | ( | BootstrapNodeHandle & | node | ) |
Definition at line 312 of file BootstrapList.cc.
00313 { 00314 Enter_Method_Silent(); 00315 00316 BootstrapNodeSet::iterator iter; 00317 00318 node.setLastPing(simTime()); 00319 00320 // if node already in the list, update its lastPing and nodePrio fields 00321 if ((iter = bootstrapList.find(node)) != bootstrapList.end()) { 00322 iter->second->setLastPing(node.getLastPing()); 00323 iter->second->setNodePrio(node.getNodePrio()); 00324 00325 return true; 00326 } 00327 00328 bootstrapList.insert(NodePair(node, &node)); 00329 locateBootstrapNode(node); 00330 00331 return false; 00332 }
bool BootstrapList::insertBootstrapCandidate | ( | const NodeHandle & | node, | |
BootstrapNodePrioType | prio = DNSSD | |||
) |
Inserts a new bootstrap candidate into the bootstrap list.
node | the bootstrap candidate | |
prio | priority of the bootstrap node |
Definition at line 285 of file BootstrapList.cc.
Referenced by initializeApp(), and GlobalNodeList::mergeBootstrapNodes().
00287 { 00288 Enter_Method_Silent(); 00289 00290 BootstrapNodeSet::iterator iter; 00291 BootstrapNodeHandle *bootstrapNode; 00292 00293 // if node already in the list, update its lastPing and nodePrio fields 00294 if ((iter = bootstrapList.find(node)) != bootstrapList.end()) { 00295 iter->second->setLastPing(simTime()); 00296 iter->second->setNodePrio(prio); 00297 00298 return true; 00299 } 00300 00301 if ((bootstrapNode = new BootstrapNodeHandle(node, prio))) { 00302 bootstrapNode->setLastPing(simTime()); 00303 bootstrapList.insert(NodePair(*bootstrapNode, bootstrapNode)); 00304 } 00305 00306 locateBootstrapNode(node); 00307 00308 return false; 00309 }
void BootstrapList::locateBootstrapNode | ( | const NodeHandle & | node | ) |
Determine locality of a bootstrap node.
node | the newly discovered bootstrap node |
Definition at line 268 of file BootstrapList.cc.
Referenced by insertBootstrapCandidate().
00269 { 00270 Enter_Method_Silent(); 00271 00272 if ((overlay->getState() == BaseOverlay::READY) && (!node.isUnspecified()) 00273 && mergeOverlayPartitions) { 00274 LookupCall* call = new LookupCall(); 00275 call->setBitLength(0); 00276 call->setKey(node.getKey()); 00277 call->setNumSiblings(overlay->getMaxNumSiblings()); 00278 sendInternalRpcCall(OVERLAY_COMP, call); 00279 } 00280 00281 return; 00282 }
void BootstrapList::pingResponse | ( | PingResponse * | pingResponse, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [protected, virtual] |
Reimplemented from BaseRpc.
Definition at line 202 of file BootstrapList.cc.
00205 { 00206 NodeHandle &srcNode = pingResponse->getSrcNode(); 00207 BootstrapNodeSet::iterator iter; 00208 00209 EV << "[BootstrapList::pingResponse() @ " << overlay->getThisNode().getAddress() 00210 << " (" << overlay->getThisNode().getKey() << ")]\n" 00211 << " Ping response from node " << srcNode 00212 << " with rtt " << rtt << endl; 00213 00214 // update the lastPing field of the source node 00215 if (!srcNode.isUnspecified()) 00216 if ((iter = bootstrapList.find(srcNode)) != bootstrapList.end()) 00217 iter->second->setLastPing(simTime()); 00218 00219 return; 00220 }
void BootstrapList::pingTimeout | ( | PingCall * | pingCall, | |
const TransportAddress & | dest, | |||
cPolymorphic * | context, | |||
int | rpcId | |||
) | [protected, virtual] |
Reimplemented from BaseRpc.
Definition at line 223 of file BootstrapList.cc.
00227 { 00228 EV << "[BootstrapList::pingTimeout() @ " << overlay->getThisNode().getAddress() 00229 << " (" << overlay->getThisNode().getKey() << ")]\n" 00230 << " Ping timeout for node " << dest << endl; 00231 // destination does not answer, remove it from the list 00232 removeBootstrapCandidate(dest); 00233 }
void BootstrapList::registerBootstrapNode | ( | const NodeHandle & | node | ) |
Definition at line 364 of file BootstrapList.cc.
Referenced by BaseOverlay::setOverlayReady().
00365 { 00366 globalNodeList->registerPeer(node); 00367 00368 // at this point, we consider this node as booted and therefore have to 00369 // announce the boot service for it via zeroconfConnector 00370 if (zeroconfConnector) { 00371 zeroconfConnector->announceService(node); 00372 } 00373 }
void BootstrapList::removeBootstrapCandidate | ( | const TransportAddress & | addr | ) |
Remove an unavailable bootstrap candidate from the bootstraplist.
addr | the address of the bootstrap candidate |
Definition at line 335 of file BootstrapList.cc.
Referenced by pingTimeout().
00336 { 00337 BootstrapNodeSet::iterator iter; 00338 BootstrapNodeHandle* bootstrapNode; 00339 00340 if (!addr.isUnspecified()) { 00341 if ((iter = bootstrapList.find(addr)) != bootstrapList.end()) { 00342 bootstrapNode = iter->second; 00343 bootstrapList.erase(iter); 00344 delete bootstrapNode; 00345 } 00346 } 00347 00348 return; 00349 }
void BootstrapList::removeBootstrapNode | ( | const NodeHandle & | node | ) |
Definition at line 352 of file BootstrapList.cc.
Referenced by BasePastry::baseChangeState(), Gia::finishOverlay(), oversim::Chord::finishOverlay(), BasePastry::finishOverlay(), Kademlia::joinOverlay(), and BaseOverlay::setOverlayReady().
00353 { 00354 overlay->globalNodeList->removePeer(node); 00355 // at this point, we consider this node not being able to provide the 00356 // boot service anymore, therefore we have to revoke 00357 // the service via zeroconfConnector 00358 if (zeroconfConnector) { 00359 zeroconfConnector->revokeService(); 00360 } 00361 }
BootstrapNodeSet BootstrapList::bootstrapList [private] |
Definition at line 110 of file BootstrapList.h.
Referenced by finishApp(), getBootstrapNode(), handleBootstrapListTimerExpired(), handleLookupResponse(), initializeApp(), insertBootstrapCandidate(), pingResponse(), and removeBootstrapCandidate().
bool BootstrapList::maintainList [private] |
maintain a list of bootstrap candidates and check them periodically
Definition at line 147 of file BootstrapList.h.
Referenced by getBootstrapNode(), and initializeApp().
bool BootstrapList::mergeOverlayPartitions [private] |
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().
pointer to the ZeroconfConnector module
Definition at line 145 of file BootstrapList.h.
Referenced by BootstrapList(), finishApp(), getBootstrapNode(), initializeApp(), registerBootstrapNode(), and removeBootstrapNode().