Main Omnet module for the implementation of Internet Indirection Infrastructure. More...
#include <I3.h>
Public Member Functions | |
I3TriggerTable & | getTriggerTable () |
Returns the table of inserted triggers. | |
const I3Identifier * | findClosestMatch (const I3Identifier &t) const |
Finds the closest match to t from the stored trigger identifiers. | |
void | insertTrigger (I3Trigger &t) |
Inserts a trigger into I3. | |
void | removeTrigger (I3Trigger &t) |
Removes a trigger from I3. | |
void | sendPacket (I3SendPacketMessage *msg) |
Sends a packet through I3. | |
void | sendToNode (I3SendPacketMessage *imsg) |
Sends packet to matching IP address (used by sendPacket). | |
Protected Member Functions | |
int | numInitStages () const |
Returns number of required init stages. | |
virtual void | initializeApp (int stage) |
Actual initialization function. | |
virtual void | deliver (OverlayKey &key, cMessage *msg) |
Delivers a packet from the overlay. | |
virtual void | handleUDPMessage (cMessage *msg) |
Handles a message from UDP. | |
virtual void | handleTimerEvent (cMessage *msg) |
Handles timers. | |
void | sendQueryReply (const I3Identifier &id, const I3IPAddress &add) |
Replies to a query of which server is responsible for the given identifier (this server). | |
virtual void | forward (OverlayKey *key, cPacket **msg, NodeHandle *nextHopNode) |
Common API function: handles messages from overlay to be forwarded. | |
void | updateTriggerTableString () |
Updates TriggerTable's module display string. | |
virtual void | finish () |
collects statistical data | |
Protected Attributes | |
int | numDroppedPackets |
Number of dropped packets. | |
int | byteDroppedPackets |
int | numForwardedPackets |
int | numForwardedBytes |
int | triggerTimeToLive |
Time before inserted triggers expire. | |
I3TriggerTable | triggerTable |
Table containing inserted triggers. | |
cMessage * | expirationTimer |
Timer to check for trigger expiration. |
Main Omnet module for the implementation of Internet Indirection Infrastructure.
Definition at line 46 of file I3.h.
void I3::deliver | ( | OverlayKey & | key, | |
cMessage * | msg | |||
) | [protected, virtual] |
Delivers a packet from the overlay.
key | Key from the overlay | |
msg | Message to deliver |
Reimplemented from BaseApp.
Reimplemented in I3TRTServer.
Definition at line 314 of file I3.cc.
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 }
const I3Identifier * I3::findClosestMatch | ( | const I3Identifier & | t | ) | const |
Finds the closest match to t from the stored trigger identifiers.
Note that, in the case that there are many biggest prefix matches, it will only return the first one (bug! - couldn't find efficient way to do)
t | Identifier to be matchesd |
Definition at line 63 of file I3.cc.
Referenced by sendPacket().
00064 { 00065 int prevDist = 0, nextDist = 0; 00066 00067 00068 if (triggerTable.size() == 0) return 0; 00069 00070 /* find the closest identifier to t */ 00071 /* if no match exists, it gets the next identifier with a bigger key */ 00072 I3TriggerTable::const_iterator it = triggerTable.lower_bound(t); 00073 00074 if (it == triggerTable.end()) { 00075 it--; // if at the end, check last 00076 } 00077 00078 if (it->first == t) return &it->first; // if we found an exact match, no need to bother 00079 00080 if (it != triggerTable.begin()) { // if no smaller keys, begin() is the candidate itself 00081 00082 /* no exact match, check which is closer: */ 00083 /* either where the iterator points to (the next biggest) or the previous one. */ 00084 /* see I3Identifier::distanceTo for distance definition */ 00085 00086 nextDist = it->first.distanceTo(t); 00087 it--; 00088 prevDist = it->first.distanceTo(t); 00089 00090 // if the next one is closest, put iterator back in place 00091 if (nextDist < prevDist) { 00092 it++; 00093 } 00094 } 00095 00096 /* now check if they match in the I3 sense (first prefixLength bits) */ 00097 return (it->first.isMatch(t)) ? &it->first : 0; 00098 }
void I3::finish | ( | ) | [protected, virtual] |
collects statistical data
Reimplemented from BaseApp.
Reimplemented in I3TRTServer.
Definition at line 431 of file I3.cc.
00432 { 00433 recordScalar("I3 Packets dropped", numDroppedPackets); 00434 recordScalar("I3 Bytes dropped", byteDroppedPackets); 00435 }
void I3::forward | ( | OverlayKey * | key, | |
cPacket ** | msg, | |||
NodeHandle * | nextHopNode | |||
) | [protected, virtual] |
Common API function: handles messages from overlay to be forwarded.
method to handle decapsulated KBRdeliver messages from overlay module, should be overwritten in derived application if needed
key | destination key | |
msg | message to forward | |
nextHopNode | next hop |
Reimplemented from BaseApp.
Definition at line 231 of file I3.cc.
00232 { 00233 numForwardedPackets++; 00234 numForwardedBytes += (*msg)->getByteLength(); 00235 00236 BaseApp::forward(key, msg, hint); 00237 }
I3TriggerTable & I3::getTriggerTable | ( | ) |
Returns the table of inserted triggers.
Definition at line 426 of file I3.cc.
Referenced by TriggerTable::initialize().
00427 { 00428 return triggerTable; 00429 }
void I3::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
Handles timers.
msg | Timer |
Reimplemented from BaseRpc.
Definition at line 392 of file I3.cc.
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 //cout << "Trigger " << *sit << " has 00403 if (simTime() - sit->getInsertionTime() > triggerTimeToLive) { 00404 //if ((bool)par("debugOutput")) { 00405 // cout << "Erasing trigger " << *sit << " in " << 00406 // thisNode.getAddress()<< ", insertion time is " << sit->getInsertionTime()<< endl; 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 }
void I3::handleUDPMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Handles a message from UDP.
msg | Incoming message |
Reimplemented from BaseApp.
Definition at line 240 of file I3.cc.
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 /* if ((imsg->getSource().address.d[0] & 0xff) == 56) { 00263 cout << "UDP Server " << thisNode.getAddress()<< " trigger " << imsg->getTrigger() << " key " << key << endl; 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 /* got an empty identifier stack - nothing to do */ 00282 delete msg; 00283 return; 00284 } 00285 I3SubIdentifier &subId = smsg->getIdentifierStack().peek(); 00286 if (subId.getType() == I3SubIdentifier::IPAddress) { 00287 /* why didn't they send it directly?! */ 00288 sendToNode(smsg); 00289 } else { 00290 key = subId.getIdentifier().asOverlayKey(); 00291 callRoute(key, smsg); 00292 } 00293 break; 00294 } 00295 default: 00296 /* should't happen */ 00297 delete msg; 00298 break; 00299 } 00300 }
void I3::initializeApp | ( | int | stage | ) | [protected, virtual] |
Actual initialization function.
stage | Actual stage |
Reimplemented from BaseApp.
Reimplemented in I3TRTServer.
Definition at line 363 of file I3.cc.
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 }
void I3::insertTrigger | ( | I3Trigger & | t | ) |
Inserts a trigger into I3.
t | Trigger to be inserted |
Definition at line 100 of file I3.cc.
Referenced by deliver().
00101 { 00102 00103 if (t.getIdentifierStack().size() == 0) { 00104 /* don't bother */ 00105 cout << "Warning: Got trigger " << t << " with size 0 in " << thisNode.getAddress()<< endl; 00106 return; 00107 } 00108 00109 t.setInsertionTime(simTime()); 00110 00111 /* insert packet in triggerTable; */ 00112 /* if it was already there, remove and insert updated copy */ 00113 00114 triggerTable[t.getIdentifier()].erase(t); 00115 triggerTable[t.getIdentifier()].insert(t); 00116 00117 updateTriggerTableString(); 00118 }
int I3::numInitStages | ( | ) | const [protected] |
Returns number of required init stages.
Reimplemented from BaseApp.
Definition at line 358 of file I3.cc.
00359 { 00360 return MIN_STAGE_APP + 1; 00361 }
void I3::removeTrigger | ( | I3Trigger & | t | ) |
Removes a trigger from I3.
t | Trigger to be removed |
Definition at line 120 of file I3.cc.
Referenced by deliver().
00121 { 00122 00123 //cout << "Removing trigger at " << getId() << endl; 00124 //getParentModule()->getParentModule()->bubble("Removing trigger"); 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 }
void I3::sendPacket | ( | I3SendPacketMessage * | msg | ) |
Sends a packet through I3.
It checks the trigger table for triggers matching the message's first I3SubIdentifier from the stack. If none are found, the subidentifier is dropped and the packet is routed based on the next remaining one (if no subidentifiers remain, the packet itself is dropped). The matching trigger's own subidentifier stack is then appended to the message stack, and then routed to the first subidentifier of the resulting stack (or sent through UDP if it's an IP address).
msg | Message to be sent |
Definition at line 146 of file I3.cc.
Referenced by deliver().
00147 { 00148 00149 I3IdentifierStack &idStack = msg->getIdentifierStack(); 00150 00151 if (idStack.size() == 0) { 00152 /* no identifiers left! drop packet */ 00153 /* shouldn't happen (how'd it get here anyway?) */ 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 /* shouldn't happen (how'd they find us anyway?) but just in case */ 00164 sendToNode(msg); 00165 } else { 00166 00167 /* if we were asked to reply, send it now */ 00168 if (msg->getSendReply()) { 00169 sendQueryReply(id.getIdentifier(), msg->getSource()); 00170 } 00171 00172 const I3Identifier *i3id = findClosestMatch(id.getIdentifier()); 00173 00174 /* eliminate top of the stack */ 00175 idStack.pop(); 00176 00177 if (!i3id) { 00178 /* no matching ids found in this server, re-route to next id */ 00179 if (idStack.size() == 0) { 00180 /* no identifiers left! drop packet */ 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)); /* stack size changed, recalculate */ 00188 if (idStack.peek().getType() == I3SubIdentifier::IPAddress) { 00189 msg->getMatchedTrigger().clear(); // not trigger, but direct IP match 00190 sendToNode(msg); 00191 } else { 00192 OverlayKey key = idStack.peek().getIdentifier().asOverlayKey(); 00193 callRoute(key, msg); 00194 } 00195 } 00196 00197 } else { 00198 /* some id found, send to all friends */ 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); /* create copy */ 00208 newMsg->getIdentifierStack().push(it->getIdentifierStack()); /* append our stuff to the top of the stack */ 00209 dupMsg = check_and_cast<cPacket*>(msg->getEncapsulatedPacket()->dup()); /* dup msg */ 00210 newMsg->setBitLength(SEND_PACKET_L(newMsg)); /* stack size changed, recalculate */ 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 /* copies sent, erase original */ 00225 delete msg; 00226 00227 } 00228 } 00229 }
void I3::sendQueryReply | ( | const I3Identifier & | id, | |
const I3IPAddress & | add | |||
) | [protected] |
Replies to a query of which server is responsible for the given identifier (this server).
id | I3 identifier of the query | |
add | IP address of requester |
Definition at line 302 of file I3.cc.
Referenced by deliver(), and sendPacket().
00302 { 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 }
void I3::sendToNode | ( | I3SendPacketMessage * | imsg | ) |
Sends packet to matching IP address (used by sendPacket).
imsg | Message to be sent |
Definition at line 137 of file I3.cc.
Referenced by handleUDPMessage(), and sendPacket().
00138 { 00139 I3IPAddress address; 00140 /* re-route message to a client node */ 00141 address = imsg->getIdentifierStack().peek().getIPAddress(); 00142 imsg->getIdentifierStack().pop(); // pop ip address 00143 sendMessageToUDP(address, imsg); 00144 }
void I3::updateTriggerTableString | ( | ) | [protected] |
Updates TriggerTable's module display string.
Definition at line 420 of file I3.cc.
Referenced by handleTimerEvent(), insertTrigger(), and removeTrigger().
00421 { 00422 TriggerTable *table = check_and_cast<TriggerTable*>(getParentModule()->getSubmodule("triggerTable")); 00423 table->updateDisplayString(); 00424 }
int I3::byteDroppedPackets [protected] |
Definition at line 51 of file I3.h.
Referenced by finish(), initializeApp(), and sendPacket().
cMessage* I3::expirationTimer [protected] |
Timer to check for trigger expiration.
Definition at line 63 of file I3.h.
Referenced by handleTimerEvent(), and initializeApp().
int I3::numDroppedPackets [protected] |
Number of dropped packets.
Definition at line 50 of file I3.h.
Referenced by finish(), initializeApp(), and sendPacket().
int I3::numForwardedBytes [protected] |
Definition at line 54 of file I3.h.
Referenced by forward(), and initializeApp().
int I3::numForwardedPackets [protected] |
Definition at line 53 of file I3.h.
Referenced by forward(), and initializeApp().
I3TriggerTable I3::triggerTable [protected] |
Table containing inserted triggers.
Definition at line 60 of file I3.h.
Referenced by findClosestMatch(), getTriggerTable(), handleTimerEvent(), insertTrigger(), removeTrigger(), and sendPacket().
int I3::triggerTimeToLive [protected] |
Time before inserted triggers expire.
Definition at line 57 of file I3.h.
Referenced by handleTimerEvent(), and initializeApp().