BootstrapOracle Class Reference

#include <BootstrapOracle.h>

List of all members.


Detailed Description

Global modul that supports bootstrap process and key distribution.

Author:
Markus Mauch, Robert Palmer

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 KeyListgetKeyList (uint maximumKeys)
 Returns a keylist.
virtual DataMapgetDataMap ()
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 PeerInfogetPeerInfo (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 PeerInfogetRandomPeerInfo (uint32_t nodeType=0, bool bootstrapNeeded=false)
 Selects a random node from the peerSet.
virtual PeerInfogetPeerInfo (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
GlobalStatisticsglobalStatistics
 pointer to GlobalStatistics module in this node
bool connectionMatrix [MAX_NODETYPES][MAX_NODETYPES]
 matrix specifices with node types (partitions) can communication

Member Typedef Documentation

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.


Member Function Documentation

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.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
nodeType If != 0, return a node of that type
bootstrappedNeeded does the node need to be bootstrapped?
Returns:
NodeHandle of the node
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.

Returns:
NodeHandle of the node
00140 {
00141     return getRandomNode(0, true);
00142 }

void BootstrapOracle::registerPeer ( const TransportAddress peer  )  [virtual]

Bootstraps peers in the peer set.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
maximumKeys maximum number of keys in new keylist
Returns:
pointer to 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]

00297 {
00298     return &dataMap;
00299 }

const OverlayKey & BootstrapOracle::getRandomKeyListItem (  )  const [virtual]

Returns random key from list.

Returns:
the key
00327 {
00328     return keyList[intuniform(0,keyList.size()-1)];
00329 }

void BootstrapOracle::setOverlayReadyIcon ( const TransportAddress address,
bool  ready 
) [virtual]

Colors module-icon blue (ready), green (ready, malicious) or red (not ready).

Parameters:
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.

Parameters:
peer TransportAddress of the specified node
Returns:
PeerInfo of the node or NULL if node is not in peerSet
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.

Parameters:
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.

Parameters:
address TransportAddress of the node
Returns:
if the node is malicious
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.

Parameters:
nodeType If != 0, return a node of that type
bootstrapNeeded does the node need to be bootstrapped?
Returns:
The peerInfo of a random node
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.

Parameters:
ip IPvXAddress of the specified node
Returns:
PeerInfo of the node or NULL if node is not in peerSet
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.

Parameters:
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.

Parameters:
size size of new keylist
00291 {
00292     for (uint i = 0; i < size; i++)
00293         keyList.push_back(OverlayKey::random());
00294 }


Member Data Documentation

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

GlobalStatistics* BootstrapOracle::globalStatistics [private]

pointer to GlobalStatistics module in this node

bool BootstrapOracle::connectionMatrix[MAX_NODETYPES][MAX_NODETYPES] [private]

matrix specifices with node types (partitions) can communication


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