I3.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00023 #include <UDPAppBase.h>
00024 #include <UDPControlInfo_m.h>
00025 #include "UDPSocket.h"
00026 #include "UDPControlInfo_m.h"
00027
00028 #include <IPAddressResolver.h>
00029 #include <CommonMessages_m.h>
00030 #include <GlobalNodeListAccess.h>
00031 #include <UnderlayConfiguratorAccess.h>
00032
00033 #include <omnetpp.h>
00034 #include <OverlayKey.h>
00035 #include "SHA1.h"
00036
00037 #include "TriggerTable.h"
00038 #include "I3Identifier.h"
00039 #include "I3IPAddress.h"
00040 #include "I3SubIdentifier.h"
00041 #include "I3IdentifierStack.h"
00042 #include "I3Trigger.h"
00043 #include "I3Message_m.h"
00044 #include "I3Message.h"
00045 #include "I3.h"
00046
00047 using namespace std;
00048
00049 std::ostream& operator<<(std::ostream& os, const I3TriggerSet &t)
00050 {
00051 os << endl;
00052
00053 I3TriggerSet::iterator it;
00054 for (it = t.begin(); it != t.end(); it++) {
00055 os << *it << " in " << it->getInsertionTime() << "(" <<
00056 (simTime() - it->getInsertionTime()) << ")" << endl;
00057 }
00058 return os;
00059 }
00060
00061 Define_Module(I3);
00062
00063 const I3Identifier *I3::findClosestMatch(const I3Identifier &t) const
00064 {
00065 int prevDist = 0, nextDist = 0;
00066
00067
00068 if (triggerTable.size() == 0) return 0;
00069
00070
00071
00072 I3TriggerTable::const_iterator it = triggerTable.lower_bound(t);
00073
00074 if (it == triggerTable.end()) {
00075 it--;
00076 }
00077
00078 if (it->first == t) return &it->first;
00079
00080 if (it != triggerTable.begin()) {
00081
00082
00083
00084
00085
00086 nextDist = it->first.distanceTo(t);
00087 it--;
00088 prevDist = it->first.distanceTo(t);
00089
00090
00091 if (nextDist < prevDist) {
00092 it++;
00093 }
00094 }
00095
00096
00097 return (it->first.isMatch(t)) ? &it->first : 0;
00098 }
00099
00100 void I3::insertTrigger(I3Trigger &t)
00101 {
00102
00103 if (t.getIdentifierStack().size() == 0) {
00104
00105 cout << "Warning: Got trigger " << t << " with size 0 in " << thisNode.getAddress()<< endl;
00106 return;
00107 }
00108
00109 t.setInsertionTime(simTime());
00110
00111
00112
00113
00114 triggerTable[t.getIdentifier()].erase(t);
00115 triggerTable[t.getIdentifier()].insert(t);
00116
00117 updateTriggerTableString();
00118 }
00119
00120 void I3::removeTrigger(I3Trigger &t)
00121 {
00122
00123
00124
00125
00126 if (triggerTable.count(t.getIdentifier()) == 0) return;
00127
00128 set<I3Trigger> &s = triggerTable[t.getIdentifier()];
00129
00130 s.erase(t);
00131
00132 if (s.size() == 0) triggerTable.erase(t.getIdentifier());
00133
00134 updateTriggerTableString();
00135 }
00136
00137 void I3::sendToNode(I3SendPacketMessage *imsg)
00138 {
00139 I3IPAddress address;
00140
00141 address = imsg->getIdentifierStack().peek().getIPAddress();
00142 imsg->getIdentifierStack().pop();
00143 sendMessageToUDP(address, imsg);
00144 }
00145
00146 void I3::sendPacket(I3SendPacketMessage *msg)
00147 {
00148
00149 I3IdentifierStack &idStack = msg->getIdentifierStack();
00150
00151 if (idStack.size() == 0) {
00152
00153
00154 numDroppedPackets++;
00155 byteDroppedPackets += msg->getBitLength();
00156 delete msg;
00157 return;
00158 }
00159
00160 I3SubIdentifier id = idStack.peek();
00161
00162 if (id.getType() == I3SubIdentifier::IPAddress) {
00163
00164 sendToNode(msg);
00165 } else {
00166
00167
00168 if (msg->getSendReply()) {
00169 sendQueryReply(id.getIdentifier(), msg->getSource());
00170 }
00171
00172 const I3Identifier *i3id = findClosestMatch(id.getIdentifier());
00173
00174
00175 idStack.pop();
00176
00177 if (!i3id) {
00178
00179 if (idStack.size() == 0) {
00180
00181 numDroppedPackets++;
00182 byteDroppedPackets += msg->getBitLength();
00183 cout << "Dropped packet at" << thisNode.getAddress()<< " to unknown id " << id.getIdentifier() << endl;
00184 delete msg;
00185 return;
00186 } else {
00187 msg->setBitLength(SEND_PACKET_L(msg));
00188 if (idStack.peek().getType() == I3SubIdentifier::IPAddress) {
00189 msg->getMatchedTrigger().clear();
00190 sendToNode(msg);
00191 } else {
00192 OverlayKey key = idStack.peek().getIdentifier().asOverlayKey();
00193 callRoute(key, msg);
00194 }
00195 }
00196
00197 } else {
00198
00199 set<I3Trigger> &s = triggerTable[*i3id];
00200 set<I3Trigger>::iterator it;
00201
00202 for (it = s.begin(); it != s.end(); it++) {
00203 I3SendPacketMessage *newMsg;
00204 cPacket *dupMsg;
00205
00206 newMsg = new I3SendPacketMessage();
00207 newMsg->setIdentifierStack(idStack);
00208 newMsg->getIdentifierStack().push(it->getIdentifierStack());
00209 dupMsg = check_and_cast<cPacket*>(msg->getEncapsulatedPacket()->dup());
00210 newMsg->setBitLength(SEND_PACKET_L(newMsg));
00211 newMsg->encapsulate(dupMsg);
00212
00213 I3SubIdentifier &top = newMsg->getIdentifierStack().peek();
00214
00215 if (top.getType() == I3SubIdentifier::IPAddress) {
00216 newMsg->setMatchedTrigger(*it);
00217 sendToNode(newMsg);
00218 } else {
00219 OverlayKey key = top.getIdentifier().asOverlayKey();
00220 callRoute(key, newMsg);
00221 }
00222 }
00223
00224
00225 delete msg;
00226
00227 }
00228 }
00229 }
00230
00231 void I3::forward(OverlayKey *key, cPacket **msg, NodeHandle *hint)
00232 {
00233 numForwardedPackets++;
00234 numForwardedBytes += (*msg)->getByteLength();
00235
00236 BaseApp::forward(key, msg, hint);
00237 }
00238
00239
00240 void I3::handleUDPMessage(cMessage *msg)
00241 {
00242 I3Message *i3msg;
00243
00244 i3msg = dynamic_cast<I3Message*>(msg);
00245
00246 if (!i3msg) {
00247 delete msg;
00248 return;
00249 }
00250
00251 OverlayKey key;
00252
00253 msg->removeControlInfo();
00254 switch (i3msg->getType()) {
00255 case INSERT_TRIGGER:
00256 I3InsertTriggerMessage *imsg;
00257
00258 imsg = check_and_cast<I3InsertTriggerMessage*>(i3msg);
00259 key = imsg->getTrigger().getIdentifier().asOverlayKey();
00260 callRoute(key, imsg);
00261
00262
00263
00264
00265
00266 break;
00267 case REMOVE_TRIGGER:
00268 I3RemoveTriggerMessage *rmsg;
00269
00270 rmsg = check_and_cast<I3RemoveTriggerMessage*>(i3msg);
00271 key = rmsg->getTrigger().getIdentifier().asOverlayKey();
00272 callRoute(key, rmsg);
00273
00274 break;
00275 case SEND_PACKET:
00276 {
00277 I3SendPacketMessage *smsg;
00278
00279 smsg = check_and_cast<I3SendPacketMessage*>(i3msg);
00280 if (smsg->getIdentifierStack().size() == 0) {
00281
00282 delete msg;
00283 return;
00284 }
00285 I3SubIdentifier &subId = smsg->getIdentifierStack().peek();
00286 if (subId.getType() == I3SubIdentifier::IPAddress) {
00287
00288 sendToNode(smsg);
00289 } else {
00290 key = subId.getIdentifier().asOverlayKey();
00291 callRoute(key, smsg);
00292 }
00293 break;
00294 }
00295 default:
00296
00297 delete msg;
00298 break;
00299 }
00300 }
00301
00302 void I3::sendQueryReply(const I3Identifier &id, const I3IPAddress &add) {
00303 I3QueryReplyMessage *pmsg;
00304 I3IPAddress myAddress(thisNode.getAddress(), par("serverPort"));
00305
00306 pmsg = new I3QueryReplyMessage();
00307 pmsg->setSource(myAddress);
00308 pmsg->setSendingTime(simTime());
00309 pmsg->setIdentifier(id);
00310 pmsg->setBitLength(QUERY_REPLY_L(pmsg));
00311 sendMessageToUDP(add, pmsg);
00312 }
00313
00314 void I3::deliver(OverlayKey& key, cMessage* msg)
00315 {
00316 I3Message *i3msg;
00317
00318 i3msg = dynamic_cast<I3Message*>(msg);
00319 if (!i3msg) {
00320 cout << "Delivered non I3 Message!" << endl;
00321 delete msg;
00322 return;
00323 }
00324
00325 switch (i3msg->getType()) {
00326 case INSERT_TRIGGER:
00327 I3InsertTriggerMessage *imsg;
00328
00329 imsg = check_and_cast<I3InsertTriggerMessage*>(i3msg);
00330 insertTrigger(imsg->getTrigger());
00331
00332 if (imsg->getSendReply()) {
00333 sendQueryReply(imsg->getTrigger().getIdentifier(), imsg->getSource());
00334 }
00335
00336 delete msg;
00337 break;
00338 case REMOVE_TRIGGER:
00339 I3RemoveTriggerMessage *rmsg;
00340
00341 rmsg = check_and_cast<I3RemoveTriggerMessage*>(i3msg);
00342 removeTrigger(rmsg->getTrigger());
00343 delete msg;
00344 break;
00345 case SEND_PACKET:
00346 I3SendPacketMessage *smsg;
00347
00348 smsg = check_and_cast<I3SendPacketMessage*>(i3msg);
00349 sendPacket(smsg);
00350
00351 break;
00352 default:
00353 delete msg;
00354 break;
00355 }
00356 }
00357
00358 int I3::numInitStages() const
00359 {
00360 return MIN_STAGE_APP + 1;
00361 }
00362
00363 void I3::initializeApp(int stage)
00364 {
00365 if (stage != MIN_STAGE_APP)
00366 return;
00367
00368 numDroppedPackets = 0;
00369 WATCH(numDroppedPackets);
00370 byteDroppedPackets = 0;
00371 WATCH(byteDroppedPackets);
00372
00373 numForwardedPackets = 0;
00374 numForwardedBytes = 0;
00375
00376 WATCH(numForwardedPackets);
00377 WATCH(numForwardedBytes);
00378
00379 triggerTimeToLive = par("triggerTimeToLive");
00380 WATCH(triggerTimeToLive);
00381
00382 expirationTimer = new cMessage("expiration timer");
00383 scheduleAt(simTime() + triggerTimeToLive, expirationTimer);
00384
00385 getDisplayString() = "i=i3";
00386
00387 thisNode.setPort(par("serverPort"));
00388 bindToPort(thisNode.getPort());
00389
00390 }
00391
00392 void I3::handleTimerEvent(cMessage* msg)
00393 {
00394 bool updateString = false;
00395
00396 if (msg == expirationTimer) {
00397 scheduleAt(simTime() + triggerTimeToLive, expirationTimer);
00398
00399 for (I3TriggerTable::iterator it = triggerTable.begin(); it != triggerTable.end(); it++) {
00400 set<I3Trigger> &triggerSet = it->second;
00401 for (set<I3Trigger>::const_iterator sit = triggerSet.begin(); sit != triggerSet.end(); sit++) {
00402
00403 if (simTime() - sit->getInsertionTime() > triggerTimeToLive) {
00404
00405
00406
00407
00408 triggerSet.erase(sit);
00409 updateString = true;
00410 }
00411 }
00412 if (it->second.size() == 0) {
00413 triggerTable.erase(it);
00414 }
00415 }
00416 if (updateString) updateTriggerTableString();
00417 } else delete msg;
00418 }
00419
00420 void I3::updateTriggerTableString()
00421 {
00422 TriggerTable *table = check_and_cast<TriggerTable*>(getParentModule()->getSubmodule("triggerTable"));
00423 table->updateDisplayString();
00424 }
00425
00426 I3TriggerTable &I3::getTriggerTable()
00427 {
00428 return triggerTable;
00429 }
00430
00431 void I3::finish()
00432 {
00433 recordScalar("I3 Packets dropped", numDroppedPackets);
00434 recordScalar("I3 Bytes dropped", byteDroppedPackets);
00435 }