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.

00358 {
00359     return MIN_STAGE_APP + 1;
00360 }

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

Actual initialization function.

Parameters:
stage Actual stage

Reimplemented from BaseApp.

Reimplemented in I3TRTServer.

00363 {
00364     if ( stage != MIN_STAGE_APP )
00365         return;
00366 
00367     numDroppedPackets = 0;
00368     WATCH(numDroppedPackets);
00369     byteDroppedPackets = 0;
00370     WATCH(byteDroppedPackets);
00371 
00372     numForwardedPackets = 0;
00373     numForwardedBytes = 0;
00374 
00375     WATCH(numForwardedPackets);
00376     WATCH(numForwardedBytes);
00377 
00378 
00379     triggerTimeToLive = par("triggerTimeToLive");
00380     WATCH(triggerTimeToLive);
00381 
00382     expirationTimer = new cMessage("expiration timer");
00383     scheduleAt(simulation.simTime() + triggerTimeToLive, expirationTimer);
00384 
00385     displayString() = "i=i3";
00386 
00387     /* bind to par("serverPort") */
00388 //     cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00389 //     UDPControlInfo *ctrl = new UDPControlInfo();
00390 //     ctrl->setSrcPort(par("serverPort"));
00391 //     ctrl->setSockId(UDPSocket::generateSocketId());
00392 //     msg->setControlInfo(ctrl);
00393 //     send(msg, "to_udp");
00394     bindToPort(par("serverPort"));
00395 
00396 }

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.

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

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

Handles a message from UDP.

Parameters:
msg Incoming message

Reimplemented from BaseApp.

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

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

Handles timers.

Parameters:
msg Timer

Reimplemented from BaseApp.

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

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

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.

00231 {
00232     numForwardedPackets++;
00233     numForwardedBytes += (*msg)->length();
00234 
00235     BaseApp::forward(key, msg, hint);
00236 }

void I3::updateTriggerTableString (  )  [protected]

Updates TriggerTable's module display string.

00427 {
00428     TriggerTable *table = check_and_cast<TriggerTable*>(parentModule()->submodule("triggerTable"));
00429     table->updateDisplayString();
00430 }

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

collects statistical data

Reimplemented from BaseApp.

Reimplemented in I3TRTServer.

00438 {
00439     recordScalar("I3 Packets dropped", numDroppedPackets);
00440     recordScalar("I3 Bytes dropped", byteDroppedPackets);
00441 }

I3TriggerTable & I3::getTriggerTable (  ) 

Returns the table of inserted triggers.

00433 {
00434     return triggerTable;
00435 }

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

void I3::insertTrigger ( I3Trigger t  ) 

Inserts a trigger into I3.

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

void I3::removeTrigger ( I3Trigger t  ) 

Removes a trigger from I3.

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

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

void I3::sendToNode ( I3SendPacketMessage imsg  ) 

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

Parameters:
imsg Message to be sent
00137 {
00138     I3IPAddress address;
00139     /* re-route message to a client node */
00140     address = imsg->getIdentifierStack().peek().getIPAddress();
00141     imsg->getIdentifierStack().pop(); // pop ip address
00142     sendMessageToUDP(imsg, address);
00143 }


Member Data Documentation

int I3::numDroppedPackets [protected]

Number of dropped packets.

int I3::byteDroppedPackets [protected]

int I3::numForwardedPackets [protected]

int I3::numForwardedBytes [protected]

int I3::triggerTimeToLive [protected]

Time before inserted triggers expire.

I3TriggerTable I3::triggerTable [protected]

Table containing inserted triggers.

cMessage* I3::expirationTimer [protected]

Timer to check for trigger expiration.


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:29 2008 for ITM OverSim by  doxygen 1.5.3