Public Member Functions | Protected Member Functions | Protected Attributes

I3 Class Reference

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

#include <I3.h>

Inheritance diagram for I3:
BaseApp BaseRpc BaseTcpSupport 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.

{
    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)

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

{
    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

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

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

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

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

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

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

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

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

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

Parameters:
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();
}


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: