#include <IPv4UnderlayConfigurator.h>
Inheritance diagram for IPv4UnderlayConfigurator:
Public Member Functions | |
int | createRandomNode (bool initialize) |
Creates an overlay node and adds it to a randomly chosen access net. | |
void | killRandomNode () |
Removes randomly chosen overlay nodes from a randomly chosen access net. | |
void | migrateRandomNode () |
Migrates randomly chosen overlay nodes from on access net to another. | |
Protected Member Functions | |
void | initializeUnderlay (int stage) |
Init method for derived underlay configurators. | |
void | finish () |
Cleans up configurator. | |
void | setDisplayString () |
Updates the statistics display string. | |
Protected Attributes | |
std::vector< cModule * > | accessNode |
int | numCreated |
int | numKilled |
Private Attributes | |
int | accessRouterNum |
int | overlayAccessRouterNum |
int | overlayTerminalNum |
int IPv4UnderlayConfigurator::createRandomNode | ( | bool | initialize | ) | [virtual] |
Creates an overlay node and adds it to a randomly chosen access net.
initialize | creation during init phase? |
Implements UnderlayConfigurator.
00265 { 00266 // derive overlay node from ned 00267 cModuleType* moduleType = findModuleType("OverlayHost");//parentModule()->par("overlayTerminalType")); 00268 cModule* node = moduleType->create("overlayTerminal", parentModule()); 00269 00270 node->par("overlayType").setStringValue(parentModule()->par("overlayType")); 00271 node->par("tier2Type").setStringValue(parentModule()->par("tier1Type")); 00272 node->par("tier2Type").setStringValue(parentModule()->par("tier2Type")); 00273 node->par("tier3Type").setStringValue(parentModule()->par("tier3Type")); 00274 00275 00276 node->setGateSize("in", 1); 00277 node->setGateSize("out", 1); 00278 node->setDisplayString("i=device/wifilaptop_l;i2=block/circle_s"); 00279 node->buildInside(); 00280 node->scheduleStart(simulation.simTime()); 00281 00282 // add node to a randomly chosen access net 00283 AccessNet* accessNet = check_and_cast<AccessNet*> 00284 (accessNode[intuniform(0, accessNode.size() - 1)]->submodule("accessNet")); 00285 accessNet->addOverlayNode(node); 00286 00287 // append index to module name 00288 char buf[80]; 00289 sprintf(buf, "overlayTerminal[%i]", numCreated); 00290 node->setName(buf); 00291 00292 //add node to bootstrap oracle 00293 //TransportAddress* peer = new TransportAddress(IPAddressResolver().addressOf(node).get4()); 00294 PeerInfo* info = new PeerInfo(node->submodule("overlay")->id()); 00295 //bootstrapOracle->addPeer(peer, info); 00296 bootstrapOracle->addPeer(IPAddressResolver().addressOf(node).get4(), info); 00297 00298 // if the node was not created during startup we have to 00299 // finish the initialization process manually 00300 if ( !initialize) { 00301 for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) { 00302 node->callInitialize(i); 00303 } 00304 } 00305 00306 overlayTerminalCount++; 00307 numCreated++; 00308 00309 return node->id(); 00310 }
void IPv4UnderlayConfigurator::finish | ( | ) | [protected, virtual] |
Cleans up configurator.
Implements UnderlayConfigurator.
00385 { 00386 // statistics 00387 recordScalar("Terminals added", numCreated); 00388 recordScalar("Terminals removed", numKilled); 00389 00390 struct timeval now, diff; 00391 gettimeofday(&now, NULL); 00392 timersub(&now, &initFinishedTime, &diff); 00393 printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec); 00394 }
void IPv4UnderlayConfigurator::initializeUnderlay | ( | int | stage | ) | [protected, virtual] |
Init method for derived underlay configurators.
Implements UnderlayConfigurator.
00035 { 00036 //backbone configuration 00037 if(stage == MIN_STAGE_UNDERLAY) { 00038 // Find all router module types. 00039 cTopology topo("topo"); 00040 const char* typeNames[6]; 00041 typeNames[0] = "Router"; 00042 typeNames[1] = "OverlayRouter"; 00043 typeNames[2] = "AccessRouter"; 00044 typeNames[3] = "OverlayAccessRouter"; 00045 typeNames[4] = "TunOutRouter"; 00046 typeNames[5] = NULL; 00047 topo.extractByModuleType(typeNames); 00048 00049 // Assign IP addresses to all router modules. 00050 std::vector<uint32> nodeAddresses; 00051 nodeAddresses.resize(topo.nodes()); 00052 00053 // IP addresses for backbone 00054 // Take start IP from config file 00055 // FIXME: Make Netmask for Routers configurable! 00056 uint32 lowIPBoundary = IPAddress(par("startIP").stringValue()).getInt(); 00057 00058 // uint32 lowIPBoundary = uint32((1 << 24) + 1); 00059 int numIPNodes = 0; 00060 for (int i = 0; i < topo.nodes(); i++) { 00061 ++numIPNodes; 00062 00063 uint32 addr = lowIPBoundary + uint32(numIPNodes << 16); 00064 nodeAddresses[i] = addr; 00065 00066 // update ip display string 00067 if (ev.isGUI()) { 00068 const char* ip_disp = const_cast<char*>(IPAddress(addr).str().c_str()); 00069 topo.node(i)->module()->displayString().insertTag("t", 0); 00070 topo.node(i)->module()->displayString().setTagArg("t", 0, ip_disp); 00071 topo.node(i)->module()->displayString().setTagArg("t", 1, "l"); 00072 topo.node(i)->module()->displayString().setTagArg("t", 2, "red"); 00073 } 00074 00075 // find interface table and assign address to all (non-loopback) interfaces 00076 InterfaceTable* ift = IPAddressResolver().interfaceTableOf(topo.node(i)->module()); 00077 00078 for ( int k = 0; k < ift->numInterfaces(); k++ ) { 00079 InterfaceEntry* ie = ift->interfaceAt(k); 00080 if (!ie->isLoopback()) { 00081 ie->ipv4()->setInetAddress(IPAddress(addr)); 00082 // full address must match for local delivery 00083 ie->ipv4()->setNetmask(IPAddress::ALLONES_ADDRESS); 00084 } 00085 } 00086 } 00087 00088 // Fill in routing tables. 00089 for ( int i = 0; i < topo.nodes(); i++ ) { 00090 cTopology::Node* destNode = topo.node(i); 00091 uint32 destAddr = nodeAddresses[i]; 00092 00093 // calculate shortest paths from everywhere towards destNode 00094 topo.unweightedSingleShortestPathsTo(destNode); 00095 00096 // add overlayAccessRouters and overlayBackboneRouters 00097 // to the BootstrapOracle 00098 if ((strcmp(destNode->module()->name(), "overlayBackboneRouter") 00099 == 0 ) || 00100 (strcmp(destNode->module()->name(), "overlayAccessRouter") 00101 == 0)) { 00102 //add node to bootstrap oracle 00103 PeerInfo* info = new PeerInfo(destNode->module()-> 00104 submodule("overlay")->id()); 00105 bootstrapOracle->addPeer(IPvXAddress(nodeAddresses[i]), info); 00106 } 00107 00108 00109 // If destNode is the outRouter, add a default route 00110 // to outside network via the TunOutDevice and a route to the 00111 // Gateway 00112 if ( strcmp(destNode->module()->name(), "outRouter" ) == 0 ) { 00113 RoutingEntry* defRoute = new RoutingEntry(); 00114 defRoute->host = IPAddress::UNSPECIFIED_ADDRESS; 00115 defRoute->netmask = IPAddress::UNSPECIFIED_ADDRESS; 00116 defRoute->gateway = IPAddress(par("gatewayIP").stringValue()); 00117 defRoute->interfaceName = "tunDev"; 00118 defRoute->interfacePtr = IPAddressResolver().interfaceTableOf(destNode->module())-> 00119 interfaceByName("tunDev"); 00120 defRoute->type = RoutingEntry::REMOTE; 00121 defRoute->source = RoutingEntry::MANUAL; 00122 IPAddressResolver().routingTableOf(destNode->module())->addRoutingEntry(defRoute); 00123 00124 RoutingEntry* gwRoute = new RoutingEntry(); 00125 gwRoute->host = IPAddress(par("gatewayIP").stringValue()); 00126 gwRoute->netmask = IPAddress(255, 255, 255, 255); 00127 gwRoute->interfaceName = "tunDev"; 00128 gwRoute->interfacePtr = IPAddressResolver().interfaceTableOf(destNode->module())-> 00129 interfaceByName("tunDev"); 00130 gwRoute->type = RoutingEntry::DIRECT; 00131 gwRoute->source = RoutingEntry::MANUAL; 00132 IPAddressResolver().routingTableOf(destNode->module())->addRoutingEntry(gwRoute); 00133 } 00134 00135 // add route (with host=destNode) to every routing table in the network 00136 for ( int j = 0; j < topo.nodes(); j++ ) { 00137 // continue if same node 00138 if ( i == j ) 00139 continue; 00140 00141 // cancel simulation if node is not conencted with destination 00142 cTopology::Node* atNode = topo.node(j); 00143 if(atNode->paths() == 0) 00144 error((std::string(atNode->module()->name()) + 00145 ": Network is not entirely connected." 00146 "Please increase your value for the " 00147 "connectivity parameter").c_str()); 00148 00149 // 00150 // Add routes at the atNode. 00151 // 00152 00153 // find atNode's interface and routing table 00154 InterfaceTable* ift = IPAddressResolver().interfaceTableOf(atNode->module()); 00155 RoutingTable* rt = IPAddressResolver().routingTableOf(atNode->module()); 00156 00157 // find atNode's interface entry for the next hop node 00158 int outputGateId = atNode->path(0)->localGate()->id(); 00159 InterfaceEntry *ie = ift->interfaceByNodeOutputGateId(outputGateId); 00160 00161 // find the next hop node on the path towards destNode 00162 cModule* next_hop = atNode->path(0)->remoteNode()->module(); 00163 IPAddress next_hop_ip = IPAddressResolver().addressOf(next_hop).get4(); 00164 00165 00166 // Requirement 1: Each router has exactly one routing entry 00167 // (netmask 255.255.0.0) to each other router 00168 RoutingEntry* re = new RoutingEntry(); 00169 00170 re->host = IPAddress(destAddr); 00171 re->interfaceName = ie->name(); 00172 re->interfacePtr = ie; 00173 re->source = RoutingEntry::MANUAL; 00174 re->netmask = IPAddress(255, 255, 0, 0); 00175 re->gateway = IPAddress(next_hop_ip); 00176 re->type = RoutingEntry::REMOTE; 00177 00178 rt->addRoutingEntry(re); 00179 00180 // Requirement 2: Each router has a point-to-point routing 00181 // entry (netmask 255.255.255.255) for each immediate neighbour 00182 if ( atNode->distanceToTarget() == 1 ) { 00183 RoutingEntry* re2 = new RoutingEntry(); 00184 00185 re2->host = IPAddress(destAddr); 00186 re2->interfaceName = ie->name(); 00187 re2->interfacePtr = ie; 00188 re2->source = RoutingEntry::MANUAL; 00189 re2->netmask = IPAddress(255, 255, 255, 255); 00190 re2->type = RoutingEntry::DIRECT; 00191 00192 rt->addRoutingEntry(re2); 00193 } 00194 00195 // If destNode is the outRouter, add a default route 00196 // to the next hop in the direction of the outRouter 00197 if ( strcmp(destNode->module()->name(), "outRouter" ) == 0 ) { 00198 RoutingEntry* defRoute = new RoutingEntry(); 00199 defRoute->host = IPAddress::UNSPECIFIED_ADDRESS; 00200 defRoute->netmask = IPAddress::UNSPECIFIED_ADDRESS; 00201 defRoute->gateway = IPAddress(next_hop_ip); 00202 defRoute->interfaceName = ie->name(); 00203 defRoute->interfacePtr = ie; 00204 defRoute->type = RoutingEntry::REMOTE; 00205 defRoute->source = RoutingEntry::MANUAL; 00206 00207 rt->addRoutingEntry(defRoute); 00208 } 00209 } 00210 } 00211 } 00212 //accessnet configuration 00213 else if(stage == MAX_STAGE_UNDERLAY) { 00214 // fetch some parameters 00215 accessRouterNum = parentModule()->par("accessRouterNum"); 00216 overlayAccessRouterNum = parentModule()->par("overlayAccessRouterNum"); 00217 00218 // flag indicating simulation initialization phase (true) vs. normal mode (false) 00219 init = true; 00220 00221 // count the overlay clients 00222 overlayTerminalCount = 0; 00223 numCreated = 0; 00224 numKilled = 0; 00225 00226 // add access node modules to access node vector 00227 // and assing the channel tpye to be used by the access node 00228 cModule* node; 00229 AccessNet* nodeAccess; 00230 for ( int i = 0; i < accessRouterNum; i++ ) { 00231 node = parentModule()->submodule("accessRouter", i); 00232 accessNode.push_back( node ); 00233 nodeAccess = check_and_cast<AccessNet*>( node->submodule("accessNet") ); 00234 nodeAccess->selectChannel( channelTypes[intuniform(0, channelTypes.size()-1)] ); 00235 } 00236 00237 for ( int i = 0; i < overlayAccessRouterNum; i++ ) { 00238 node = parentModule()->submodule("overlayAccessRouter", i); 00239 accessNode.push_back( node ); 00240 nodeAccess = check_and_cast<AccessNet*>( node->submodule("accessNet") ); 00241 nodeAccess->selectChannel( channelTypes[intuniform(0, channelTypes.size()-1)] ); 00242 } 00243 00244 // add the overlay nodes 00245 firstNodeId = createRandomNode(true); 00246 for ( int i = 1; i < initialOverlayTerminalNum; i++ ) { 00247 createRandomNode(true); 00248 } 00249 00250 // debug stuff 00251 WATCH_PTRVECTOR(accessNode); 00252 00253 // update display 00254 setDisplayString(); 00255 00256 // initialize simulation 00257 if ( par("simulateMobility") ) { 00258 cMessage* msg = new cMessage(); 00259 scheduleAt(simulation.simTime(), msg); 00260 } 00261 } 00262 }
void IPv4UnderlayConfigurator::killRandomNode | ( | ) | [virtual] |
Removes randomly chosen overlay nodes from a randomly chosen access net.
Implements UnderlayConfigurator.
00314 { 00315 // find an access net with one or more overlay nodes 00316 AccessNet* accessNetModule; 00317 do { 00318 int z = intuniform(0, accessNode.size()-1); 00319 accessNetModule = check_and_cast<AccessNet*>(accessNode[z]->submodule("accessNet")); 00320 } while ( accessNetModule->size() == 0 ); 00321 00322 // remove a random node from the access net and delete it 00323 int index = intuniform(0, accessNetModule->size() - 1); 00324 00325 //TODO: keepFirstNode in while-loop? 00326 if(keepFirstNode && (firstNodeId == accessNetModule->getOverlayNodeId(index))) 00327 return; 00328 00329 cModule* node = accessNetModule->removeOverlayNode(index);//intuniform(0, accessNetModule->size() - 1)); 00330 00331 //remove node from bootstrap oracle 00332 bootstrapOracle->killPeer(IPAddressResolver().addressOf(node).get4()); 00333 00334 node->callFinish(); 00335 node->deleteModule(); 00336 00337 overlayTerminalCount--; 00338 numKilled++; 00339 }
void IPv4UnderlayConfigurator::migrateRandomNode | ( | ) | [virtual] |
Migrates randomly chosen overlay nodes from on access net to another.
Implements UnderlayConfigurator.
00342 { 00343 // find an access net with one or more overlay nodes 00344 AccessNet* accessNetModule; 00345 do { 00346 int z = intuniform(0, accessNode.size()-1); 00347 accessNetModule = check_and_cast<AccessNet*>(accessNode[z]->submodule("accessNet")); 00348 } while ( accessNetModule->size() == 0 ); 00349 00350 // disconnect a random overlay node 00351 int index = intuniform(0, accessNetModule->size() - 1); 00352 00353 if(keepFirstNode && (firstNodeId == accessNetModule->getOverlayNodeId(index))) 00354 return; 00355 00356 cModule* node = accessNetModule->removeOverlayNode(index);//intuniform(0, accessNetModule->size() - 1)); 00357 00358 //remove node from bootstrap oracle 00359 bootstrapOracle->killPeer(IPAddressResolver().addressOf(node).get4()); 00360 00361 node->bubble("I am migrating!"); 00362 00363 // connect the node to another access net 00364 AccessNet* newAccessNetModule; 00365 do { 00366 newAccessNetModule = check_and_cast<AccessNet*>(accessNode[intuniform(0, accessNode.size() - 1)]->submodule("accessNet")); 00367 00368 } while((newAccessNetModule == accessNetModule) && (accessNode.size() != 1)); 00369 00370 newAccessNetModule->addOverlayNode(node, true); 00371 00372 // inform the notofication board about the migration 00373 NotificationBoard* nb = check_and_cast<NotificationBoard*>(node->submodule("notificationBoard")); 00374 nb->fireChangeNotification(NF_HOSTPOSITION_UPDATED); 00375 }
void IPv4UnderlayConfigurator::setDisplayString | ( | ) | [protected, virtual] |
Updates the statistics display string.
Implements UnderlayConfigurator.
00378 { 00379 char buf[80]; 00380 sprintf(buf, "%i overlay clients\n%i access router\n%i overlay access router", overlayTerminalCount, accessRouterNum, overlayAccessRouterNum); 00381 displayString().setTagArg("t", 0, buf); 00382 }
std::vector<cModule*> IPv4UnderlayConfigurator::accessNode [protected] |
int IPv4UnderlayConfigurator::accessRouterNum [private] |
int IPv4UnderlayConfigurator::numCreated [protected] |
int IPv4UnderlayConfigurator::numKilled [protected] |
int IPv4UnderlayConfigurator::overlayAccessRouterNum [private] |
int IPv4UnderlayConfigurator::overlayTerminalNum [private] |