I3 Class Reference

Main Omnet module for the implementation of Internet Indirection Infrastructure. More...

#include <I3.h>

Inheritance diagram for I3:
BaseApp BaseRpc RpcListener I3TRTServer

List of all members.

Public Member Functions

I3TriggerTablegetTriggerTable ()
 Returns the table of inserted triggers.
const I3IdentifierfindClosestMatch (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.

Detailed Description

Main Omnet module for the implementation of Internet Indirection Infrastructure.

Definition at line 46 of file I3.h.


Member Function Documentation

void I3::deliver ( OverlayKey key,
cMessage *  msg 
) [protected, virtual]

Delivers a packet from the overlay.

Parameters:
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)

Parameters:
t Identifier to be matchesd
Returns:
Pointer to the biggest prefix match, or NULL if none was found

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

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
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).

Parameters:
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).

Parameters:
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).

Parameters:
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 }


Member Data Documentation

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().

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().


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:17 2010 for OverSim by  doxygen 1.6.3