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.
{ I3Message *i3msg; i3msg = dynamic_cast<I3Message*>(msg); if (!i3msg) { cout << "Delivered non I3 Message!" << endl; delete msg; return; } switch (i3msg->getType()) { case INSERT_TRIGGER: I3InsertTriggerMessage *imsg; imsg = check_and_cast<I3InsertTriggerMessage*>(i3msg); insertTrigger(imsg->getTrigger()); if (imsg->getSendReply()) { sendQueryReply(imsg->getTrigger().getIdentifier(), imsg->getSource()); } delete msg; break; case REMOVE_TRIGGER: I3RemoveTriggerMessage *rmsg; rmsg = check_and_cast<I3RemoveTriggerMessage*>(i3msg); removeTrigger(rmsg->getTrigger()); delete msg; break; case SEND_PACKET: I3SendPacketMessage *smsg; smsg = check_and_cast<I3SendPacketMessage*>(i3msg); sendPacket(smsg); break; default: delete msg; break; } }
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().
{ int prevDist = 0, nextDist = 0; if (triggerTable.size() == 0) return 0; /* find the closest identifier to t */ /* if no match exists, it gets the next identifier with a bigger key */ I3TriggerTable::const_iterator it = triggerTable.lower_bound(t); if (it == triggerTable.end()) { it--; // if at the end, check last } if (it->first == t) return &it->first; // if we found an exact match, no need to bother if (it != triggerTable.begin()) { // if no smaller keys, begin() is the candidate itself /* no exact match, check which is closer: */ /* either where the iterator points to (the next biggest) or the previous one. */ /* see I3Identifier::distanceTo for distance definition */ nextDist = it->first.distanceTo(t); it--; prevDist = it->first.distanceTo(t); // if the next one is closest, put iterator back in place if (nextDist < prevDist) { it++; } } /* now check if they match in the I3 sense (first prefixLength bits) */ return (it->first.isMatch(t)) ? &it->first : 0; }
void I3::finish | ( | ) | [protected, virtual] |
collects statistical data
Reimplemented from BaseApp.
Reimplemented in I3TRTServer.
Definition at line 431 of file I3.cc.
{ recordScalar("I3 Packets dropped", numDroppedPackets); recordScalar("I3 Bytes dropped", byteDroppedPackets); }
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.
{ numForwardedPackets++; numForwardedBytes += (*msg)->getByteLength(); BaseApp::forward(key, msg, hint); }
I3TriggerTable & I3::getTriggerTable | ( | ) |
Returns the table of inserted triggers.
Definition at line 426 of file I3.cc.
Referenced by TriggerTable::initialize().
{ return triggerTable; }
void I3::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
Handles timers.
msg | Timer |
Definition at line 392 of file I3.cc.
{ bool updateString = false; if (msg == expirationTimer) { scheduleAt(simTime() + triggerTimeToLive, expirationTimer); for (I3TriggerTable::iterator it = triggerTable.begin(); it != triggerTable.end(); it++) { set<I3Trigger> &triggerSet = it->second; for (set<I3Trigger>::const_iterator sit = triggerSet.begin(); sit != triggerSet.end(); sit++) { //cout << "Trigger " << *sit << " has if (simTime() - sit->getInsertionTime() > triggerTimeToLive) { //if ((bool)par("debugOutput")) { // cout << "Erasing trigger " << *sit << " in " << // thisNode.getIp()<< ", insertion time is " << sit->getInsertionTime()<< endl; //} triggerSet.erase(sit); updateString = true; } } if (it->second.size() == 0) { triggerTable.erase(it); } } if (updateString) updateTriggerTableString(); } else delete msg; }
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.
{ I3Message *i3msg; i3msg = dynamic_cast<I3Message*>(msg); if (!i3msg) { delete msg; return; } OverlayKey key; msg->removeControlInfo(); switch (i3msg->getType()) { case INSERT_TRIGGER: I3InsertTriggerMessage *imsg; imsg = check_and_cast<I3InsertTriggerMessage*>(i3msg); key = imsg->getTrigger().getIdentifier().asOverlayKey(); callRoute(key, imsg); /* if ((imsg->getSource().address.d[0] & 0xff) == 56) { cout << "UDP Server " << thisNode.getIp()<< " trigger " << imsg->getTrigger() << " key " << key << endl; }*/ break; case REMOVE_TRIGGER: I3RemoveTriggerMessage *rmsg; rmsg = check_and_cast<I3RemoveTriggerMessage*>(i3msg); key = rmsg->getTrigger().getIdentifier().asOverlayKey(); callRoute(key, rmsg); break; case SEND_PACKET: { I3SendPacketMessage *smsg; smsg = check_and_cast<I3SendPacketMessage*>(i3msg); if (smsg->getIdentifierStack().size() == 0) { /* got an empty identifier stack - nothing to do */ delete msg; return; } I3SubIdentifier &subId = smsg->getIdentifierStack().peek(); if (subId.getType() == I3SubIdentifier::IPAddress) { /* why didn't they send it directly?! */ sendToNode(smsg); } else { key = subId.getIdentifier().asOverlayKey(); callRoute(key, smsg); } break; } default: /* should't happen */ delete msg; break; } }
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.
{ if (stage != MIN_STAGE_APP) return; numDroppedPackets = 0; WATCH(numDroppedPackets); byteDroppedPackets = 0; WATCH(byteDroppedPackets); numForwardedPackets = 0; numForwardedBytes = 0; WATCH(numForwardedPackets); WATCH(numForwardedBytes); triggerTimeToLive = par("triggerTimeToLive"); WATCH(triggerTimeToLive); expirationTimer = new cMessage("expiration timer"); scheduleAt(simTime() + triggerTimeToLive, expirationTimer); getDisplayString() = "i=i3"; thisNode.setPort(par("serverPort")); bindToPort(thisNode.getPort()); }
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().
{ if (t.getIdentifierStack().size() == 0) { /* don't bother */ cout << "Warning: Got trigger " << t << " with size 0 in " << thisNode.getIp()<< endl; return; } t.setInsertionTime(simTime()); /* insert packet in triggerTable; */ /* if it was already there, remove and insert updated copy */ triggerTable[t.getIdentifier()].erase(t); triggerTable[t.getIdentifier()].insert(t); updateTriggerTableString(); }
int I3::numInitStages | ( | ) | const [protected] |
Returns number of required init stages.
Reimplemented from BaseApp.
Definition at line 358 of file I3.cc.
{ return MIN_STAGE_APP + 1; }
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().
{ //cout << "Removing trigger at " << getId() << endl; //getParentModule()->getParentModule()->bubble("Removing trigger"); if (triggerTable.count(t.getIdentifier()) == 0) return; set<I3Trigger> &s = triggerTable[t.getIdentifier()]; s.erase(t); if (s.size() == 0) triggerTable.erase(t.getIdentifier()); updateTriggerTableString(); }
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().
{ I3IdentifierStack &idStack = msg->getIdentifierStack(); if (idStack.size() == 0) { /* no identifiers left! drop packet */ /* shouldn't happen (how'd it get here anyway?) */ numDroppedPackets++; byteDroppedPackets += msg->getBitLength(); delete msg; return; } I3SubIdentifier id = idStack.peek(); if (id.getType() == I3SubIdentifier::IPAddress) { /* shouldn't happen (how'd they find us anyway?) but just in case */ sendToNode(msg); } else { /* if we were asked to reply, send it now */ if (msg->getSendReply()) { sendQueryReply(id.getIdentifier(), msg->getSource()); } const I3Identifier *i3id = findClosestMatch(id.getIdentifier()); /* eliminate top of the stack */ idStack.pop(); if (!i3id) { /* no matching ids found in this server, re-route to next id */ if (idStack.size() == 0) { /* no identifiers left! drop packet */ numDroppedPackets++; byteDroppedPackets += msg->getBitLength(); cout << "Dropped packet at" << thisNode.getIp()<< " to unknown id " << id.getIdentifier() << endl; delete msg; return; } else { msg->setBitLength(SEND_PACKET_L(msg)); /* stack size changed, recalculate */ if (idStack.peek().getType() == I3SubIdentifier::IPAddress) { msg->getMatchedTrigger().clear(); // not trigger, but direct IP match sendToNode(msg); } else { OverlayKey key = idStack.peek().getIdentifier().asOverlayKey(); callRoute(key, msg); } } } else { /* some id found, send to all friends */ set<I3Trigger> &s = triggerTable[*i3id]; set<I3Trigger>::iterator it; for (it = s.begin(); it != s.end(); it++) { I3SendPacketMessage *newMsg; cPacket *dupMsg; newMsg = new I3SendPacketMessage(); newMsg->setIdentifierStack(idStack); /* create copy */ newMsg->getIdentifierStack().push(it->getIdentifierStack()); /* append our stuff to the top of the stack */ dupMsg = check_and_cast<cPacket*>(msg->getEncapsulatedPacket()->dup()); /* dup msg */ newMsg->setBitLength(SEND_PACKET_L(newMsg)); /* stack size changed, recalculate */ newMsg->encapsulate(dupMsg); I3SubIdentifier &top = newMsg->getIdentifierStack().peek(); if (top.getType() == I3SubIdentifier::IPAddress) { newMsg->setMatchedTrigger(*it); sendToNode(newMsg); } else { OverlayKey key = top.getIdentifier().asOverlayKey(); callRoute(key, newMsg); } } /* copies sent, erase original */ delete msg; } } }
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().
{ I3QueryReplyMessage *pmsg; I3IPAddress myAddress(thisNode.getIp(), par("serverPort")); pmsg = new I3QueryReplyMessage(); pmsg->setSource(myAddress); pmsg->setSendingTime(simTime()); pmsg->setIdentifier(id); pmsg->setBitLength(QUERY_REPLY_L(pmsg)); sendMessageToUDP(add, pmsg); }
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().
{ I3IPAddress address; /* re-route message to a client node */ address = imsg->getIdentifierStack().peek().getIPAddress(); imsg->getIdentifierStack().pop(); // pop ip address sendMessageToUDP(address, imsg); }
void I3::updateTriggerTableString | ( | ) | [protected] |
Updates TriggerTable's module display string.
Definition at line 420 of file I3.cc.
Referenced by handleTimerEvent(), insertTrigger(), and removeTrigger().
{ TriggerTable *table = check_and_cast<TriggerTable*>(getParentModule()->getSubmodule("triggerTable")); table->updateDisplayString(); }
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().