Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "ReaSEUnderlayConfigurator.h"
00025
00026 #include <GlobalNodeList.h>
00027 #include <TransportAddress.h>
00028
00029 #include <StringConvert.h>
00030
00031 #include <ConnectReaSE.h>
00032 #include <IRoutingTable.h>
00033 #include <IInterfaceTable.h>
00034 #include <IPAddressResolver.h>
00035 #include <IPv4InterfaceData.h>
00036 #include <NotificationBoard.h>
00037
00038
00039 #include <ReaSEInfo.h>
00040
00041 Define_Module(ReaSEUnderlayConfigurator);
00042
00043 void ReaSEUnderlayConfigurator::initializeUnderlay(int stage)
00044 {
00045
00046 if (stage == MIN_STAGE_UNDERLAY) {
00047
00048 }
00049
00050 else if (stage == MAX_STAGE_UNDERLAY) {
00051
00052
00053
00054
00055 overlayTerminalCount = 0;
00056
00057 numCreated = 0;
00058 numKilled = 0;
00059
00060
00061 TerminalConnector = (ConnectReaSE*)getParentModule()->getSubmodule("TerminalConnector");
00062 }
00063 }
00064
00065 TransportAddress* ReaSEUnderlayConfigurator::createNode(NodeType type, bool initialize)
00066 {
00067 Enter_Method_Silent();
00068
00069 std::string nameStr = "overlayTerminal";
00070 if (churnGenerator.size() > 1) {
00071 nameStr += "-" + convertToString<int32_t>(type.typeID);
00072 }
00073 AccessInfo accessNet= TerminalConnector->getAccessNode();
00074 cModuleType* moduleType = cModuleType::get(type.terminalType.c_str());
00075 cModule* node = moduleType->create(nameStr.c_str(), accessNet.edge->Router->getParentModule(),
00076 numCreated + 1, numCreated);
00077
00078 if (type.channelTypesTx.size() > 0) {
00079 throw cRuntimeError("ReaSEUnderlayConfigurator::createNode(): Setting "
00080 "channel types via the churn generator is not allowed "
00081 "with the ReaSEUnderlay. Use **.accessNet.channelTypes instead!");
00082 }
00083
00084 node->setGateSize("pppg", 1);
00085
00086 std::string displayString;
00087
00088 if ((type.typeID > 0) && (type.typeID <= NUM_COLORS)) {
00089 ((displayString += "i=device/wifilaptop_l,")
00090 += colorNames[type.typeID - 1])
00091 += ",40;i2=block/circle_s";
00092 } else {
00093 displayString = "i=device/wifilaptop_l;i2=block/circle_s";
00094 }
00095
00096 node->finalizeParameters();
00097 node->setDisplayString(displayString.c_str());
00098
00099 node->buildInside();
00100 node->scheduleStart(simTime());
00101
00102
00103 ReaSEInfo* info = new ReaSEInfo(type.typeID, node->getId(), type.context);
00104
00105 accessNet.terminal = node;
00106
00107 info->setNodeID(TerminalConnector->addOverlayNode(&accessNet));
00108
00109
00110
00111 globalNodeList->addPeer(IPAddressResolver().addressOf(node), info);
00112
00113
00114
00115 if (!initialize) {
00116 for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) {
00117 node->callInitialize(i);
00118 }
00119 }
00120
00121 overlayTerminalCount++;
00122 numCreated++;
00123
00124 churnGenerator[type.typeID]->terminalCount++;
00125
00126 TransportAddress *address = new TransportAddress(
00127 IPAddressResolver().addressOf(node));
00128
00129
00130 setDisplayString();
00131
00132 return address;
00133 }
00134
00135
00136 void ReaSEUnderlayConfigurator::preKillNode(NodeType type, TransportAddress* addr)
00137 {
00138 Enter_Method_Silent();
00139
00140
00141 int nodeID;
00142 ReaSEInfo* info;
00143
00144
00145 if (addr == NULL) {
00146 addr = globalNodeList->getRandomAliveNode(type.typeID);
00147
00148 if (addr == NULL) {
00149
00150 std::cout << "all nodes are already prekilled" << std::endl;
00151 return;
00152 }
00153 }
00154
00155
00156 info = dynamic_cast<ReaSEInfo*>(globalNodeList->getPeerInfo(*addr));
00157
00158 if (info != NULL) {
00159
00160 nodeID = info->getNodeID();
00161 } else {
00162 opp_error("IPv4UnderlayConfigurator: Trying to pre kill node "
00163 "with nonexistant TransportAddress!");
00164 }
00165
00166 uint32_t effectiveType = info->getTypeID();
00167
00168
00169 if (scheduledID.count(nodeID))
00170 return;
00171
00172 cModule* node = TerminalConnector->getOverlayNode(nodeID);
00173 globalNodeList->removePeer(IPAddressResolver().addressOf(node));
00174
00175
00176 killList.push_front(IPAddressResolver().addressOf(node));
00177 scheduledID.insert(nodeID);
00178
00179 overlayTerminalCount--;
00180 numKilled++;
00181
00182 churnGenerator[effectiveType]->terminalCount--;
00183
00184
00185 setDisplayString();
00186
00187
00188 NotificationBoard* nb = check_and_cast<NotificationBoard*>(
00189 node->getSubmodule("notificationBoard"));
00190 nb->fireChangeNotification(NF_OVERLAY_NODE_LEAVE);
00191
00192 double random = uniform(0, 1);
00193
00194 if (random < gracefulLeaveProbability) {
00195 nb->fireChangeNotification(NF_OVERLAY_NODE_GRACEFUL_LEAVE);
00196 }
00197
00198 cMessage* msg = new cMessage();
00199 scheduleAt(simTime() + gracefulLeaveDelay, msg);
00200
00201 }
00202
00203 void ReaSEUnderlayConfigurator::migrateNode(NodeType type, TransportAddress* addr)
00204 {
00205 Enter_Method_Silent();
00206
00207
00208 int nodeID = -1;
00209 ReaSEInfo* info;
00210
00211
00212 if (addr == NULL) {
00213 info = dynamic_cast<ReaSEInfo*>(globalNodeList->getRandomPeerInfo(type.typeID));
00214 } else {
00215
00216 info = dynamic_cast<ReaSEInfo*>(globalNodeList->getPeerInfo(*addr));
00217 }
00218
00219 if (info != NULL) {
00220
00221 nodeID = info->getNodeID();
00222 } else {
00223 opp_error("ReaSEUnderlayConfigurator: Trying to pre kill node with nonexistant TransportAddress!");
00224 }
00225
00226
00227 if (scheduledID.count(nodeID))
00228 return;
00229
00230 cModule* node = TerminalConnector->removeOverlayNode(nodeID);
00231
00232 if (node == NULL)
00233 opp_error("ReaSEUnderlayConfigurator: Trying to remove node which is not an overlay node in network!");
00234
00235
00236 globalNodeList->killPeer(IPAddressResolver().addressOf(node));
00237
00238 node->bubble("I am migrating!");
00239
00240 AccessInfo newAccessModule;
00241
00242
00243 ReaSEInfo* newinfo = new ReaSEInfo(type.typeID, node->getId(), type.context);
00244 newAccessModule = TerminalConnector->migrateNode(node->getId());
00245 newAccessModule.terminal = node;
00246
00247 info->setNodeID(TerminalConnector->addOverlayNode(&newAccessModule));
00248
00249
00250 globalNodeList->addPeer(IPAddressResolver().addressOf(node), newinfo);
00251
00252
00253 NotificationBoard* nb = check_and_cast<NotificationBoard*>(node->getSubmodule("notificationBoard"));
00254 nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00255 }
00256
00257 void ReaSEUnderlayConfigurator::handleTimerEvent(cMessage* msg)
00258 {
00259 Enter_Method_Silent();
00260
00261
00262 IPvXAddress addr = killList.back();
00263 killList.pop_back();
00264
00265
00266 int nodeID = -1;
00267
00268 ReaSEInfo* info = dynamic_cast<ReaSEInfo*>(globalNodeList->getPeerInfo(addr));
00269 if (info != NULL) {
00270
00271 nodeID = info->getNodeID();
00272 } else {
00273 opp_error("IPv4UnderlayConfigurator: Trying to kill node with nonexistant TransportAddress!");
00274 }
00275
00276 scheduledID.erase(nodeID);
00277 globalNodeList->killPeer(addr);
00278
00279 cModule* node = TerminalConnector->removeOverlayNode(nodeID);
00280
00281 if (node == NULL)
00282 opp_error("IPv4UnderlayConfigurator: Trying to remove node which is nonexistant in AccessNet!");
00283
00284 node->callFinish();
00285 node->deleteModule();
00286
00287 delete msg;
00288 }
00289
00290 void ReaSEUnderlayConfigurator::setDisplayString()
00291 {
00292 char buf[80];
00293 sprintf(buf, "%i overlay terminals",
00294 overlayTerminalCount);
00295 getDisplayString().setTagArg("t", 0, buf);
00296 }
00297
00298 void ReaSEUnderlayConfigurator::finishUnderlay()
00299 {
00300
00301 recordScalar("Terminals added", numCreated);
00302 recordScalar("Terminals removed", numKilled);
00303
00304 if (!isInInitPhase()) {
00305 struct timeval now, diff;
00306 gettimeofday(&now, NULL);
00307 timersub(&now, &initFinishedTime, &diff);
00308 printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00309 }
00310 }
00311
00312