#include <SimpleNetConfigurator.h>
Adds overlay nodes to the network in init phase and adds/removes/migrates overlay nodes after init phase.
Public Member Functions | |
~SimpleNetConfigurator () | |
virtual TransportAddress * | createNode (NodeType type, bool initialize=false) |
Creates an overlay node. | |
virtual void | preKillNode (NodeType type, TransportAddress *addr=NULL) |
Notifies and schedules overlay nodes for removal. | |
virtual void | migrateNode (NodeType type, TransportAddress *addr=NULL) |
Migrates overlay nodes from one access net to another. | |
uint | getFieldSize () |
uint | getFieldDimension () |
uint | getSendQueueLenghth () |
Protected Member Functions | |
void | initializeUnderlay (int stage) |
Enables access to the globalHashMap, sets some parameters and adds the initial number of nodes to the network. | |
void | handleTimerEvent (cMessage *msg) |
void | finishUnderlay () |
Saves statistics, prints simulation time. | |
void | setDisplayString () |
Prints statistics. | |
uint | parseCoordFile (const char *nodeCoordinateSource) |
Protected Attributes | |
uint32 | nextFreeAddress |
adress of the node that will be created next | |
std::deque< IPvXAddress > | killList |
stores nodes scheduled to be killed | |
std::set< int > | scheduledID |
stores nodeIds to prevent migration of prekilled nodes | |
uint | sendQueueLength |
send queue length of overlay terminals | |
uint | fieldSize |
int | dimensions |
bool | fixedNodePositions |
bool | useXmlCoords |
const char * | nodeCoordinateSource |
uint | maxCoordinate |
std::vector< std::pair < NodeRecord *, bool > > | nodeRecordPool |
int | numCreated |
number of overall created overlay terminals | |
int | numKilled |
number of overall killed overlay terminals |
SimpleNetConfigurator::~SimpleNetConfigurator | ( | ) |
00049 { 00050 for (uint i = 0; i < nodeRecordPool.size(); ++i) { 00051 //std::cout << (nodeRecordPool[i].second ? "+" : "_"); 00052 delete nodeRecordPool[i].first; 00053 } 00054 nodeRecordPool.clear(); 00055 }
TransportAddress * SimpleNetConfigurator::createNode | ( | NodeType | type, | |
bool | initialize = false | |||
) | [virtual] |
Creates an overlay node.
type | NodeType of the node to create | |
initialize | are we in init phase? |
Implements UnderlayConfigurator.
00103 { 00104 Enter_Method_Silent(); 00105 // derive overlay node from ned 00106 cModuleType* moduleType = findModuleType(type.terminalType.c_str()); 00107 00108 cModule* node = moduleType->create("overlayTerminal", parentModule()); 00109 00110 node->par("overlayType").setStringValue(type.overlayType.c_str()); 00111 node->par("tier1Type").setStringValue(type.tier1Type.c_str()); 00112 node->par("tier2Type").setStringValue(type.tier2Type.c_str()); 00113 node->par("tier3Type").setStringValue(type.tier3Type.c_str()); 00114 00115 std::string displayString; 00116 00117 if ((type.typeID > 1) && (type.typeID <= (NUM_COLORS + 1))) { 00118 ((displayString += "i=device/wifilaptop_l,") += colorNames[type.typeID 00119 - 2]) += ",40;i2=block/circle_s"; 00120 } else { 00121 displayString = "i=device/wifilaptop_l;i2=block/circle_s"; 00122 } 00123 00124 node->setDisplayString(displayString.c_str()); 00125 node->buildInside(); 00126 node->scheduleStart(simulation.simTime()); 00127 00128 for (int i = 0; i < MAX_STAGE_UNDERLAY + 1; i++) { 00129 node->callInitialize(i); 00130 } 00131 00132 // FIXME use only IPv4? 00133 IPvXAddress addr = IPAddress(nextFreeAddress++); 00134 00135 cChannelType* chan = findChannelType(type.channelTypes[intuniform(0, 00136 type.channelTypes.size() - 1)].c_str()); 00137 00138 if (!chan) 00139 opp_error("Could not find Channel Type. Most likely parameter " 00140 "channelTypes does not match the channels defined in " 00141 "channels.ned"); 00142 SimpleNodeEntry* entry; 00143 00144 if (!useXmlCoords) { 00145 entry = new SimpleNodeEntry(node, chan, fieldSize, sendQueueLength); 00146 } else { 00147 //get random unused node 00148 uint volunteer = intuniform(0, nodeRecordPool.size() - 1); 00149 uint temp = volunteer; 00150 while (nodeRecordPool[volunteer].second == false) { 00151 //std::cout << "."; 00152 ++volunteer; 00153 if (volunteer >= nodeRecordPool.size()) 00154 volunteer = 0; 00155 // stop with errormessage if no more unused nodes available 00156 if (temp == volunteer) 00157 throw new cRuntimeError("No unused coordinates left -> " 00158 "cannot create any more nodes. " 00159 "Provide %s-file with more nodes!\n", nodeCoordinateSource); 00160 } 00161 00162 entry 00163 = new SimpleNodeEntry(node, chan, sendQueueLength, nodeRecordPool[volunteer].first, volunteer); 00164 00165 //insert IP-address into noderecord used 00166 nodeRecordPool[volunteer].first->ip = addr; 00167 nodeRecordPool[volunteer].second = false; 00168 } 00169 00170 node->gate("out", 0)->setChannel(chan->create("outChan")); 00171 00172 SimpleUDP* simple = check_and_cast<SimpleUDP*> (node->submodule("udp")); 00173 simple->setNodeEntry(entry); 00174 00175 // Add pseudo-Interface to node's interfaceTable 00176 IPv4InterfaceData* ifdata = new IPv4InterfaceData; 00177 ifdata->setInetAddress(addr.get4()); 00178 ifdata->setNetmask(IPAddress("255.255.255.255")); 00179 InterfaceEntry* e = new InterfaceEntry; 00180 e->setName("dummy interface"); 00181 e->setIPv4Data(ifdata); 00182 00183 IPAddressResolver().interfaceTableOf(node)->addInterface(e, NULL); 00184 00185 // create meta information 00186 SimpleInfo* info = new SimpleInfo(type.typeID, node->id()); 00187 info->setEntry(entry); 00188 00189 // append index to module name 00190 char buf[80]; 00191 sprintf(buf, "overlayTerminal[%i]", numCreated); 00192 node->setName(buf); 00193 00194 //add node to bootstrap oracle 00195 bootstrapOracle->addPeer(addr, info); 00196 00197 // if the node was not created during startup we have to 00198 // finish the initialization process manually 00199 if (!initialize) { 00200 for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) { 00201 node->callInitialize(i); 00202 } 00203 } 00204 00205 //show ip... 00206 //TODO: migrate 00207 if (fixedNodePositions && ev.isGUI()) { 00208 node->displayString().insertTag("p"); 00209 node->displayString().setTagArg("p", 0, (long int) entry->getX()); 00210 node->displayString().setTagArg("p", 1, (long int) entry->getY()); 00211 node->displayString().insertTag("t", 0); 00212 node->displayString().setTagArg("t", 0, addr.str().c_str()); 00213 node->displayString().setTagArg("t", 1, "l"); 00214 } 00215 00216 overlayTerminalCount++; 00217 numCreated++; 00218 00219 churnGenerator[type.typeID - 1]->terminalCount++; 00220 00221 TransportAddress *address = new TransportAddress(addr); 00222 00223 // update display 00224 setDisplayString(); 00225 00226 return address; 00227 }
void SimpleNetConfigurator::preKillNode | ( | NodeType | type, | |
TransportAddress * | addr = NULL | |||
) | [virtual] |
Notifies and schedules overlay nodes for removal.
type | NodeType of the node to remove | |
addr | NULL for random node |
Implements UnderlayConfigurator.
00278 { 00279 Enter_Method_Silent(); 00280 00281 SimpleNodeEntry* entry = NULL; 00282 SimpleInfo* info; 00283 00284 if (addr == NULL) { 00285 addr = bootstrapOracle->getRandomAliveNode(type.typeID); 00286 00287 if (addr == NULL) { 00288 // all nodes are already prekilled 00289 std::cout << "all nodes are already prekilled" << std::endl; 00290 return; 00291 } 00292 } 00293 00294 info = dynamic_cast<SimpleInfo*> (bootstrapOracle->getPeerInfo(*addr)); 00295 00296 if (info != NULL) { 00297 entry = info->getEntry(); 00298 bootstrapOracle->setPreKilled(*addr); 00299 } else { 00300 opp_error("SimpleNetConfigurator: Trying to pre kill node " 00301 "with nonexistant TransportAddress!"); 00302 } 00303 00304 uint32_t effectiveType = info->getTypeID(); 00305 cGate* gate = entry->getGate(); 00306 00307 cModule* node = gate->ownerModule()->parentModule(); 00308 00309 if (scheduledID.count(node->id())) { 00310 std::cout << "SchedID" << std::endl; 00311 return; 00312 } 00313 00314 // remove node from bootstrap oracle 00315 bootstrapOracle->removePeer(IPAddressResolver().addressOf(node)); 00316 00317 // put node into the kill list and schedule a message for final removal 00318 // of the node 00319 killList.push_front(IPAddressResolver().addressOf(node)); 00320 scheduledID.insert(node->id()); 00321 00322 overlayTerminalCount--; 00323 numKilled++; 00324 00325 churnGenerator[effectiveType - 1]->terminalCount--; 00326 00327 // update display 00328 setDisplayString(); 00329 00330 // inform the notification board about the removal 00331 NotificationBoard* nb = check_and_cast<NotificationBoard*> ( 00332 node-> submodule("notificationBoard")); 00333 nb->fireChangeNotification(NF_OVERLAY_NODE_LEAVE); 00334 00335 double random = uniform(0, 1); 00336 if (random < gracefulLeaveProbability) { 00337 nb->fireChangeNotification(NF_OVERLAY_NODE_GRACEFUL_LEAVE); 00338 } 00339 00340 cMessage* msg = new cMessage(); 00341 scheduleAt(simulation.simTime() + gracefulLeaveDelay, msg); 00342 }
void SimpleNetConfigurator::migrateNode | ( | NodeType | type, | |
TransportAddress * | addr = NULL | |||
) | [virtual] |
Migrates overlay nodes from one access net to another.
type | NodeType of the node to migrate | |
addr | NULL for random node |
Implements UnderlayConfigurator.
00345 { 00346 Enter_Method_Silent(); 00347 00348 SimpleNodeEntry* entry = NULL; 00349 00350 if (addr != NULL) { 00351 SimpleInfo* info = 00352 dynamic_cast<SimpleInfo*> (bootstrapOracle->getPeerInfo(*addr)); 00353 if (info != NULL) { 00354 entry = info->getEntry(); 00355 } else { 00356 opp_error("SimpleNetConfigurator: Trying to migrate node with " 00357 "nonexistant TransportAddress!"); 00358 } 00359 } else { 00360 SimpleInfo* info = dynamic_cast<SimpleInfo*> ( 00361 bootstrapOracle-> getRandomPeerInfo(type.typeID)); 00362 entry = info->getEntry(); 00363 } 00364 00365 cGate* gate = entry->getGate(); 00366 cModule* node = gate->ownerModule()->parentModule(); 00367 00368 // do not migrate node that is already scheduled 00369 if (scheduledID.count(node->id())) 00370 return; 00371 00372 //std::cout << "migration @ " << tmp_ip << " --> " << address << std::endl; 00373 00374 // FIXME use only IPv4? 00375 IPvXAddress address = IPAddress(nextFreeAddress++); 00376 00377 IPvXAddress tmp_ip = IPAddressResolver().addressOf(node); 00378 SimpleNodeEntry* newentry; 00379 00380 if (useXmlCoords) { 00381 newentry = new SimpleNodeEntry(node, findChannelType( 00382 channelTypes[intuniform(0, channelTypes.size() - 1)].c_str()), 00383 sendQueueLength, entry->getNodeRecord(), entry->getRecordIndex()); 00384 00385 newentry->getNodeRecord()->ip = address; 00386 } else { 00387 newentry = new SimpleNodeEntry(node, findChannelType( 00388 channelTypes[intuniform(0, channelTypes.size() - 1)].c_str()), 00389 fieldSize, sendQueueLength); 00390 } 00391 00392 node->bubble("I am migrating!"); 00393 00394 //remove node from bootstrap oracle 00395 bootstrapOracle->killPeer(tmp_ip); 00396 00397 SimpleUDP* simple = check_and_cast<SimpleUDP*> (gate->ownerModule()); 00398 simple->setNodeEntry(newentry); 00399 00400 InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)-> 00401 interfaceByName("dummy interface"); 00402 delete ie->ipv4(); 00403 00404 // Add pseudo-Interface to node's interfaceTable 00405 IPv4InterfaceData* ifdata = new IPv4InterfaceData; 00406 ifdata->setInetAddress(address.get4()); 00407 ifdata->setNetmask(IPAddress("255.255.255.255")); 00408 ie->setIPv4Data(ifdata); 00409 00410 // create meta information 00411 SimpleInfo* newinfo = new SimpleInfo(type.typeID, node->id()); 00412 newinfo->setEntry(newentry); 00413 00414 //add node to bootstrap oracle 00415 bootstrapOracle->addPeer(address, newinfo); 00416 00417 // inform the notification board about the migration 00418 NotificationBoard* nb = check_and_cast<NotificationBoard*> ( 00419 node->submodule("notificationBoard")); 00420 nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED); 00421 }
uint SimpleNetConfigurator::getFieldSize | ( | ) | [inline] |
uint SimpleNetConfigurator::getFieldDimension | ( | ) | [inline] |
uint SimpleNetConfigurator::getSendQueueLenghth | ( | ) | [inline] |
void SimpleNetConfigurator::initializeUnderlay | ( | int | stage | ) | [protected, virtual] |
Enables access to the globalHashMap, sets some parameters and adds the initial number of nodes to the network.
stage | the phase of the initialisation |
Implements UnderlayConfigurator.
00058 { 00059 if (stage != MAX_STAGE_UNDERLAY) 00060 return; 00061 00062 // fetch some parameters 00063 fixedNodePositions = par("fixedNodePositions"); 00064 00065 // set maximum coordinates and send queue length 00066 fieldSize = par("fieldSize"); 00067 sendQueueLength = par("sendQueueLength"); 00068 00069 // get parameter of sourcefile's name 00070 nodeCoordinateSource = par("nodeCoordinateSource"); 00071 00072 // check if exists and process xml-file containing coordinates 00073 std::ifstream check_for_xml_file(nodeCoordinateSource); 00074 if (check_for_xml_file) { 00075 useXmlCoords = 1; 00076 00077 EV<< "[SimpleNetConfigurator::initializeUnderlay()]\n" 00078 << " Using '" << nodeCoordinateSource 00079 << "' as Coordinate-Sourcefile" << endl; 00080 00081 maxCoordinate = parseCoordFile(nodeCoordinateSource); 00082 } else { 00083 useXmlCoords = 0; 00084 dimensions = 2; 00085 EV << "[SimpleNetConfigurator::initializeUnderlay()]\n" 00086 << " Using conventional (random) coordinates for placing nodes!\n" 00087 << " (An XML-Sourcefile could not be opened)" << endl; 00088 } 00089 check_for_xml_file.close(); 00090 00091 // FIXME get address from parameter 00092 nextFreeAddress = 0x1000001; 00093 00094 // count the overlay clients 00095 overlayTerminalCount = 0; 00096 00097 numCreated = 0; 00098 numKilled = 0; 00099 }
void SimpleNetConfigurator::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
Reimplemented from UnderlayConfigurator.
00424 { 00425 Enter_Method_Silent(); 00426 00427 // get next scheduled node and remove it from the kill list 00428 IPvXAddress addr = killList.back(); 00429 killList.pop_back(); 00430 00431 SimpleNodeEntry* entry = NULL; 00432 00433 SimpleInfo* info = 00434 dynamic_cast<SimpleInfo*> (bootstrapOracle->getPeerInfo(addr)); 00435 00436 if (info != NULL) { 00437 entry = info->getEntry(); 00438 } else { 00439 opp_error("SimpleNetConfigurator: Trying to kill node with " 00440 "unknown TransportAddress!"); 00441 } 00442 00443 cGate* gate = entry->getGate(); 00444 cModule* node = gate->ownerModule()->parentModule(); 00445 00446 if (useXmlCoords) { 00447 nodeRecordPool[entry->getRecordIndex()].second = true; 00448 } 00449 00450 scheduledID.erase(node->id()); 00451 bootstrapOracle->killPeer(addr); 00452 00453 InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)-> 00454 interfaceByName("dummy interface"); 00455 delete ie->ipv4(); 00456 00457 node->callFinish(); 00458 node->deleteModule(); 00459 00460 delete msg; 00461 }
void SimpleNetConfigurator::finishUnderlay | ( | ) | [protected, virtual] |
Saves statistics, prints simulation time.
Reimplemented from UnderlayConfigurator.
00472 { 00473 // statistics 00474 recordScalar("Terminals added", numCreated); 00475 recordScalar("Terminals removed", numKilled); 00476 00477 if (!isInInitPhase()) { 00478 struct timeval now, diff; 00479 gettimeofday(&now, NULL); 00480 timersub(&now, &initFinishedTime, &diff); 00481 printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec); 00482 } 00483 }
void SimpleNetConfigurator::setDisplayString | ( | ) | [protected, virtual] |
Prints statistics.
Implements UnderlayConfigurator.
Referenced by createNode(), and preKillNode().
00464 { 00465 // Updates the statistics display string. 00466 char buf[80]; 00467 sprintf(buf, "%i overlay terminals", overlayTerminalCount); 00468 displayString().setTagArg("t", 0, buf); 00469 }
uint SimpleNetConfigurator::parseCoordFile | ( | const char * | nodeCoordinateSource | ) | [protected] |
Referenced by initializeUnderlay().
00230 { 00231 cXMLElement* rootElement = ev.getXMLDocument(nodeCoordinateSource); 00232 00233 // get number of dimensions from attribute of xml rootelement 00234 dimensions = atoi(rootElement->getAttribute("dimensions")); 00235 EV << "[SimpleNetConfigurator::parseCoordFile()]\n" 00236 << " using " << dimensions << " dimensions: "; 00237 00238 double max_coord = 0; 00239 00240 for (cXMLElement *tmpElement = rootElement->getFirstChild(); tmpElement; 00241 tmpElement = tmpElement->getNextSibling()) { 00242 00243 // get "ip" and "isRoot" from Attributes (not needed yet) 00244 /* 00245 const char* str_ip = tmpElement->getAttribute("ip"); 00246 int tmpIP = 0; 00247 if (str_ip) sscanf(str_ip, "%x", &tmpIP); 00248 bool tmpIsRoot = atoi(tmpElement->getAttribute("isroot")); 00249 */ 00250 00251 // create tmpNode to be added to vector 00252 NodeRecord* tmpNode = new NodeRecord(dimensions); 00253 00254 // get coords from childEntries and fill tmpNodes Array 00255 int i = 0; 00256 for (cXMLElement *coord = tmpElement->getFirstChild(); coord; 00257 coord = coord->getNextSibling()) { 00258 00259 tmpNode->coords[i] = atof(coord->getNodeValue()); 00260 00261 if (fabs(tmpNode->coords[i])> max_coord) { 00262 max_coord = fabs(tmpNode->coords[i]); 00263 } 00264 i++; 00265 } 00266 00267 // add to vector 00268 nodeRecordPool.push_back(make_pair(tmpNode, true)); 00269 } // now all nodes from xml-file are in vector unusedRootNodes 00270 00271 EV << nodeRecordPool.size() 00272 << " nodes added to vector \"nodeRecordPool\"." << endl; 00273 00274 return (uint)ceil(max_coord); 00275 }
uint32 SimpleNetConfigurator::nextFreeAddress [protected] |
adress of the node that will be created next
Referenced by createNode(), initializeUnderlay(), and migrateNode().
std::deque<IPvXAddress> SimpleNetConfigurator::killList [protected] |
std::set<int> SimpleNetConfigurator::scheduledID [protected] |
stores nodeIds to prevent migration of prekilled nodes
Referenced by handleTimerEvent(), migrateNode(), and preKillNode().
uint SimpleNetConfigurator::sendQueueLength [protected] |
send queue length of overlay terminals
Referenced by createNode(), getSendQueueLenghth(), initializeUnderlay(), and migrateNode().
uint SimpleNetConfigurator::fieldSize [protected] |
Referenced by createNode(), getFieldSize(), initializeUnderlay(), and migrateNode().
int SimpleNetConfigurator::dimensions [protected] |
Referenced by getFieldDimension(), initializeUnderlay(), and parseCoordFile().
bool SimpleNetConfigurator::fixedNodePositions [protected] |
Referenced by createNode(), and initializeUnderlay().
bool SimpleNetConfigurator::useXmlCoords [protected] |
Referenced by createNode(), handleTimerEvent(), initializeUnderlay(), and migrateNode().
const char* SimpleNetConfigurator::nodeCoordinateSource [protected] |
Referenced by createNode(), and initializeUnderlay().
uint SimpleNetConfigurator::maxCoordinate [protected] |
Referenced by initializeUnderlay().
std::vector<std::pair<NodeRecord*, bool> > SimpleNetConfigurator::nodeRecordPool [protected] |
Referenced by createNode(), handleTimerEvent(), parseCoordFile(), and ~SimpleNetConfigurator().
int SimpleNetConfigurator::numCreated [protected] |
number of overall created overlay terminals
Referenced by createNode(), finishUnderlay(), and initializeUnderlay().
int SimpleNetConfigurator::numKilled [protected] |
number of overall killed overlay terminals
Referenced by finishUnderlay(), initializeUnderlay(), and preKillNode().