#include <BootstrapOracle.h>
Public Types | |
typedef std::vector < OverlayKey > | KeyList |
holds all OverlayKeys | |
typedef std::map < OverlayKey, DHTEntry > | DataMap |
Public Member Functions | |
void | addPeer (const IPvXAddress &ip, PeerInfo *info) |
Adds new peers to the peer set. | |
void | sendNotificationToAllPeers (int category) |
Sends a NotificationBoard message to all registered peers. | |
virtual void | killPeer (const IPvXAddress &ip) |
Removes a peer from the peerSet. | |
virtual const NodeHandle & | getRandomNode (uint32_t nodeType=0, bool bootstrappedNeeded=true) |
Returns a random NodeHandle. | |
virtual const NodeHandle & | getBootstrapNode () |
Returns a random NodeHandle. | |
virtual void | registerPeer (const TransportAddress &peer) |
Bootstraps peers in the peer set. | |
virtual void | registerPeer (const NodeHandle &peer) |
Bootstraps peers in the peer set. | |
virtual void | removePeer (const TransportAddress &peer) |
Debootstraps peers in the peer set. | |
virtual KeyList * | getKeyList (uint maximumKeys) |
Returns a keylist. | |
virtual DataMap * | getDataMap () |
virtual const OverlayKey & | getRandomKeyListItem () const |
Returns random key from list. | |
virtual void | setOverlayReadyIcon (const TransportAddress &address, bool ready) |
Colors module-icon blue (ready), green (ready, malicious) or red (not ready). | |
virtual PeerInfo * | getPeerInfo (const TransportAddress &peer) |
Searches the peerSet for the specified node. | |
virtual void | setMalicious (const TransportAddress &address, bool malicious) |
Set a node to be malicious. | |
virtual bool | isMalicious (const TransportAddress &address) |
Check if a node is malicious. | |
virtual PeerInfo * | getRandomPeerInfo (uint32_t nodeType=0, bool bootstrapNeeded=false) |
Selects a random node from the peerSet. | |
virtual PeerInfo * | getPeerInfo (const IPvXAddress &ip) |
Searches the peerSet for the specified node. | |
bool | areNodeTypesConnected (uint32_t a, uint32_t b) |
void | connectNodeTypes (uint32_t a, uint32_t b) |
void | disconnectNodeTypes (uint32_t a, uint32_t b) |
void | mergeBootstrapNodes (int toPartition, int fromPartition, int numNodes) |
Protected Types | |
typedef __gnu_cxx::hash_map < IPvXAddress, bootstrapEntry > | PeerHashMap |
Set of nodes participating in the overlay. | |
Protected Member Functions | |
virtual void | initialize () |
Init member function of module. | |
virtual void | handleMessage (cMessage *msg) |
HandleMessage member function of module. | |
virtual void | createKeyList (uint size) |
Member function to create keylist. | |
Protected Attributes | |
KeyList | keyList |
the keylist | |
DataMap | dataMap |
the datamap | |
uint | bootstrappedPeerSize |
number of bootstrapped peers in the peer set | |
uint | bootstrappedMaliciousNodes |
number of bootstrapped malicious nodes in the peer set | |
uint | maliciousNodes |
number of malicious nodes in the peer set | |
double | maliciousNodeRatio |
ratio of current malicious nodes when changing the ratio dynamically | |
cOutVector | maliciousNodesVector |
vector that records the cange of malicious node rate | |
PeerHashMap | peerSet |
Set of nodes participating in the overlay. | |
uint | maxNumberOfKeys |
parameter used by createKeyList() | |
double | keyProbability |
probability of keys to be owned by nodes | |
Private Attributes | |
uint32 | min_ip |
uint32 | max_ip |
used for random node choosing | |
GlobalStatistics * | globalStatistics |
pointer to GlobalStatistics module in this node | |
bool | connectionMatrix [MAX_NODETYPES][MAX_NODETYPES] |
matrix specifices with node types (partitions) can communication |
typedef std::vector<OverlayKey> BootstrapOracle::KeyList |
holds all OverlayKeys
typedef std::map<OverlayKey, DHTEntry> BootstrapOracle::DataMap |
typedef __gnu_cxx::hash_map<IPvXAddress, bootstrapEntry> BootstrapOracle::PeerHashMap [protected] |
Set of nodes participating in the overlay.
void BootstrapOracle::addPeer | ( | const IPvXAddress & | ip, | |
PeerInfo * | info | |||
) |
Adds new peers to the peer set.
Called automatically by the underlay, when new peers are created.
ip | IPvXAddress of the peer to add | |
info | underlay specific info of the peer to add |
00191 { 00192 bootstrapEntry temp; 00193 temp.node = new TransportAddress(ip); 00194 temp.info = info; 00195 peerSet.insert(std::make_pair(temp.node->ip, temp)); 00196 // set bounds for random node retrival 00197 if(ip.get4().getInt() < min_ip) min_ip = ip.get4().getInt(); 00198 if(ip.get4().getInt() > max_ip) max_ip = ip.get4().getInt(); 00199 00200 if (uniform(0, 1) < (double) par("maliciousNodeProbability") || 00201 (par("maliciousNodeChange") && uniform(0, 1) < maliciousNodeRatio)) 00202 setMalicious(*temp.node, true); 00203 }
void BootstrapOracle::sendNotificationToAllPeers | ( | int | category | ) |
Sends a NotificationBoard message to all registered peers.
category | Type of notification |
00179 { 00180 PeerHashMap::iterator it; 00181 for (it = peerSet.begin(); it != peerSet.end(); it++) { 00182 NotificationBoard* nb = check_and_cast<NotificationBoard*>( 00183 simulation.module(it->second.info->getModuleID()) 00184 ->submodule("notificationBoard")); 00185 00186 nb->fireChangeNotification(category); 00187 } 00188 }
void BootstrapOracle::killPeer | ( | const IPvXAddress & | ip | ) | [virtual] |
Removes a peer from the peerSet.
Called automatically by the underlay, when peers are removed.
ip | IPvXAddress of the peer to remove |
00272 { 00273 PeerHashMap::iterator it = peerSet.find(ip); 00274 if(it != peerSet.end()) { 00275 if(it->second.info->isBootstrapped()) { 00276 bootstrappedPeerSize--; 00277 00278 if(it->second.info->isMalicious()) 00279 bootstrappedMaliciousNodes--; 00280 00281 it->second.info->setBootstrapped(false); 00282 } 00283 00284 delete it->second.node; 00285 delete it->second.info; 00286 peerSet.erase(it); 00287 } 00288 }
const NodeHandle & BootstrapOracle::getRandomNode | ( | uint32_t | nodeType = 0 , |
|
bool | bootstrappedNeeded = true | |||
) | [virtual] |
Returns a random NodeHandle.
Returns a random NodeHandle from the peerSet if at least one peer has been registered, an empty TransportAddress otherwise.
nodeType | If != 0, return a node of that type | |
bootstrappedNeeded | does the node need to be bootstrapped? |
00145 { 00146 if (peerSet.size() == 0) 00147 return NodeHandle::UNSPECIFIED_NODE; 00148 if (bootstrappedNeeded && bootstrappedPeerSize == 0) 00149 return NodeHandle::UNSPECIFIED_NODE; 00150 else { 00151 // return random TransportAddress in O(log n) 00152 PeerHashMap::iterator it = peerSet.end(); 00153 bootstrapEntry tempEntry = {NULL, NULL}; 00154 00155 while(it == peerSet.end() ||(nodeType && (it->second.info->getTypeID() != nodeType)) 00156 || (bootstrappedNeeded && !it->second.info->isBootstrapped())) { 00157 IPvXAddress randomAddr(intuniform(min_ip, max_ip)); 00158 00159 it = peerSet.find(randomAddr); 00160 00161 if (it == peerSet.end()) { 00162 it = peerSet.insert(std::make_pair(randomAddr,tempEntry)).first; 00163 peerSet.erase(it++); 00164 } 00165 00166 if (it == peerSet.end()) 00167 it = peerSet.begin(); 00168 } 00169 00170 if(dynamic_cast<NodeHandle*>(it->second.node)) { 00171 return *dynamic_cast<NodeHandle*>(it->second.node); 00172 } else { 00173 return NodeHandle::UNSPECIFIED_NODE; 00174 } 00175 } 00176 }
const NodeHandle & BootstrapOracle::getBootstrapNode | ( | ) | [virtual] |
Returns a random NodeHandle.
Returns a random NodeHandle of an already bootstrapped node from the peerSet if at least one peer has been registered, an empty TransportAddress otherwise.
00140 { 00141 return getRandomNode(0, true); 00142 }
void BootstrapOracle::registerPeer | ( | const TransportAddress & | peer | ) | [virtual] |
Bootstraps peers in the peer set.
peer | node to register |
00206 { 00207 PeerHashMap::iterator it = peerSet.find(peer.ip); 00208 if (it == peerSet.end()) 00209 error("unable to bootstrap peer, peer is not in peer set"); 00210 else { 00211 PeerInfo* info = it->second.info; 00212 00213 if (!info->isBootstrapped()) { 00214 bootstrappedPeerSize++; 00215 info->setBootstrapped(); 00216 00217 if (info->isMalicious()) 00218 bootstrappedMaliciousNodes++; 00219 } 00220 00221 delete it->second.node; 00222 peerSet.erase(it); 00223 00224 bootstrapEntry temp; 00225 temp.node = new TransportAddress(peer); 00226 temp.info = info; 00227 peerSet.insert(std::make_pair(temp.node->ip, temp)); 00228 } 00229 }
void BootstrapOracle::registerPeer | ( | const NodeHandle & | peer | ) | [virtual] |
Bootstraps peers in the peer set.
peer | node to register |
00232 { 00233 PeerHashMap::iterator it = peerSet.find(peer.ip); 00234 if (it == peerSet.end()) 00235 error("unable to bootstrap peer, peer is not in peer set"); 00236 else { 00237 PeerInfo* info = it->second.info; 00238 00239 if (!info->isBootstrapped()) { 00240 bootstrappedPeerSize++; 00241 info->setBootstrapped(); 00242 00243 if (info->isMalicious()) 00244 bootstrappedMaliciousNodes++; 00245 } 00246 00247 delete it->second.node; 00248 peerSet.erase(it); 00249 00250 bootstrapEntry temp; 00251 temp.node = new NodeHandle(peer); 00252 temp.info = info; 00253 peerSet.insert(std::make_pair(temp.node->ip, temp)); 00254 } 00255 }
void BootstrapOracle::removePeer | ( | const TransportAddress & | peer | ) | [virtual] |
Debootstraps peers in the peer set.
peer | node to remove |
00258 { 00259 PeerHashMap::iterator it = peerSet.find(peer.ip); 00260 if(it != peerSet.end() && it->second.info->isBootstrapped()) { 00261 bootstrappedPeerSize--; 00262 it->second.info->setBootstrapped(false); 00263 00264 if(it->second.info->isMalicious()) 00265 bootstrappedMaliciousNodes--; 00266 00267 it->second.info->setBootstrapped(false); 00268 } 00269 }
BootstrapOracle::KeyList * BootstrapOracle::getKeyList | ( | uint | maximumKeys | ) | [virtual] |
Returns a keylist.
maximumKeys | maximum number of keys in new keylist |
00302 { 00303 if (maximumKeys > keyList.size()) { 00304 maximumKeys = keyList.size(); 00305 } 00306 // copy keylist to temporary keylist 00307 KeyList tmpKeyList; 00308 tmpKeyList.clear(); 00309 00310 for (uint i=0; i < keyList.size(); i++) { 00311 tmpKeyList.push_back(keyList[i]); 00312 } 00313 00314 KeyList* returnList = new KeyList; 00315 00316 for (uint i=0; i < ((float)maximumKeys * keyProbability); i++) { 00317 uint index = intuniform(0, tmpKeyList.size()-1); 00318 00319 returnList->push_back(tmpKeyList[index]); 00320 tmpKeyList.erase(tmpKeyList.begin()+index); 00321 } 00322 00323 return returnList; 00324 }
BootstrapOracle::DataMap * BootstrapOracle::getDataMap | ( | ) | [virtual] |
const OverlayKey & BootstrapOracle::getRandomKeyListItem | ( | ) | const [virtual] |
void BootstrapOracle::setOverlayReadyIcon | ( | const TransportAddress & | address, | |
bool | ready | |||
) | [virtual] |
Colors module-icon blue (ready), green (ready, malicious) or red (not ready).
address | TransportAddress of the specified node | |
ready | state to visualize |
00414 { 00415 if (ev.isGUI()) { 00416 const char* color; 00417 00418 if (ready) { 00419 // change color if node is malicious 00420 color = isMalicious(address) ? "green" : ""; 00421 } else { 00422 color = "red"; 00423 } 00424 00425 PeerInfo* info = getPeerInfo(address); 00426 00427 if(info != NULL) { 00428 simulation.module(info->getModuleID()) 00429 ->displayString().setTagArg("i2", 1, color); 00430 } 00431 } 00432 }
PeerInfo * BootstrapOracle::getPeerInfo | ( | const TransportAddress & | peer | ) | [virtual] |
Searches the peerSet for the specified node.
peer | TransportAddress of the specified node |
00332 { 00333 PeerHashMap::iterator it = peerSet.find(peer.ip); 00334 00335 if (it == peerSet.end()) 00336 return NULL; 00337 else 00338 return it->second.info; 00339 }
void BootstrapOracle::setMalicious | ( | const TransportAddress & | address, | |
bool | malicious | |||
) | [virtual] |
Set a node to be malicious.
address | TransportAddress of the node | |
malicious | state to set |
00381 { 00382 PeerInfo* peer = getPeerInfo(address); 00383 00384 if(peer != NULL) { 00385 if(malicious && !peer->isMalicious()) { 00386 maliciousNodes++; 00387 if (peer->isBootstrapped()) { 00388 bootstrappedMaliciousNodes++; 00389 } 00390 } 00391 00392 if (!malicious && peer->isMalicious()) { 00393 maliciousNodes--; 00394 if (peer->isBootstrapped()) { 00395 bootstrappedMaliciousNodes--; 00396 } 00397 } 00398 peer->setMalicious(malicious); 00399 } 00400 }
bool BootstrapOracle::isMalicious | ( | const TransportAddress & | address | ) | [virtual] |
Check if a node is malicious.
address | TransportAddress of the node |
00403 { 00404 PeerInfo* peer = getPeerInfo(address); 00405 00406 if(peer != NULL) 00407 return peer->isMalicious(); 00408 00409 return false; 00410 }
PeerInfo * BootstrapOracle::getRandomPeerInfo | ( | uint32_t | nodeType = 0 , |
|
bool | bootstrapNeeded = false | |||
) | [virtual] |
Selects a random node from the peerSet.
nodeType | If != 0, return a node of that type | |
bootstrapNeeded | does the node need to be bootstrapped? |
00352 { 00353 // return random TransportAddress in O(log n) 00354 PeerHashMap::iterator it; 00355 bootstrapEntry tempEntry = {NULL, NULL}; 00356 00357 IPvXAddress randomAddr(intuniform(min_ip, max_ip)); 00358 00359 it = peerSet.find(randomAddr); 00360 if (it == peerSet.end()) { 00361 it = peerSet.insert(std::make_pair(randomAddr,tempEntry)).first; 00362 peerSet.erase(it++); 00363 } 00364 00365 if (it == peerSet.end()) 00366 it = peerSet.begin(); 00367 00368 // if nodeType != 0, search for next node with the given type 00369 if (nodeType) { 00370 while((nodeType && (it->second.info->getTypeID() != nodeType)) 00371 || (bootstrappedNeeded && !it->second.info->isBootstrapped())) { 00372 ++it; 00373 if (it == peerSet.end()) it = peerSet.begin(); 00374 } 00375 } 00376 00377 return it->second.info; 00378 }
PeerInfo * BootstrapOracle::getPeerInfo | ( | const IPvXAddress & | ip | ) | [virtual] |
Searches the peerSet for the specified node.
ip | IPvXAddress of the specified node |
00342 { 00343 PeerHashMap::iterator it = peerSet.find(ip); 00344 00345 if (it == peerSet.end()) 00346 return NULL; 00347 else 00348 return it->second.info; 00349 }
bool BootstrapOracle::areNodeTypesConnected | ( | uint32_t | a, | |
uint32_t | b | |||
) |
00435 { 00436 if ((a > MAX_NODETYPES) || (b > MAX_NODETYPES)) 00437 throw new cException("BootstrapOracle::areNodeTypesConnected(): nodeType " 00438 "bigger then MAX_NODETYPES"); 00439 00440 return connectionMatrix[a][b]; 00441 }
void BootstrapOracle::connectNodeTypes | ( | uint32_t | a, | |
uint32_t | b | |||
) |
00444 { 00445 if ((a > MAX_NODETYPES) || (b > MAX_NODETYPES)) 00446 throw new cException("BootstrapOracle::connectNodeTypes(): nodeType " 00447 "bigger then MAX_NODETYPES"); 00448 00449 connectionMatrix[a][b]=true; 00450 00451 EV << "[BootstrapOracle::connectNodeTypes()]\n" 00452 << " Connecting " << a << "->" << b 00453 << endl; 00454 00455 }
void BootstrapOracle::disconnectNodeTypes | ( | uint32_t | a, | |
uint32_t | b | |||
) |
00458 { 00459 if ((a > MAX_NODETYPES) || (b > MAX_NODETYPES)) 00460 throw new cException("BootstrapOracle::disconnectNodeTypes(): nodeType " 00461 "bigger then MAX_NODETYPES"); 00462 00463 connectionMatrix[a][b]=false; 00464 00465 EV << "[BootstrapOracle::disconnectNodeTypes()]\n" 00466 << " Disconnecting " << a << "->" << b 00467 << endl; 00468 00469 }
void BootstrapOracle::mergeBootstrapNodes | ( | int | toPartition, | |
int | fromPartition, | |||
int | numNodes | |||
) |
00473 { 00474 00475 #if 0 00476 BootstrapList* bootstrapList = 00477 check_and_cast<BootstrapList*>(simulation.module( 00478 getRandomPeerInfo(toPartition, false)->getModuleID())-> 00479 submodule("bootstrapList")); 00480 #endif 00481 00482 BaseOverlay *overlay = check_and_cast<BaseOverlay*>(simulation.module( 00483 getRandomPeerInfo(toPartition, false)->getModuleID()) 00484 ->submodule("overlay")-> 00485 gate("from_app")->destinationGate()->ownerModule()); 00486 00487 overlay->insertBootstrapNode(getBootstrapNode()); 00488 00489 }
void BootstrapOracle::initialize | ( | ) | [protected, virtual] |
Init member function of module.
00058 { 00059 maxNumberOfKeys = par("maxNumberOfKeys"); 00060 keyProbability = par("keyProbability"); 00061 WATCH_HASH_MAP(peerSet); 00062 WATCH_MAP(dataMap); 00063 WATCH_VECTOR(keyList); 00064 WATCH(bootstrappedPeerSize); 00065 WATCH(bootstrappedMaliciousNodes); 00066 WATCH(maliciousNodes); 00067 createKeyList(maxNumberOfKeys); 00068 bootstrappedPeerSize = 0; 00069 bootstrappedMaliciousNodes = 0; 00070 maliciousNodes = 0; 00071 00072 if (par("maliciousNodeChange")) { 00073 if ((double) par("maliciousNodeProbability") > 0) 00074 error("maliciousNodeProbability and maliciousNodeChange are not supported concurrently"); 00075 00076 cMessage* msg = new cMessage("maliciousNodeChange"); 00077 scheduleAt(simulation.simTime() + (int) par("maliciousNodeChangeStartTime"), msg); 00078 maliciousNodesVector.setName("MaliciousNodeRate"); 00079 maliciousNodesVector.record(0); 00080 maliciousNodeRatio = 0; 00081 } 00082 00083 min_ip =0xFFFFFFFF; 00084 max_ip =0x00000000; 00085 00086 for (int i=0; i<MAX_NODETYPES; i++) { 00087 for (int j=0; j<MAX_NODETYPES; j++) { 00088 connectionMatrix[i][j] = true; 00089 } 00090 } 00091 00092 globalStatistics = GlobalStatisticsAccess().get(); 00093 00094 cMessage* timer = new cMessage("oracleTimer"); 00095 00096 scheduleAt(simulation.simTime(), timer); 00097 }
void BootstrapOracle::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
HandleMessage member function of module.
msg | messag to handle |
00100 { 00101 if (msg->isName("maliciousNodeChange")) { 00102 double newRatio = maliciousNodeRatio + (double) par("maliciousNodeChangeRate"); // ratio to obtain 00103 if (maliciousNodeRatio < (double) par("maliciousNodeChangeStartValue")) 00104 newRatio = (double) par("maliciousNodeChangeStartValue"); 00105 00106 if (newRatio < (double) par("maliciousNodeChangeStopValue")) // schedule next event 00107 scheduleAt(simulation.simTime() + (int) par("maliciousNodeChangeInterval"), msg); 00108 00109 int nodesNeeded = (int) (((double) par("maliciousNodeChangeRate")) * peerSet.size()); 00110 00111 EV << "[BootstrapOracle::handleMessage()]\n" 00112 << " Changing " << nodesNeeded << " nodes to be malicious" 00113 << endl; 00114 00115 for (int i = 0; i < nodesNeeded; i++) { 00116 // search a node that is not yet malicious 00117 NodeHandle node; 00118 do node = getRandomNode(false); 00119 while (isMalicious(node)); 00120 00121 setMalicious(node, true); 00122 } 00123 00124 maliciousNodesVector.record(newRatio); 00125 maliciousNodeRatio = newRatio; 00126 00127 return; 00128 } 00129 00130 else if (msg->isName("oracleTimer")) { 00131 RECORD_STATS(globalStatistics->recordOutVector( 00132 "BootstrapOracle: Number of nodes", peerSet.size())); 00133 scheduleAt(simulation.simTime() + 10, msg); 00134 } else { 00135 opp_error("BootstrapOracle::handleMessage: Unknown message type!"); 00136 } 00137 }
void BootstrapOracle::createKeyList | ( | uint | size | ) | [protected, virtual] |
Member function to create keylist.
size | size of new keylist |
00291 { 00292 for (uint i = 0; i < size; i++) 00293 keyList.push_back(OverlayKey::random()); 00294 }
KeyList BootstrapOracle::keyList [protected] |
the keylist
DataMap BootstrapOracle::dataMap [protected] |
the datamap
uint BootstrapOracle::bootstrappedPeerSize [protected] |
number of bootstrapped peers in the peer set
uint BootstrapOracle::bootstrappedMaliciousNodes [protected] |
number of bootstrapped malicious nodes in the peer set
uint BootstrapOracle::maliciousNodes [protected] |
number of malicious nodes in the peer set
double BootstrapOracle::maliciousNodeRatio [protected] |
ratio of current malicious nodes when changing the ratio dynamically
cOutVector BootstrapOracle::maliciousNodesVector [protected] |
vector that records the cange of malicious node rate
PeerHashMap BootstrapOracle::peerSet [protected] |
Set of nodes participating in the overlay.
uint BootstrapOracle::maxNumberOfKeys [protected] |
parameter used by createKeyList()
double BootstrapOracle::keyProbability [protected] |
probability of keys to be owned by nodes
uint32 BootstrapOracle::min_ip [private] |
uint32 BootstrapOracle::max_ip [private] |
used for random node choosing
pointer to GlobalStatistics module in this node
bool BootstrapOracle::connectionMatrix[MAX_NODETYPES][MAX_NODETYPES] [private] |
matrix specifices with node types (partitions) can communication