Sets up a SimpleNetwork. More...
#include <SimpleUnderlayConfigurator.h>
Public Member Functions | |
~SimpleUnderlayConfigurator () | |
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. | |
uint32_t | getFieldSize () |
uint32_t | getFieldDimension () |
uint32_t | 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. | |
uint32_t | 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 | |
uint32_t | sendQueueLength |
send queue length of overlay terminals | |
uint32_t | fieldSize |
int | dimensions |
bool | fixedNodePositions |
bool | useIPv6 |
bool | useXmlCoords |
const char * | nodeCoordinateSource |
uint32_t | maxCoordinate |
std::vector< std::pair < NodeRecord *, bool > > | nodeRecordPool |
int | numCreated |
number of overall created overlay terminals | |
int | numKilled |
number of overall killed overlay terminals |
Sets up a SimpleNetwork.
Adds overlay nodes to the network in init phase and adds/removes/migrates overlay nodes after init phase.
Definition at line 43 of file SimpleUnderlayConfigurator.h.
SimpleUnderlayConfigurator::~SimpleUnderlayConfigurator | ( | ) |
Definition at line 52 of file SimpleUnderlayConfigurator.cc.
{ for (uint32_t i = 0; i < nodeRecordPool.size(); ++i) { //std::cout << (nodeRecordPool[i].second ? "+" : "_"); delete nodeRecordPool[i].first; } nodeRecordPool.clear(); }
TransportAddress * SimpleUnderlayConfigurator::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.
Definition at line 111 of file SimpleUnderlayConfigurator.cc.
{ Enter_Method_Silent(); // derive overlay node from ned cModuleType* moduleType = cModuleType::get(type.terminalType.c_str()); std::string nameStr = "overlayTerminal"; if (churnGenerator.size() > 1) { nameStr += "-" + convertToString<int32_t>(type.typeID); } cModule* node = moduleType->create(nameStr.c_str(), getParentModule(), numCreated + 1, numCreated); std::string displayString; if ((type.typeID > 0) && (type.typeID <= NUM_COLORS)) { ((displayString += "i=device/wifilaptop_l,") += colorNames[type.typeID - 1]) += ",40;i2=block/circle_s"; } else { displayString = "i=device/wifilaptop_l;i2=block/circle_s"; } node->finalizeParameters(); node->setDisplayString(displayString.c_str()); node->buildInside(); node->scheduleStart(simTime()); for (int i = 0; i < MAX_STAGE_UNDERLAY + 1; i++) { node->callInitialize(i); } IPvXAddress addr; if (useIPv6) { addr = IPv6Address(0, nextFreeAddress++, 0, 0); } else { addr = IPAddress(nextFreeAddress++); } int chanIndex = intuniform(0, type.channelTypesRx.size() - 1); cChannelType* rxChan = cChannelType::find(type.channelTypesRx[chanIndex].c_str()); cChannelType* txChan = cChannelType::find(type.channelTypesTx[chanIndex].c_str()); if (!txChan || !rxChan) opp_error("Could not find Channel Type. Most likely parameter " "channelTypesRx or channelTypes does not match the channels defined in " "channels.ned"); SimpleNodeEntry* entry; if (!useXmlCoords) { entry = new SimpleNodeEntry(node, rxChan, txChan, sendQueueLength, fieldSize); } else { // get random unused node uint32_t volunteer = intuniform(0, nodeRecordPool.size() - 1); uint32_t temp = volunteer; while (nodeRecordPool[volunteer].second == false) { ++volunteer; if (volunteer >= nodeRecordPool.size()) volunteer = 0; // stop with errormessage if no more unused nodes available if (temp == volunteer) throw cRuntimeError("No unused coordinates left -> " "cannot create any more nodes. " "Provide %s-file with more nodes!\n", nodeCoordinateSource); } entry = new SimpleNodeEntry(node, rxChan, txChan, sendQueueLength, nodeRecordPool[volunteer].first, volunteer); // insert IP-address into noderecord used // nodeRecordPool[volunteer].first->ip = addr; nodeRecordPool[volunteer].second = false; } SimpleUDP* simpleUdp = check_and_cast<SimpleUDP*> (node->getSubmodule("udp")); simpleUdp->setNodeEntry(entry); SimpleTCP* simpleTcp = dynamic_cast<SimpleTCP*> (node->getSubmodule("tcp", 0)); if (simpleTcp) { simpleTcp->setNodeEntry(entry); } // Add pseudo-Interface to node's interfaceTable if (useIPv6) { IPv6InterfaceData* ifdata = new IPv6InterfaceData; ifdata->assignAddress(addr.get6(),false, 0, 0); IPv6InterfaceData::AdvPrefix prefix = {addr.get6(), 64}; ifdata->addAdvPrefix(prefix); InterfaceEntry* e = new InterfaceEntry; e->setName("dummy interface"); e->setIPv6Data(ifdata); IPAddressResolver().interfaceTableOf(node)->addInterface(e, NULL); } else { IPv4InterfaceData* ifdata = new IPv4InterfaceData; ifdata->setIPAddress(addr.get4()); ifdata->setNetmask(IPAddress("255.255.255.255")); InterfaceEntry* e = new InterfaceEntry; e->setName("dummy interface"); e->setIPv4Data(ifdata); IPAddressResolver().interfaceTableOf(node)->addInterface(e, NULL); } // create meta information SimpleInfo* info = new SimpleInfo(type.typeID, node->getId(), type.context); info->setEntry(entry); //add node to bootstrap oracle globalNodeList->addPeer(addr, info); // if the node was not created during startup we have to // finish the initialization process manually if (!initialize) { for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) { node->callInitialize(i); } } //show ip... //TODO: migrate if (fixedNodePositions && ev.isGUI()) { node->getDisplayString().insertTag("p"); node->getDisplayString().setTagArg("p", 0, (long int)(entry->getX() * 5)); node->getDisplayString().setTagArg("p", 1, (long int)(entry->getY() * 5)); node->getDisplayString().insertTag("t", 0); node->getDisplayString().setTagArg("t", 0, addr.str().c_str()); node->getDisplayString().setTagArg("t", 1, "l"); } overlayTerminalCount++; numCreated++; churnGenerator[type.typeID]->terminalCount++; TransportAddress *address = new TransportAddress(addr); // update display setDisplayString(); return address; }
void SimpleUnderlayConfigurator::finishUnderlay | ( | ) | [protected, virtual] |
Saves statistics, prints simulation time.
Reimplemented from UnderlayConfigurator.
Definition at line 515 of file SimpleUnderlayConfigurator.cc.
{ // statistics recordScalar("Terminals added", numCreated); recordScalar("Terminals removed", numKilled); if (!isInInitPhase()) { struct timeval now, diff; gettimeofday(&now, NULL); timersub(&now, &initFinishedTime, &diff); printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec); } }
uint32_t SimpleUnderlayConfigurator::getFieldDimension | ( | ) | [inline] |
Definition at line 73 of file SimpleUnderlayConfigurator.h.
{ return dimensions; };
uint32_t SimpleUnderlayConfigurator::getFieldSize | ( | ) | [inline] |
Definition at line 72 of file SimpleUnderlayConfigurator.h.
{ return fieldSize; };
uint32_t SimpleUnderlayConfigurator::getSendQueueLenghth | ( | ) | [inline] |
Definition at line 74 of file SimpleUnderlayConfigurator.h.
{ return sendQueueLength; };
void SimpleUnderlayConfigurator::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
Reimplemented from UnderlayConfigurator.
Definition at line 467 of file SimpleUnderlayConfigurator.cc.
{ Enter_Method_Silent(); // get next scheduled node and remove it from the kill list IPvXAddress addr = killList.back(); killList.pop_back(); SimpleNodeEntry* entry = NULL; SimpleInfo* info = dynamic_cast<SimpleInfo*> (globalNodeList->getPeerInfo(addr)); if (info != NULL) { entry = info->getEntry(); } else { throw cRuntimeError("SimpleUnderlayConfigurator: Trying to kill " "node with unknown TransportAddress!"); } cGate* gate = entry->getUdpIPv4Gate(); cModule* node = gate->getOwnerModule()->getParentModule(); if (useXmlCoords) { nodeRecordPool[entry->getRecordIndex()].second = true; } scheduledID.erase(node->getId()); globalNodeList->killPeer(addr); InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)-> getInterfaceByName("dummy interface"); delete ie->ipv4Data(); node->callFinish(); node->deleteModule(); delete msg; }
void SimpleUnderlayConfigurator::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.
Definition at line 61 of file SimpleUnderlayConfigurator.cc.
{ if (stage != MAX_STAGE_UNDERLAY) return; // fetch some parameters fixedNodePositions = par("fixedNodePositions"); useIPv6 = par("useIPv6Addresses"); // set maximum coordinates and send queue length fieldSize = par("fieldSize"); sendQueueLength = par("sendQueueLength"); // get parameter of sourcefile's name nodeCoordinateSource = par("nodeCoordinateSource"); if (std::string(nodeCoordinateSource) != "") { // check if exists and process xml-file containing coordinates std::ifstream check_for_xml_file(nodeCoordinateSource); if (check_for_xml_file) { useXmlCoords = 1; EV<< "[SimpleNetConfigurator::initializeUnderlay()]\n" << " Using '" << nodeCoordinateSource << "' as coordinate source file" << endl; maxCoordinate = parseCoordFile(nodeCoordinateSource); } else { throw cRuntimeError("Coordinate source file not found!"); } check_for_xml_file.close(); } else { useXmlCoords = 0; dimensions = 2; //TODO do we need this variable? NodeRecord::setDim(dimensions); EV << "[SimpleNetConfigurator::initializeUnderlay()]\n" << " Using conventional (random) coordinates for placing nodes!\n" << " (no XML coordinate source file was specified)" << endl; } // FIXME get address from parameter nextFreeAddress = 0x1000001; // count the overlay clients overlayTerminalCount = 0; numCreated = 0; numKilled = 0; }
void SimpleUnderlayConfigurator::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.
Definition at line 379 of file SimpleUnderlayConfigurator.cc.
{ Enter_Method_Silent(); SimpleNodeEntry* entry = NULL; if (addr != NULL) { SimpleInfo* info = dynamic_cast<SimpleInfo*> (globalNodeList->getPeerInfo(*addr)); if (info != NULL) { entry = info->getEntry(); } else { opp_error("SimpleNetConfigurator: Trying to migrate node with " "nonexistant TransportAddress!"); } } else { SimpleInfo* info = dynamic_cast<SimpleInfo*> ( globalNodeList-> getRandomPeerInfo(type.typeID)); entry = info->getEntry(); } cGate* gate = entry->getUdpIPv4Gate(); cModule* node = gate->getOwnerModule()->getParentModule(); // do not migrate node that is already scheduled if (scheduledID.count(node->getId())) return; //std::cout << "migration @ " << tmp_ip << " --> " << address << std::endl; // FIXME use only IPv4? IPvXAddress address = IPAddress(nextFreeAddress++); IPvXAddress tmp_ip = IPAddressResolver().addressOf(node); SimpleNodeEntry* newentry; int chanIndex = intuniform(0, type.channelTypesRx.size() - 1); cChannelType* rxChan = cChannelType::find(type.channelTypesRx[chanIndex].c_str()); cChannelType* txChan = cChannelType::find(type.channelTypesTx[chanIndex].c_str()); if (!txChan || !rxChan) opp_error("Could not find Channel Type. Most likely parameter " "channelTypesRx or channelTypes does not match the channels defined in " "channels.ned"); if (useXmlCoords) { newentry = new SimpleNodeEntry(node, rxChan, txChan, sendQueueLength, entry->getNodeRecord(), entry->getRecordIndex()); //newentry->getNodeRecord()->ip = address; } else { newentry = new SimpleNodeEntry(node, rxChan, txChan, fieldSize, sendQueueLength); } node->bubble("I am migrating!"); //remove node from bootstrap oracle globalNodeList->killPeer(tmp_ip); SimpleUDP* simple = check_and_cast<SimpleUDP*> (gate->getOwnerModule()); simple->setNodeEntry(newentry); InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)-> getInterfaceByName("dummy interface"); delete ie->ipv4Data(); // Add pseudo-Interface to node's interfaceTable IPv4InterfaceData* ifdata = new IPv4InterfaceData; ifdata->setIPAddress(address.get4()); ifdata->setNetmask(IPAddress("255.255.255.255")); ie->setIPv4Data(ifdata); // create meta information SimpleInfo* newinfo = new SimpleInfo(type.typeID, node->getId(), type.context); newinfo->setEntry(newentry); //add node to bootstrap oracle globalNodeList->addPeer(address, newinfo); // inform the notification board about the migration NotificationBoard* nb = check_and_cast<NotificationBoard*> ( node->getSubmodule("notificationBoard")); nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED); }
uint32_t SimpleUnderlayConfigurator::parseCoordFile | ( | const char * | nodeCoordinateSource | ) | [protected] |
Definition at line 254 of file SimpleUnderlayConfigurator.cc.
Referenced by initializeUnderlay().
{ cXMLElement* rootElement = ev.getXMLDocument(nodeCoordinateSource); // get number of dimensions from attribute of xml rootelement dimensions = atoi(rootElement->getAttribute("dimensions")); NodeRecord::setDim(dimensions); EV << "[SimpleNetConfigurator::parseCoordFile()]\n" << " using " << dimensions << " dimensions: "; double max_coord = 0; for (cXMLElement *tmpElement = rootElement->getFirstChild(); tmpElement; tmpElement = tmpElement->getNextSibling()) { // get "ip" and "isRoot" from Attributes (not needed yet) /* const char* str_ip = tmpElement->getAttribute("ip"); int tmpIP = 0; if (str_ip) sscanf(str_ip, "%x", &tmpIP); bool tmpIsRoot = atoi(tmpElement->getAttribute("isroot")); */ // create tmpNode to be added to vector NodeRecord* tmpNode = new NodeRecord; // get coords from childEntries and fill tmpNodes Array int i = 0; for (cXMLElement *coord = tmpElement->getFirstChild(); coord; coord = coord->getNextSibling()) { tmpNode->coords[i] = atof(coord->getNodeValue()); double newMax = fabs(tmpNode->coords[i]); if (newMax > max_coord) { max_coord = newMax; } i++; } // add to vector nodeRecordPool.push_back(make_pair(tmpNode, true)); //if (nodeRecordPool.size() >= maxSize) break; //TODO use other xml lib } EV << nodeRecordPool.size() << " nodes added to vector \"nodeRecordPool\"." << endl; #if OMNETPP_VERSION>=0x0401 // free memory used for xml document ev.forgetXMLDocument(nodeCoordinateSource); malloc_trim(0); #endif return (uint32_t)ceil(max_coord); }
void SimpleUnderlayConfigurator::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.
Definition at line 312 of file SimpleUnderlayConfigurator.cc.
{ Enter_Method_Silent(); SimpleNodeEntry* entry = NULL; SimpleInfo* info; if (addr == NULL) { addr = globalNodeList->getRandomAliveNode(type.typeID); if (addr == NULL) { // all nodes are already prekilled std::cout << "all nodes are already prekilled" << std::endl; return; } } info = dynamic_cast<SimpleInfo*> (globalNodeList->getPeerInfo(*addr)); if (info != NULL) { entry = info->getEntry(); globalNodeList->setPreKilled(*addr); } else { opp_error("SimpleNetConfigurator: Trying to pre kill node " "with nonexistant TransportAddress!"); } uint32_t effectiveType = info->getTypeID(); cGate* gate = entry->getUdpIPv4Gate(); cModule* node = gate->getOwnerModule()->getParentModule(); if (scheduledID.count(node->getId())) { std::cout << "SchedID" << std::endl; return; } // remove node from bootstrap oracle globalNodeList->removePeer(IPAddressResolver().addressOf(node)); // put node into the kill list and schedule a message for final removal // of the node killList.push_front(IPAddressResolver().addressOf(node)); scheduledID.insert(node->getId()); overlayTerminalCount--; numKilled++; churnGenerator[effectiveType]->terminalCount--; // update display setDisplayString(); // inform the notification board about the removal NotificationBoard* nb = check_and_cast<NotificationBoard*> ( node-> getSubmodule("notificationBoard")); nb->fireChangeNotification(NF_OVERLAY_NODE_LEAVE); double random = uniform(0, 1); if (random < gracefulLeaveProbability) { nb->fireChangeNotification(NF_OVERLAY_NODE_GRACEFUL_LEAVE); } cMessage* msg = new cMessage(); scheduleAt(simTime() + gracefulLeaveDelay, msg); }
void SimpleUnderlayConfigurator::setDisplayString | ( | ) | [protected, virtual] |
Prints statistics.
Implements UnderlayConfigurator.
Definition at line 507 of file SimpleUnderlayConfigurator.cc.
Referenced by createNode(), and preKillNode().
{ // Updates the statistics display string. char buf[80]; sprintf(buf, "%i overlay terminals", overlayTerminalCount); getDisplayString().setTagArg("t", 0, buf); }
int SimpleUnderlayConfigurator::dimensions [protected] |
Definition at line 105 of file SimpleUnderlayConfigurator.h.
Referenced by getFieldDimension(), initializeUnderlay(), and parseCoordFile().
uint32_t SimpleUnderlayConfigurator::fieldSize [protected] |
Definition at line 104 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), getFieldSize(), initializeUnderlay(), and migrateNode().
bool SimpleUnderlayConfigurator::fixedNodePositions [protected] |
Definition at line 106 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), and initializeUnderlay().
std::deque<IPvXAddress> SimpleUnderlayConfigurator::killList [protected] |
stores nodes scheduled to be killed
Definition at line 100 of file SimpleUnderlayConfigurator.h.
Referenced by handleTimerEvent(), and preKillNode().
uint32_t SimpleUnderlayConfigurator::maxCoordinate [protected] |
Definition at line 111 of file SimpleUnderlayConfigurator.h.
Referenced by initializeUnderlay().
uint32 SimpleUnderlayConfigurator::nextFreeAddress [protected] |
adress of the node that will be created next
Definition at line 99 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), initializeUnderlay(), and migrateNode().
const char* SimpleUnderlayConfigurator::nodeCoordinateSource [protected] |
Definition at line 110 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), and initializeUnderlay().
std::vector<std::pair<NodeRecord*, bool> > SimpleUnderlayConfigurator::nodeRecordPool [protected] |
Definition at line 113 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), handleTimerEvent(), parseCoordFile(), and ~SimpleUnderlayConfigurator().
int SimpleUnderlayConfigurator::numCreated [protected] |
number of overall created overlay terminals
Definition at line 116 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), finishUnderlay(), and initializeUnderlay().
int SimpleUnderlayConfigurator::numKilled [protected] |
number of overall killed overlay terminals
Definition at line 117 of file SimpleUnderlayConfigurator.h.
Referenced by finishUnderlay(), initializeUnderlay(), and preKillNode().
std::set<int> SimpleUnderlayConfigurator::scheduledID [protected] |
stores nodeIds to prevent migration of prekilled nodes
Definition at line 101 of file SimpleUnderlayConfigurator.h.
Referenced by handleTimerEvent(), migrateNode(), and preKillNode().
uint32_t SimpleUnderlayConfigurator::sendQueueLength [protected] |
send queue length of overlay terminals
Definition at line 103 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), getSendQueueLenghth(), initializeUnderlay(), and migrateNode().
bool SimpleUnderlayConfigurator::useIPv6 [protected] |
Definition at line 107 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), and initializeUnderlay().
bool SimpleUnderlayConfigurator::useXmlCoords [protected] |
Definition at line 109 of file SimpleUnderlayConfigurator.h.
Referenced by createNode(), handleTimerEvent(), initializeUnderlay(), and migrateNode().