I3 Class Reference

#include <I3.h>

Inheritance diagram for I3:

BaseApp BaseRpc RpcListener I3TRTServer

List of all members.


Detailed Description

Main Omnet module for the implementation of Internet Indirection Infrastructure.

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, cMessage **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.

Member Function Documentation

int I3::numInitStages (  )  const [protected]

Returns number of required init stages.

Reimplemented from BaseApp.

00356 {
00357     return MIN_STAGE_APP + 1;
00358 }

void I3::initializeApp ( int  stage  )  [protected, virtual]

Actual initialization function.

Parameters:
stage Actual stage

Reimplemented from BaseApp.

Reimplemented in I3TRTServer.

Referenced by I3TRTServer::initializeApp().

00361 {
00362     if (stage != MIN_STAGE_APP)
00363         return;
00364 
00365     numDroppedPackets = 0;
00366     WATCH(numDroppedPackets);
00367     byteDroppedPackets = 0;
00368     WATCH(byteDroppedPackets);
00369 
00370     numForwardedPackets = 0;
00371     numForwardedBytes = 0;
00372 
00373     WATCH(numForwardedPackets);
00374     WATCH(numForwardedBytes);
00375 
00376     triggerTimeToLive = par("triggerTimeToLive");
00377     WATCH(triggerTimeToLive);
00378 
00379     expirationTimer = new cMessage("expiration timer");
00380     scheduleAt(simulation.simTime() + triggerTimeToLive, expirationTimer);
00381 
00382     displayString() = "i=i3";
00383 
00384     thisNode.port = par("serverPort");
00385     bindToPort(thisNode.port);
00386 
00387 }

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.

Referenced by I3TRTServer::deliver().

00312 {
00313     I3Message *i3msg;
00314 
00315     i3msg = dynamic_cast<I3Message*>(msg);
00316     if (!i3msg) {
00317         cout << "Delivered non I3 Message!" << endl;
00318         delete msg;
00319         return;
00320     }
00321 
00322     switch (i3msg->getType()) {
00323     case INSERT_TRIGGER:
00324         I3InsertTriggerMessage *imsg;
00325 
00326         imsg = check_and_cast<I3InsertTriggerMessage*>(i3msg);
00327         insertTrigger(imsg->getTrigger());
00328 
00329         if (imsg->getSendReply()) {
00330             sendQueryReply(imsg->getTrigger().getIdentifier(), imsg->getSource());
00331         }
00332 
00333         delete msg;
00334         break;
00335     case REMOVE_TRIGGER:
00336         I3RemoveTriggerMessage *rmsg;
00337 
00338         rmsg = check_and_cast<I3RemoveTriggerMessage*>(i3msg);
00339         removeTrigger(rmsg->getTrigger());
00340         delete msg;
00341         break;
00342     case SEND_PACKET:
00343         I3SendPacketMessage *smsg;
00344 
00345         smsg = check_and_cast<I3SendPacketMessage*>(i3msg);
00346         sendPacket(smsg);
00347 
00348         break;
00349     default:
00350         delete msg;
00351         break;
00352     }
00353 }

void I3::handleUDPMessage ( cMessage *  msg  )  [protected, virtual]

Handles a message from UDP.

Parameters:
msg Incoming message

Reimplemented from BaseApp.

00238 {
00239     I3Message *i3msg;
00240 
00241     i3msg = dynamic_cast<I3Message*>(msg);
00242 
00243     if (!i3msg) {
00244         delete msg;
00245         return;
00246     }
00247 
00248     OverlayKey key;
00249 
00250     msg->removeControlInfo();
00251     switch (i3msg->getType()) {
00252     case INSERT_TRIGGER:
00253         I3InsertTriggerMessage *imsg;
00254 
00255         imsg = check_and_cast<I3InsertTriggerMessage*>(i3msg);
00256         key = imsg->getTrigger().getIdentifier().asOverlayKey();
00257         callRoute(key, imsg);
00258 
00259         /*            if ((imsg->getSource().address.d[0] & 0xff) == 56) {
00260                     cout << "UDP Server " << thisNode.ip << " trigger " << imsg->getTrigger() << " key " << key << endl;
00261             }*/
00262 
00263         break;
00264     case REMOVE_TRIGGER:
00265         I3RemoveTriggerMessage *rmsg;
00266 
00267         rmsg = check_and_cast<I3RemoveTriggerMessage*>(i3msg);
00268         key = rmsg->getTrigger().getIdentifier().asOverlayKey();
00269         callRoute(key, rmsg);
00270 
00271         break;
00272     case SEND_PACKET:
00273     {
00274         I3SendPacketMessage *smsg;
00275 
00276         smsg = check_and_cast<I3SendPacketMessage*>(i3msg);
00277         if (smsg->getIdentifierStack().size() == 0) {
00278             /* got an empty identifier stack - nothing to do */
00279             delete msg;
00280             return;
00281         }
00282         I3SubIdentifier &subId = smsg->getIdentifierStack().peek();
00283         if (subId.getType() == I3SubIdentifier::IPAddress) {
00284             /* why didn't they send it directly?! */
00285             sendToNode(smsg);
00286         } else {
00287             key = subId.getIdentifier().asOverlayKey();
00288             callRoute(key, smsg);
00289         }
00290         break;
00291     }
00292     default:
00293         /* should't happen */
00294         delete msg;
00295         break;
00296     }
00297 }

void I3::handleTimerEvent ( cMessage *  msg  )  [protected, virtual]

Handles timers.

Parameters:
msg Timer

Reimplemented from BaseApp.

00390 {
00391     bool updateString = false;
00392 
00393     if (msg == expirationTimer) {
00394         scheduleAt(simulation.simTime() + triggerTimeToLive, expirationTimer);
00395 
00396         for (I3TriggerTable::iterator it = triggerTable.begin(); it != triggerTable.end(); it++) {
00397             set<I3Trigger> &triggerSet = it->second;
00398             for (set<I3Trigger>::const_iterator sit = triggerSet.begin(); sit != triggerSet.end(); sit++) {
00399                 //cout << "Trigger " << *sit << " has
00400                 if (simulation.simTime() - sit->getInsertionTime() > triggerTimeToLive) {
00401                     //if ((bool)par("debugOutput")) {
00402                     //  cout << "Erasing trigger " << *sit << " in " <<
00403                     //          thisNode.ip << ", insertion time is " << sit->getInsertionTime()<< endl;
00404                     //}
00405                     triggerSet.erase(sit);
00406                     updateString = true;
00407                 }
00408             }
00409             if (it->second.size() == 0) {
00410                 triggerTable.erase(it);
00411             }
00412         }
00413         if (updateString) updateTriggerTableString();
00414     } else delete msg;
00415 }

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

Referenced by deliver(), and sendPacket().

00299                                                                       {
00300     I3QueryReplyMessage *pmsg;
00301     I3IPAddress myAddress(thisNode.ip, par("serverPort"));
00302 
00303     pmsg = new I3QueryReplyMessage();
00304     pmsg->setSource(myAddress);
00305     pmsg->setSendingTime(simulation.simTime());
00306     pmsg->setIdentifier(id);
00307     pmsg->setLength(QUERY_REPLY_L(pmsg));
00308     sendMessageToUDP(pmsg, add);
00309 }

void I3::forward ( OverlayKey key,
cMessage **  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.

00229 {
00230     numForwardedPackets++;
00231     numForwardedBytes += (*msg)->byteLength();
00232 
00233     BaseApp::forward(key, msg, hint);
00234 }

void I3::updateTriggerTableString (  )  [protected]

Updates TriggerTable's module display string.

Referenced by handleTimerEvent(), insertTrigger(), and removeTrigger().

00418 {
00419     TriggerTable *table = check_and_cast<TriggerTable*>(parentModule()->submodule("triggerTable"));
00420     table->updateDisplayString();
00421 }

void I3::finish (  )  [protected, virtual]

collects statistical data

Reimplemented from BaseApp.

Reimplemented in I3TRTServer.

00429 {
00430     recordScalar("I3 Packets dropped", numDroppedPackets);
00431     recordScalar("I3 Bytes dropped", byteDroppedPackets);
00432 }

I3TriggerTable & I3::getTriggerTable (  ) 

Returns the table of inserted triggers.

Referenced by TriggerTable::initialize().

00424 {
00425     return triggerTable;
00426 }

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

Referenced by sendPacket().

00061 {
00062     int prevDist = 0, nextDist = 0;
00063 
00064 
00065     if (triggerTable.size() == 0) return 0;
00066 
00067     /* find the closest identifier to t */
00068     /* if no match exists, it gets the next identifier with a bigger key */
00069     I3TriggerTable::const_iterator it = triggerTable.lower_bound(t);
00070 
00071     if (it == triggerTable.end()) {
00072         it--;               // if at the end, check last
00073     }
00074 
00075     if (it->first == t) return &it->first; // if we found an exact match, no need to bother
00076 
00077     if (it != triggerTable.begin()) { // if no smaller keys, begin() is the candidate itself
00078 
00079         /* no exact match, check which is closer: */
00080         /* either where the iterator points to (the next biggest) or the previous one. */
00081         /* see I3Identifier::distanceTo for distance definition */
00082 
00083         nextDist = it->first.distanceTo(t);
00084         it--;
00085         prevDist = it->first.distanceTo(t);
00086 
00087         // if the next one is closest, put iterator back in place
00088         if (nextDist < prevDist) {
00089             it++;
00090         }
00091     }
00092 
00093     /* now check if they match in the I3 sense (first prefixLength bits) */
00094     return (it->first.isMatch(t)) ? &it->first : 0;
00095 }

void I3::insertTrigger ( I3Trigger t  ) 

Inserts a trigger into I3.

Parameters:
t Trigger to be inserted

Referenced by deliver().

00098 {
00099 
00100     if (t.getIdentifierStack().size() == 0) {
00101         /* don't bother */
00102         cout << "Warning: Got trigger " << t << " with size 0 in " << thisNode.ip << endl;
00103         return;
00104     }
00105 
00106     t.setInsertionTime(simulation.simTime());
00107 
00108     /* insert packet in triggerTable; */
00109     /* if it was already there, remove and insert updated copy */
00110 
00111     triggerTable[t.getIdentifier()].erase(t);
00112     triggerTable[t.getIdentifier()].insert(t);
00113 
00114     updateTriggerTableString();
00115 }

void I3::removeTrigger ( I3Trigger t  ) 

Removes a trigger from I3.

Parameters:
t Trigger to be removed

Referenced by deliver().

00118 {
00119 
00120     //cout << "Removing trigger at " << id() << endl;
00121     //parentModule()->parentModule()->bubble("Removing trigger");
00122 
00123     if (triggerTable.count(t.getIdentifier()) == 0) return;
00124 
00125     set<I3Trigger> &s = triggerTable[t.getIdentifier()];
00126 
00127     s.erase(t);
00128 
00129     if (s.size() == 0) triggerTable.erase(t.getIdentifier());
00130 
00131     updateTriggerTableString();
00132 }

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

Referenced by deliver().

00144 {
00145 
00146     I3IdentifierStack &idStack = msg->getIdentifierStack();
00147 
00148     if (idStack.size() == 0) {
00149         /* no identifiers left! drop packet */
00150         /* shouldn't happen (how'd it get here anyway?) */
00151         numDroppedPackets++;
00152         byteDroppedPackets += msg->length();
00153         delete msg;
00154         return;
00155     }
00156 
00157     I3SubIdentifier id = idStack.peek();
00158 
00159     if (id.getType() == I3SubIdentifier::IPAddress) {
00160         /* shouldn't happen (how'd they find us anyway?) but just in case */
00161         sendToNode(msg);
00162     } else {
00163 
00164         /* if we were asked to reply, send it now */
00165         if (msg->getSendReply()) {
00166             sendQueryReply(id.getIdentifier(), msg->getSource());
00167         }
00168 
00169         const I3Identifier *i3id = findClosestMatch(id.getIdentifier());
00170 
00171         /* eliminate top of the stack */
00172         idStack.pop();
00173 
00174         if (!i3id) {
00175             /* no matching ids found in this server, re-route to next id */
00176             if (idStack.size() == 0) {
00177                 /* no identifiers left! drop packet */
00178                 numDroppedPackets++;
00179                 byteDroppedPackets += msg->length();
00180                 cout << "Dropped packet at" << thisNode.ip << " to unknown id " << id.getIdentifier() << endl;
00181                 delete msg;
00182                 return;
00183             } else {
00184                 msg->setLength(SEND_PACKET_L(msg)); /* stack size changed, recalculate */
00185                 if (idStack.peek().getType() == I3SubIdentifier::IPAddress) {
00186                     msg->getMatchedTrigger().clear(); // not trigger, but direct IP match
00187                     sendToNode(msg);
00188                 } else {
00189                     OverlayKey key = idStack.peek().getIdentifier().asOverlayKey();
00190                     callRoute(key, msg);
00191                 }
00192             }
00193 
00194         } else {
00195             /* some id found, send to all friends */
00196             set<I3Trigger> &s = triggerTable[*i3id];
00197             set<I3Trigger>::iterator it;
00198 
00199             for (it = s.begin(); it != s.end(); it++) {
00200                 I3SendPacketMessage *newMsg;
00201                 cMessage *dupMsg;
00202 
00203                 newMsg = new I3SendPacketMessage();
00204                 newMsg->setIdentifierStack(idStack); /* create copy */
00205                 newMsg->getIdentifierStack().push(it->getIdentifierStack()); /* append our stuff to the top of the stack */
00206                 dupMsg = check_and_cast<cMessage*>(msg->encapsulatedMsg()->dup()); /* dup msg */
00207                 newMsg->setLength(SEND_PACKET_L(newMsg)); /* stack size changed, recalculate */
00208                 newMsg->encapsulate(dupMsg);
00209 
00210                 I3SubIdentifier &top = newMsg->getIdentifierStack().peek();
00211 
00212                 if (top.getType() == I3SubIdentifier::IPAddress) {
00213                     newMsg->setMatchedTrigger(*it);
00214                     sendToNode(newMsg);
00215                 } else {
00216                     OverlayKey key = top.getIdentifier().asOverlayKey();
00217                     callRoute(key, newMsg);
00218                 }
00219             }
00220 
00221             /* copies sent, erase original */
00222             delete msg;
00223 
00224         }
00225     }
00226 }

void I3::sendToNode ( I3SendPacketMessage imsg  ) 

Sends packet to matching IP address (used by sendPacket).

Parameters:
imsg Message to be sent

Referenced by handleUDPMessage(), and sendPacket().

00135 {
00136     I3IPAddress address;
00137     /* re-route message to a client node */
00138     address = imsg->getIdentifierStack().peek().getIPAddress();
00139     imsg->getIdentifierStack().pop(); // pop ip address
00140     sendMessageToUDP(imsg, address);
00141 }


Member Data Documentation

int I3::numDroppedPackets [protected]

Number of dropped packets.

Referenced by finish(), initializeApp(), and sendPacket().

int I3::byteDroppedPackets [protected]

Referenced by finish(), initializeApp(), and sendPacket().

int I3::numForwardedPackets [protected]

Referenced by forward(), and initializeApp().

int I3::numForwardedBytes [protected]

Referenced by forward(), and initializeApp().

int I3::triggerTimeToLive [protected]

Time before inserted triggers expire.

Referenced by handleTimerEvent(), and initializeApp().

Table containing inserted triggers.

Referenced by findClosestMatch(), getTriggerTable(), handleTimerEvent(), insertTrigger(), removeTrigger(), and sendPacket().

cMessage* I3::expirationTimer [protected]

Timer to check for trigger expiration.

Referenced by handleTimerEvent(), and initializeApp().


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:07 2008 for ITM OverSim by  doxygen 1.5.5