00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00025 #include <vector>
00026 #include <iostream>
00027
00028 #include <omnetpp.h>
00029
00030 #include <IRoutingTable.h>
00031 #include <IInterfaceTable.h>
00032 #include <IPAddressResolver.h>
00033 #include <IPv4InterfaceData.h>
00034
00035 #include "ConnectReaSE.h"
00036
00037 using namespace ::std;
00038
00039 Define_Module(ConnectReaSE);
00040
00041 std::ostream& operator<<(std::ostream& os, terminalInfo& n)
00042 {
00043 os << n.module;
00044 return os;
00045 }
00046
00047 void ConnectReaSE::initialize(int stage)
00048 {
00049
00050 if (stage != MAX_STAGE_UNDERLAY)
00051 return;
00052
00053
00054 channelTypesTx = cStringTokenizer(par("channelTypes"), " ").asVector();
00055 channelTypesRx = cStringTokenizer(par("channelTypesRx"), " ").asVector();
00056 channelDiversity = par("channelDiversity");
00057
00058 if (channelTypesTx.size() < channelTypesRx.size()) {
00059 channelTypesTx = channelTypesRx;
00060 }
00061 else if (channelTypesTx.size() > channelTypesRx.size()) {
00062 channelTypesRx = channelTypesTx;
00063 }
00064
00065
00066 if (channelDiversity>=100)
00067 channelDiversity = 99.99f;
00068 else if (channelDiversity<0)
00069 channelDiversity = 0;
00070
00071
00072 lifetimeVector.setName("Terminal Lifetime");
00073
00074
00075
00076 cModule* tempModule;
00077 cTopology tempTopology("tempTopo");
00078 edgePool tempEdgePool;
00079
00080
00081 tempTopology.extractByProperty("AS");
00082 totalCountOfAS = tempTopology.getNumNodes();
00083
00084 nextPow = 0;
00085 while (((uint32_t) 1 << nextPow) < totalCountOfAS + 1) {
00086 nextPow++;
00087 }
00088 ASShift = 32 - nextPow;
00089
00090 if (tempTopology.getNumNodes() == 0) {
00091
00092
00093
00094 tempTopology.extractByProperty("RL");
00095
00096 if (tempTopology.getNumNodes() == 0)
00097
00098
00099 opp_error("ConnectReaSE: Neither an AS topology nor a router topology was detected.");
00100
00101 setUpAS(getParentModule());
00102 }
00103 else {
00104
00105
00106 int index = 0;
00107 std::vector<cModule*> Modules;
00108 for (int i=0; i<tempTopology.getNumNodes(); i++) {
00109
00110 tempModule = tempTopology.getNode(i)->getModule();
00111 Modules.push_back(tempModule);
00112 index++;
00113 }
00114 for (uint32 i=0; i< Modules.size(); i++) {
00115 setUpAS(Modules[i]);
00116 }
00117 }
00118
00119
00120 for (uint32 i=0; i<AS_Pool.size(); i++) {
00121 for (uint32 j=0; j< AS_Pool[i].edgeRouter.size(); j++) {
00122 tempEdgePool.edge = &AS_Pool[i].edgeRouter[j];
00123 tempEdgePool.indexAS = i;
00124 globalEdgePool.push_back(tempEdgePool);
00125 }
00126 }
00127
00128
00129 for (uint32 i=0; i<globalEdgePool.size(); i++) {
00130
00131
00132 globalEdgePool[i].edge->channelTypeTxStr = channelTypesTx[intuniform(0,channelTypesTx.size()-1)];
00133 globalEdgePool[i].edge->channelTypeRxStr = channelTypesRx[intuniform(0,channelTypesRx.size()-1)];
00134 }
00135 }
00136
00137 AccessInfo ConnectReaSE::getAccessNode()
00138 {
00139 Enter_Method("getAccessNode()");
00140
00141 bool candidateOK = false;
00142 int numTries = 10;
00143 uint32 test_IP = 0;
00144 AccessInfo node;
00145 edgeRoutes* connectionCandidate;
00146 uint32 tempIndex, tempASindex;
00147
00148 while ((numTries > 0)&&(!candidateOK)) {
00149 numTries--;
00150 tempIndex = intuniform(0, globalEdgePool.size()-1);
00151 connectionCandidate = globalEdgePool[tempIndex].edge;
00152 tempASindex = globalEdgePool[tempIndex].indexAS;
00153
00154
00155 if (connectionCandidate->IPAddresses.size() >= ((uint32_t) 1 << AS_Pool[tempASindex].edgeShift))
00156 continue;
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 test_IP = ++connectionCandidate->lastIP;
00177 connectionCandidate->IPAddresses.push_back(test_IP);
00178 break;
00179
00180 }
00181
00182
00183 if (numTries == 0) {
00184 opp_error("Error creating node: No available IP found after four tries!");
00185 }
00186 EV << "Found available IP: " << test_IP;
00187
00188 node.ASindex = tempASindex;
00189 node.IPAddress = test_IP;
00190 node.edge = connectionCandidate;
00191 return node;
00192 }
00193
00194 int ConnectReaSE::addOverlayNode(AccessInfo* overlayNode, bool migrate)
00195 {
00196 Enter_Method("addOverlayNode()");
00197
00198 cModule* node = overlayNode->terminal;
00199 terminalInfo terminal;
00200
00201 terminal.module = node;
00202 terminal.interfaceTable = IPAddressResolver().interfaceTableOf(node);
00203 terminal.remoteInterfaceTable = overlayNode->edge->interfaceTable;
00204 terminal.routingTable = IPAddressResolver().routingTableOf(node);
00205 terminal.PPPInterface = node->getSubmodule("ppp", 0);
00206 terminal.createdAt = simTime();
00207 terminal.IPAddress = overlayNode->IPAddress;
00208 terminal.edgeRouter = overlayNode->edge;
00209 terminal.ASindex = overlayNode->ASindex;
00210
00211
00212 if (ev.isGUI()) {
00213 const char* ip_disp = const_cast<char*>
00214 (IPAddress(terminal.IPAddress).str().c_str());
00215 terminal.module->getDisplayString().insertTag("t", 0);
00216 terminal.module->getDisplayString().setTagArg("t", 0, ip_disp);
00217 terminal.module->getDisplayString().setTagArg("t", 1, "l");
00218 }
00219
00220
00221 int k = 1;
00222 while ( overlayNode->edge->Router->findSubmodule("ppp", k) != -1 )
00223 k++;
00224
00225
00226 cModuleType* pppInterfaceModuleType = cModuleType::get("inet.linklayer.ppp.PPPInterface");
00227 terminal.remotePPPInterface = pppInterfaceModuleType->
00228 create("ppp", overlayNode->edge->Router, 0, k);
00229
00230 overlayNode->edge->countPPPInterfaces++;
00231
00232
00233
00234 cGate* routerInGate = firstUnusedGate(overlayNode->edge->Router, "pppg", cGate::INPUT);
00235 cGate* routerOutGate = firstUnusedGate(overlayNode->edge->Router, "pppg", cGate::OUTPUT);
00236
00237 cChannelType* channelTypeRx = cChannelType::find( overlayNode->edge->channelTypeRxStr.c_str() );
00238 cChannelType* channelTypeTx = cChannelType::find( overlayNode->edge->channelTypeTxStr.c_str() );
00239 if (!channelTypeRx || !channelTypeTx)
00240 opp_error("Could not find Channel or ChannelRx Type. Most likely "
00241 "parameter channelTypes does not match the channels defined "
00242 "in channels.ned");
00243
00244
00245 cDatarateChannel* channelRx = check_and_cast<cDatarateChannel*>(channelTypeRx->create(overlayNode->edge->channelTypeRxStr.c_str()));
00246 cDatarateChannel* channelTx = check_and_cast<cDatarateChannel*>(channelTypeTx->create(overlayNode->edge->channelTypeTxStr.c_str()));
00247
00248
00249 terminal.module->gate("pppg$o", 0)->connectTo(routerInGate,channelRx);
00250 routerOutGate->connectTo(terminal.module->gate("pppg$i", 0),channelTx);
00251
00252
00253 routerInGate->connectTo(terminal.remotePPPInterface->gate("phys$i"));
00254 terminal.remotePPPInterface->gate("phys$o")->connectTo(routerOutGate);
00255
00256
00257 cModule* netwModule = overlayNode->edge->Router->getSubmodule("networkLayer");
00258
00259 cGate* netwInGate = firstUnusedGate(netwModule, "ifIn");
00260 cGate* netwOutGate = firstUnusedGate(netwModule, "ifOut");
00261
00262 netwOutGate->connectTo(terminal.remotePPPInterface->gate("netwIn"));
00263 terminal.remotePPPInterface->gate("netwOut")->connectTo(netwInGate);
00264
00265
00266 cModule* ipModule = overlayNode->edge->Router->getSubmodule("networkLayer")->
00267 getSubmodule("ip");
00268
00269 cGate* ipIn = firstUnusedGate(ipModule, "queueIn");
00270 netwInGate->connectTo(ipIn);
00271
00272
00273
00274
00275 terminal.remotePPPInterface->finalizeParameters();
00276 terminal.remotePPPInterface->setDisplayString("i=block/ifcard");
00277 terminal.remotePPPInterface->buildInside();
00278 terminal.remotePPPInterface->scheduleStart(simTime());
00279 terminal.remotePPPInterface->callInitialize();
00280
00281 if ( !migrate) {
00282
00283
00284 for (int i=0; i < MAX_STAGE_UNDERLAY + 1; i++) {
00285 terminal.module->callInitialize(i);
00286 }
00287 }
00288
00289
00290 double diversityFactor = (uniform(0 , 2*channelDiversity) + (100-channelDiversity))/100;
00291
00292
00293 channelRx->setDelay(SIMTIME_DBL(channelRx->getDelay()*diversityFactor));
00294 channelTx->setDelay(SIMTIME_DBL(channelTx->getDelay()*diversityFactor));
00295
00296 terminal.remoteInterfaceEntry = overlayNode->edge->interfaceTable->getInterface(
00297 overlayNode->edge->interfaceTable->getNumInterfaces() - 1);
00298 terminal.interfaceEntry = terminal.interfaceTable->getInterfaceByName("ppp0");
00299
00300
00301
00302
00303
00304
00305
00306 IPv4InterfaceData* interfaceData = new IPv4InterfaceData;
00307 interfaceData->setIPAddress(overlayNode->edge->IPAddress);
00308 interfaceData->setNetmask(IPAddress::ALLONES_ADDRESS);
00309 terminal.remoteInterfaceEntry->setIPv4Data(interfaceData);
00310
00311
00312 terminal.interfaceEntry->ipv4Data()->setIPAddress(IPAddress(terminal.IPAddress));
00313 terminal.interfaceEntry->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
00314
00315
00316
00317
00318
00319
00320
00321
00322 IPRoute* re = new IPRoute();
00323 re->setHost(IPAddress(terminal.IPAddress));
00324 re->setNetmask(IPAddress::ALLONES_ADDRESS);
00325 re->setInterface(terminal.remoteInterfaceEntry);
00326 re->setType(IPRoute::DIRECT);
00327 re->setSource(IPRoute::MANUAL);
00328 overlayNode->edge->routingTable->addRoute(re);
00329 terminal.remoteRoutingEntry = re;
00330
00331
00332
00333 IPRoute* te = new IPRoute();
00334 te->setHost(IPAddress::UNSPECIFIED_ADDRESS);
00335 te->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
00336 te->setGateway(overlayNode->edge->IPAddress);
00337 te->setInterface(terminal.interfaceEntry);
00338 te->setType(IPRoute::REMOTE);
00339 te->setSource(IPRoute::MANUAL);
00340 terminal.routingTable->addRoute(te);
00341 terminal.routingEntry = te;
00342
00343
00344 overlayTerminal.push_back(terminal);
00345 updateDisplayString();
00346 int ID = node->getId();
00347 return ID;
00348 }
00349
00350 cModule* ConnectReaSE::removeOverlayNode(int ID)
00351 {
00352 Enter_Method("removeOverlayNode()");
00353
00354 cModule* node = NULL;
00355 terminalInfo terminal;
00356 int index = 0;
00357 uint32 releasedIP;
00358
00359
00360 for (unsigned int i=0; i<overlayTerminal.size(); i++) {
00361 if (overlayTerminal[i].module->getId() == ID) {
00362 terminal = overlayTerminal[i];
00363 node = terminal.module;
00364 index = i;
00365 break;
00366 }
00367 }
00368
00369 if (node == NULL) return NULL;
00370
00371
00372 releasedIP = IPAddressResolver().addressOf(terminal.module).get4().getInt();;
00373
00374
00375 for (unsigned int i=0; i < terminal.edgeRouter->IPAddresses.size(); i++) {
00376 if (terminal.edgeRouter->IPAddresses[i] == releasedIP) {
00377 terminal.edgeRouter->IPAddresses.erase(terminal.edgeRouter->IPAddresses.begin() + i);
00378 break;
00379 }
00380 }
00381
00382
00383 cModule* ppp = terminal.remotePPPInterface;
00384
00385
00386
00387 node->gate("pppg$o", 0)->disconnect();
00388 node->gate("pppg$i", 0)->getPreviousGate()->disconnect();
00389
00390
00391 ppp->gate("netwIn")->getPathStartGate()->disconnect();
00392 ppp->gate("netwOut")->getNextGate()->disconnect();
00393
00394
00395 ppp->callFinish();
00396 ppp->deleteModule();
00397
00398 terminal.edgeRouter->countPPPInterfaces--;
00399
00400
00401 terminal.edgeRouter->interfaceTable->deleteInterface(terminal.remoteInterfaceEntry);
00402
00403
00404
00405 terminal.routingTable->deleteRoute(terminal.routingEntry);
00406 terminal.edgeRouter->routingTable ->deleteRoute(terminal.remoteRoutingEntry);
00407
00408
00409 lifetimeVector.record(simTime() - overlayTerminal[index].createdAt);
00410
00411
00412 overlayTerminal.erase(overlayTerminal.begin() + index);
00413
00414 updateDisplayString();
00415
00416 return node;
00417 }
00418
00419 cModule* ConnectReaSE::getOverlayNode(int ID)
00420 {
00421 Enter_Method("getOverlayNode()");
00422
00423 cModule* node = NULL;
00424
00425 for (unsigned int i=0; i<overlayTerminal.size(); i++) {
00426 if (overlayTerminal[i].module->getId() == ID) {
00427 node = overlayTerminal[i].module;
00428 return node;
00429 }
00430 }
00431 opp_error("Node was not found in global list of overlay terminals");
00432 return node;
00433 }
00434
00435 AccessInfo ConnectReaSE::migrateNode(int ID)
00436 {
00437
00438 Enter_Method("migrateNode()");
00439
00440 AccessInfo newEdgeRouter;
00441 terminalInfo terminal;
00442
00443 for (unsigned int i=0; i<overlayTerminal.size(); i++) {
00444 if (overlayTerminal[i].module->getId() == ID) {
00445 terminal = overlayTerminal[i];
00446 break;
00447 }
00448 }
00449
00450 if (terminal.module == NULL) opp_error("ConnectReaSE: Cannot find migrating node");
00451
00452 do {
00453 newEdgeRouter = getAccessNode();
00454 }
00455 while ((newEdgeRouter.edge->Router->getId() == terminal.edgeRouter->Router->getId()) && (AS_Pool[terminal.ASindex].edgeRouter.size()!= 1));
00456
00457 return newEdgeRouter;
00458 }
00459
00460 void ConnectReaSE::handleMessage(cMessage* msg)
00461 {
00462 error("this module doesn't handle messages, it runs only in initialize()");
00463 }
00464
00465 void ConnectReaSE::updateDisplayString()
00466 {
00467 if (ev.isGUI()) {
00468 char buf[80];
00469 if ( overlayTerminal.size() == 1 ) {
00470 sprintf(buf, "1 terminal connected");
00471 } else {
00472 sprintf(buf, "%zi terminals connected", overlayTerminal.size());
00473 }
00474 getDisplayString().setTagArg("t", 0, buf);
00475 getDisplayString().setTagArg("t", 2, "blue");
00476
00477 if ((overlayTerminal.size() % 100) == 0) {
00478 cerr << "ConnectReaSE: " << overlayTerminal.size() << " Terminals connected in network." <<endl;
00479 }
00480 }
00481 }
00482
00483 cGate* ConnectReaSE::firstUnusedGate(cModule* owner, const char* name, cGate::Type type)
00484 {
00485 int index;
00486 for (index = 0; index < owner->gateSize(name); index++) {
00487 cGate *gate = type == cGate::NONE ? owner->gate(name, index) : owner->gateHalf(name, type, index);
00488 if (!gate->isConnectedOutside()) {
00489 return gate;
00490 }
00491 }
00492
00493 owner->setGateSize(name, index + 2);
00494 return type == cGate::NONE ? owner->gate(name, index + 1) : owner->gateHalf(name, type, index + 1);
00495 }
00496
00497 bool ConnectReaSE::extractFromParentModule(cModule* currModule, void* properties)
00498 {
00499 topologyProperty* currProp = (topologyProperty*)properties;
00500
00501 if (currModule->getParentModule() == currProp->pModule) {
00502 if (currModule->getProperties()->get(currProp->property)) {
00503 return true;
00504 }
00505 }
00506 return false;
00507 }
00508
00509 void ConnectReaSE::setUpAS(cModule* currAS)
00510 {
00511
00512 cTopology edgeTopo("Edges");
00513 cTopology Topo("All nodes");
00514 topologyProperty* tempProp = new topologyProperty;
00515 cModule* tempNode;
00516 uint32 tempIP;
00517 edgeRoutes tempEdge;
00518 autoSystem tempAS;
00519 int k;
00520
00521 tempProp->pModule = currAS;
00522
00523
00524 tempProp->property = "EdgeRouter";
00525 edgeTopo.extractFromNetwork(extractFromParentModule, (void*) tempProp);
00526
00527 tempProp->property = "RL";
00528 Topo.extractFromNetwork(extractFromParentModule, (void*) tempProp);
00529
00530
00531
00532 nextPow = 1;
00533 while ((1 << nextPow) < edgeTopo.getNumNodes() + 2) {
00534 nextPow++;
00535 }
00536 tempAS.edgeShift = ASShift - nextPow;
00537
00538
00539
00540 for (int i=0; i< edgeTopo.getNumNodes(); i++) {
00541
00542 tempEdge.Router = edgeTopo.getNode(i)->getModule();
00543 tempEdge.IPAddress = IPAddressResolver().addressOf(tempEdge.Router).get4().getInt();
00544 tempEdge.IPAddresses.push_back(IPAddressResolver().addressOf(tempEdge.Router).get4().getInt());
00545 tempEdge.interfaceTable = IPAddressResolver().interfaceTableOf(tempEdge.Router);
00546 tempEdge.routingTable = IPAddressResolver().routingTableOf(tempEdge.Router);
00547
00548 k = 0;
00549 while ( tempEdge.Router->findSubmodule("ppp", k) != -1 )
00550 k++;
00551 tempEdge.countPPPInterfaces = k;
00552
00553
00554 tempEdge.lastIP = tempEdge.IPAddress + k - 1;
00555
00556
00557
00558 Topo.calculateUnweightedSingleShortestPathsTo(Topo.getNodeFor(edgeTopo.getNode(i)->getModule()));
00559
00560 for (int j=0; j< Topo.getNumNodes(); j++) {
00561 tempNode = Topo.getNode(j)->getModule();
00562 if (tempNode->getProperties()->get("CoreRouter"))
00563 continue;
00564 if (tempNode->getProperties()->get("GatewayRouter"))
00565 continue;
00566 if (tempNode->getProperties()->get("EdgeRouter"))
00567 continue;
00568 if (Topo.getNode(j)->getPath(0)->getRemoteNode()->getModule() != edgeTopo.getNode(i)->getModule())
00569 continue;
00570
00571
00572 tempIP = IPAddressResolver().addressOf(Topo.getNode(j)->getModule()).get4().getInt();
00573 tempEdge.IPAddresses.push_back(tempIP);
00574 }
00575
00576 tempAS.edgeRouter.push_back(tempEdge);
00577 }
00578
00579 delete tempProp;
00580 AS_Pool.push_back(tempAS);
00581 }