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