RSVP Class Reference

#include <RSVP.h>

Inheritance diagram for RSVP:

IScriptable List of all members.

Detailed Description

TODO documentation


Public Member Functions

 RSVP ()
virtual ~RSVP ()

Protected Member Functions

void processSignallingMessage (SignallingMsg *msg)
void processPSB_TIMER (PsbTimerMsg *msg)
void processPSB_TIMEOUT (PsbTimeoutMsg *msg)
void processRSB_REFRESH_TIMER (RsbRefreshTimerMsg *msg)
void processRSB_COMMIT_TIMER (RsbCommitTimerMsg *msg)
void processRSB_TIMEOUT (RsbTimeoutMsg *msg)
void processHELLO_TIMER (HelloTimerMsg *msg)
void processHELLO_TIMEOUT (HelloTimeoutMsg *msg)
void processPATH_NOTIFY (PathNotifyMsg *msg)
void processRSVPMessage (RSVPMessage *msg)
void processHelloMsg (RSVPHelloMsg *msg)
void processPathMsg (RSVPPathMsg *msg)
void processResvMsg (RSVPResvMsg *msg)
void processPathTearMsg (RSVPPathTear *msg)
void processPathErrMsg (RSVPPathError *msg)
PathStateBlock_tcreatePSB (RSVPPathMsg *msg)
PathStateBlock_tcreateIngressPSB (const traffic_session_t &session, const traffic_path_t &path)
void removePSB (PathStateBlock_t *psb)
ResvStateBlock_tcreateRSB (RSVPResvMsg *msg)
ResvStateBlock_tcreateEgressRSB (PathStateBlock_t *psb)
void updateRSB (ResvStateBlock_t *rsb, RSVPResvMsg *msg)
void removeRSB (ResvStateBlock_t *rsb)
void removeRsbFilter (ResvStateBlock_t *rsb, unsigned int index)
void refreshPath (PathStateBlock_t *psbEle)
void refreshResv (ResvStateBlock_t *rsbEle)
void refreshResv (ResvStateBlock_t *rsbEle, IPAddress PHOP)
void commitResv (ResvStateBlock_t *rsb)
void scheduleRefreshTimer (PathStateBlock_t *psbEle, double delay)
void scheduleTimeout (PathStateBlock_t *psbEle)
void scheduleRefreshTimer (ResvStateBlock_t *rsbEle, double delay)
void scheduleCommitTimer (ResvStateBlock_t *rsbEle)
void scheduleTimeout (ResvStateBlock_t *rsbEle)
void sendPathErrorMessage (PathStateBlock_t *psb, int errCode)
void sendPathErrorMessage (SessionObj_t session, SenderTemplateObj_t sender, SenderTspecObj_t tspec, IPAddress nextHop, int errCode)
void sendPathTearMessage (IPAddress peerIP, const SessionObj_t &session, const SenderTemplateObj_t &sender, IPAddress LIH, IPAddress NHOP, bool force)
void sendPathNotify (int handler, const SessionObj_t &session, const SenderTemplateObj_t &sender, int status, double delay)
void setupHello ()
void startHello (IPAddress peer, double delay)
void recoveryEvent (IPAddress peer)
bool allocateResource (IPAddress OI, const SessionObj_t &session, double bandwidth)
void preempt (IPAddress OI, int priority, double bandwidth)
bool doCACCheck (const SessionObj_t &session, const SenderTspecObj_t &tspec, IPAddress OI)
void announceLinkChange (int tedlinkindex)
void sendToIP (cMessage *msg, IPAddress destAddr)
bool evalNextHopInterface (IPAddress destAddr, const EroVector &ERO, IPAddress &OI)
PathStateBlock_tfindPSB (const SessionObj_t &session, const SenderTemplateObj_t &sender)
ResvStateBlock_tfindRSB (const SessionObj_t &session, const SenderTemplateObj_t &sender, unsigned int &index)
PathStateBlock_tfindPsbById (int id)
ResvStateBlock_tfindRsbById (int id)
std::vector< traffic_session_t
>::iterator 
findSession (const SessionObj_t &session)
std::vector< traffic_path_t
>::iterator 
findPath (traffic_session_t *session, const SenderTemplateObj_t &sender)
HelloState_tfindHello (IPAddress peer)
void print (RSVPPathMsg *p)
void print (RSVPResvMsg *r)
void readTrafficFromXML (const cXMLElement *traffic)
void readTrafficSessionFromXML (const cXMLElement *session)
EroVector readTrafficRouteFromXML (const cXMLElement *route)
void createPath (const SessionObj_t &session, const SenderTemplateObj_t &sender)
void pathProblem (PathStateBlock_t *psb)
void addSession (const cXMLElement &node)
void delSession (const cXMLElement &node)
virtual int numInitStages () const
virtual void initialize (int stage)
virtual void handleMessage (cMessage *msg)
virtual void processCommand (const cXMLElement &node)

Private Types

typedef std::vector< PathStateBlock_tPSBVector
typedef std::vector< ResvStateBlock_tRSBVector
typedef std::vector< HelloState_tHelloVector

Private Member Functions

int getInLabel (const SessionObj_t &session, const SenderTemplateObj_t &sender)

Private Attributes

std::vector< traffic_session_ttraffic
double helloInterval
double helloTimeout
double retryInterval
TEDtedmod
RoutingTablert
InterfaceTableift
LIBTablelt
NotificationBoardnb
IRSVPClassifierrpct
int maxPsbId
int maxRsbId
int maxSrcInstance
IPAddress routerId
PSBVector PSBList
RSBVector RSBList
HelloVector HelloList

Friends

class SimpleClassifier

Classes

struct  HelloState_t
struct  PathStateBlock_t
struct  ResvStateBlock_t
struct  traffic_path_t
struct  traffic_session_t


Member Typedef Documentation

typedef std::vector<HelloState_t> RSVP::HelloVector [private]

typedef std::vector<PathStateBlock_t> RSVP::PSBVector [private]

typedef std::vector<ResvStateBlock_t> RSVP::RSBVector [private]


Constructor & Destructor Documentation

RSVP::RSVP (  ) 

00042 {
00043 }

RSVP::~RSVP (  )  [virtual]

00046 {
00047     // TODO cancelAndDelete timers in all data structures
00048 }


Member Function Documentation

void RSVP::addSession ( const cXMLElement &  node  )  [protected]

01855 {
01856     Enter_Method_Silent();
01857 
01858     readTrafficSessionFromXML(&node);
01859 }

bool RSVP::allocateResource ( IPAddress  OI,
const SessionObj_t session,
double  bandwidth 
) [protected]

00721 {
00722     if (OI.isUnspecified())
00723         return true;
00724 
00725     if (!tedmod->isLocalAddress(OI))
00726         return true;
00727 
00728     if (bandwidth == 0.0)
00729         return true;
00730 
00731     int setupPri = session.setupPri;
00732     int holdingPri = session.holdingPri;
00733 
00734     unsigned int index = tedmod->linkIndex(OI);
00735 
00736     // Note: UnRB[7] <= UnRW[setupPri] <= UnRW[holdingPri] <= BW[0]
00737     // UnRW[7] is the actual BW left on the link
00738 
00739     if (tedmod->ted[index].UnResvBandwidth[setupPri] < bandwidth)
00740         return false;
00741 
00742     for (int p = holdingPri; p < 8; p++)
00743     {
00744         tedmod->ted[index].UnResvBandwidth[p] -= bandwidth;
00745 
00746         if (tedmod->ted[index].UnResvBandwidth[p] < 0.0)
00747             preempt(OI, p, -tedmod->ted[index].UnResvBandwidth[p]);
00748     }
00749 
00750     // announce changes
00751 
00752     announceLinkChange(index);
00753 
00754     return true;
00755 }

void RSVP::announceLinkChange ( int  tedlinkindex  )  [protected]

00758 {
00759     TEDChangeInfo d;
00760     d.setTedLinkIndicesArraySize(1);
00761     d.setTedLinkIndices(0, tedlinkindex);
00762     nb->fireChangeNotification(NF_TED_CHANGED, &d);
00763 }

void RSVP::commitResv ( ResvStateBlock_t rsb  )  [protected]

00766 {
00767     EV << "commit reservation (RSB " << rsb->id << ")" << endl;
00768 
00769     // allocate bandwidth as needed
00770 
00771     EV << "currently allocated: " << rsb->Flowspec_Object << endl;
00772 
00773     while(true)
00774     {
00775         // remove RSB if empty
00776 
00777         if (rsb->FlowDescriptor.size() == 0)
00778         {
00779             removeRSB(rsb);
00780             return;
00781         }
00782 
00783         FlowSpecObj_t req;
00784         req.req_bandwidth = 0.0;
00785 
00786         unsigned int maxFlowIndex;
00787         for (unsigned int i = 0; i < rsb->FlowDescriptor.size(); i++)
00788         {
00789             if (rsb->FlowDescriptor[i].Flowspec_Object.req_bandwidth > req.req_bandwidth)
00790             {
00791                 req.req_bandwidth = rsb->FlowDescriptor[i].Flowspec_Object.req_bandwidth;
00792                 maxFlowIndex = i;
00793             }
00794         }
00795 
00796         EV << "currently required: " << req << endl;
00797 
00798         double needed = req.req_bandwidth - rsb->Flowspec_Object.req_bandwidth;
00799 
00800         if (needed != 0.0)
00801         {
00802             if (allocateResource(rsb->OI, rsb->Session_Object, needed))
00803             {
00804                 // allocated (deallocated) successfully
00805 
00806                 EV << "additional bandwidth of " << needed << " allocated sucessfully" << endl;
00807 
00808                 rsb->Flowspec_Object.req_bandwidth += needed;
00809             }
00810             else
00811             {
00812                 // bandwidth not available
00813 
00814                 ASSERT(rsb->inLabelVector.size() == rsb->FlowDescriptor.size());
00815 
00816                 EV << "not enough bandwidth to accommodate this RSB" << endl;
00817 
00818                 int lspid = rsb->FlowDescriptor[maxFlowIndex].Filter_Spec_Object.Lsp_Id;
00819                 int oldInLabel = rsb->inLabelVector[maxFlowIndex];
00820                 PathStateBlock_t *psb = findPSB(rsb->Session_Object, (SenderTemplateObj_t&)rsb->FlowDescriptor[maxFlowIndex].Filter_Spec_Object);
00821 
00822                 EV << "removing filter lspid=" << lspid << " (max. flow)" << endl;
00823 
00824                 rsb->FlowDescriptor.erase(rsb->FlowDescriptor.begin() + maxFlowIndex);
00825                 rsb->inLabelVector.erase(rsb->inLabelVector.begin() + maxFlowIndex);
00826 
00827                 if (oldInLabel != -1)
00828                 {
00829                     // path already existed, this must be preemption
00830 
00831                     sendPathErrorMessage(psb, PATH_ERR_PREEMPTED);
00832 
00833                     lt->removeLibEntry(oldInLabel);
00834                 }
00835                 else
00836                 {
00837                     // path not established yet, report as unfeasible
00838 
00839                     sendPathErrorMessage(psb, PATH_ERR_UNFEASIBLE);
00840                 }
00841 
00842                 continue;
00843             }
00844 
00845         }
00846 
00847         break;
00848     }
00849 
00850     // install labels into lib
00851 
00852     for (unsigned int i = 0; i < rsb->FlowDescriptor.size(); i++)
00853     {
00854         int lspid = rsb->FlowDescriptor[i].Filter_Spec_Object.Lsp_Id;
00855 
00856         EV << "processing lspid=" << lspid << endl;
00857 
00858         PathStateBlock_t *psb = findPSB(rsb->Session_Object, rsb->FlowDescriptor[i].Filter_Spec_Object);
00859 
00860         LabelOpVector outLabel;
00861         std::string inInterface, outInterface;
00862 
00863         bool IR = (psb->Previous_Hop_Address == routerId);
00864         //bool ER = psb->OutInterface.isUnspecified();
00865         if (!IR)
00866         {
00867             IPAddress localInf = tedmod->interfaceAddrByPeerAddress(psb->Previous_Hop_Address);
00868             inInterface = rt->interfaceByAddress(localInf)->name();
00869         }
00870         else
00871             inInterface = "any";
00872 
00873         // outlabel and outgoing interface
00874 
00875         LabelOp lop;
00876 
00877         if (tedmod->isLocalAddress(psb->OutInterface))
00878         {
00879             // regular next hop
00880 
00881             lop.optcode = IR? PUSH_OPER: SWAP_OPER;
00882             lop.label = rsb->FlowDescriptor[i].label;
00883             outLabel.push_back(lop);
00884 
00885             outInterface = rt->interfaceByAddress(psb->OutInterface)->name();
00886         }
00887         else
00888         {
00889             // egress router
00890 
00891             lop.label = 0;
00892             lop.optcode = POP_OPER;
00893             outLabel.push_back(lop);
00894 
00895             outInterface = "lo0";
00896 
00897             if (!tedmod->isLocalAddress(psb->Session_Object.DestAddress))
00898             {
00899                 InterfaceEntry *ie = rt->interfaceForDestAddr(psb->Session_Object.DestAddress);
00900                 if (ie)
00901                     outInterface = ie->name(); // FIXME why use name to identify an interface?
00902             }
00903         }
00904 
00905         EV << "installing label for " << lspid << " outLabel=" << outLabel <<
00906             " outInterface=" << outInterface << endl;
00907 
00908         ASSERT(rsb->inLabelVector.size() == rsb->FlowDescriptor.size());
00909 
00910         int inLabel = lt->installLibEntry(rsb->inLabelVector[i], inInterface,
00911                 outLabel, outInterface, psb->color);
00912 
00913         ASSERT(inLabel >= 0);
00914 
00915         if (IR && rsb->inLabelVector[i] == -1)
00916         {
00917             // path established
00918             sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_CREATED, 0.0);
00919         }
00920 
00921         if (rsb->inLabelVector[i] != inLabel)
00922         {
00923             // remember our current label
00924             rsb->inLabelVector[i] = inLabel;
00925 
00926             // bind fec
00927             rpct->bind(psb->Session_Object, psb->Sender_Template_Object, inLabel);
00928         }
00929 
00930         // schedule commit of merging backups too...
00931         for (unsigned int j = 0; j < RSBList.size(); j++)
00932         {
00933             if (RSBList[j].OI != lspid)
00934                 continue;
00935 
00936             scheduleCommitTimer(&RSBList[j]);
00937         }
00938     }
00939 }

RSVP::ResvStateBlock_t * RSVP::createEgressRSB ( PathStateBlock_t psb  )  [protected]

01284 {
01285     ResvStateBlock_t rsbEle;
01286 
01287     rsbEle.id = ++maxRsbId;
01288 
01289     rsbEle.timeoutMsg = new RsbTimeoutMsg("rsb timeout");
01290     rsbEle.timeoutMsg->setId(rsbEle.id);
01291 
01292     rsbEle.refreshTimerMsg = new RsbRefreshTimerMsg("rsb timer");
01293     rsbEle.refreshTimerMsg->setId(rsbEle.id);
01294 
01295     rsbEle.commitTimerMsg = new RsbCommitTimerMsg("rsb commit");
01296     rsbEle.commitTimerMsg->setId(rsbEle.id);
01297 
01298     rsbEle.Session_Object = psb->Session_Object;
01299     rsbEle.Next_Hop_Address = psb->Previous_Hop_Address;
01300 
01301     rsbEle.OI = psb->OutInterface;
01302 
01303     FlowDescriptor_t flow;
01304     flow.Flowspec_Object = (FlowSpecObj_t&)psb->Sender_Tspec_Object;
01305     flow.Filter_Spec_Object = (FilterSpecObj_t&)psb->Sender_Template_Object;
01306     flow.label = -1;
01307 
01308     rsbEle.FlowDescriptor.push_back(flow);
01309     rsbEle.inLabelVector.push_back(-1);
01310 
01311     RSBList.push_back(rsbEle);
01312     ResvStateBlock_t *rsb = &(*(RSBList.end() - 1));
01313 
01314     EV << "created new (egress) RSB " << rsb->id << endl;
01315 
01316     return rsb;
01317 }

RSVP::PathStateBlock_t * RSVP::createIngressPSB ( const traffic_session_t session,
const traffic_path_t path 
) [protected]

01236 {
01237     EroVector ERO = path.ERO;
01238 
01239     while(ERO.size() > 0 && ERO[0].node == routerId)
01240     {
01241         // remove ourselves from the beginning of the hop list
01242         ERO.erase(ERO.begin());
01243     }
01244 
01245     IPAddress OI;
01246 
01247     if (!evalNextHopInterface(session.sobj.DestAddress, ERO, OI))
01248         return NULL;
01249 
01250     if (!doCACCheck(session.sobj, path.tspec, OI))
01251         return NULL;
01252 
01253     EV << "CACCheck passed, creating PSB" << endl;
01254 
01255     PathStateBlock_t psbEle;
01256     psbEle.id = ++maxPsbId;
01257 
01258     psbEle.timeoutMsg = new PsbTimeoutMsg("psb timeout");
01259     psbEle.timeoutMsg->setId(psbEle.id);
01260 
01261     psbEle.timerMsg = new PsbTimerMsg("psb timer");
01262     psbEle.timerMsg->setId(psbEle.id);
01263 
01264     psbEle.Session_Object = session.sobj;
01265     psbEle.Sender_Template_Object = path.sender;
01266     psbEle.Sender_Tspec_Object = path.tspec;
01267 
01268     psbEle.Previous_Hop_Address = routerId;
01269 
01270     psbEle.OutInterface = OI;
01271     psbEle.ERO = ERO;
01272     psbEle.color = path.color;
01273 
01274     psbEle.handler = path.owner;
01275 
01276     PSBList.push_back(psbEle);
01277     PathStateBlock_t *cPSB = &(*(PSBList.end() - 1));
01278 
01279     return cPSB;
01280 }

void RSVP::createPath ( const SessionObj_t session,
const SenderTemplateObj_t sender 
) [protected]

00091 {
00092     if (findPSB(session, sender))
00093     {
00094         EV << "path (PSB) already exists, doing nothing" << endl;
00095         return;
00096     }
00097 
00098     // find entry in traffic database
00099 
00100     std::vector<traffic_session_t>::iterator sit;
00101     sit = findSession(session);
00102 
00103     if (sit == traffic.end())
00104     {
00105         EV << "session not found in traffic database, path won't be created" << endl;
00106         return;
00107     }
00108 
00109     std::vector<traffic_path_t>::iterator pit;
00110     pit = findPath(&(*sit), sender);
00111 
00112     if (pit == sit->paths.end())
00113     {
00114         EV << "path doesn't belong to this session according to our database, doing nothing" << endl;
00115         return;
00116     }
00117 
00118     PathStateBlock_t *psb = createIngressPSB(*sit, *pit);
00119     if (psb)
00120     {
00121         // PSB successfully created, send path message downstream
00122         scheduleRefreshTimer(psb, 0.0);
00123     }
00124     else
00125     {
00126         EV << "ingress PSB couln't be created" << endl;
00127 
00128         // inform the owner of this path
00129         sendPathNotify(pit->owner, sit->sobj, pit->sender, PATH_UNFEASIBLE, 0.0);
00130 
00131         // remove non-permanent path
00132         if (!pit->permanent)
00133         {
00134             EV << "removing path from traffic database" << endl;
00135 
00136             sit->paths.erase(pit--);
00137         }
00138         else
00139         {
00140             EV << "path is permanent, we will try again later" << endl;
00141 
00142             sendPathNotify(id(), sit->sobj, pit->sender, PATH_RETRY, retryInterval);
00143         }
00144     }
00145 }

RSVP::PathStateBlock_t * RSVP::createPSB ( RSVPPathMsg msg  )  [protected]

01190 {
01191     const EroVector& ERO = msg->getERO();
01192     IPAddress destAddr = msg->getDestAddress();
01193 
01194     //
01195 
01196     IPAddress OI;
01197 
01198     if (!evalNextHopInterface(destAddr, ERO, OI))
01199         return NULL;
01200 
01201     if (tedmod->isLocalAddress(OI) && !doCACCheck(msg->getSession(), msg->getSenderTspec(), OI))
01202         return NULL; // not enough resources
01203 
01204     PathStateBlock_t psbEle;
01205 
01206     psbEle.id = ++maxPsbId;
01207 
01208     psbEle.timeoutMsg = new PsbTimeoutMsg("psb timeout");
01209     psbEle.timeoutMsg->setId(psbEle.id);
01210 
01211     psbEle.timerMsg = new PsbTimerMsg("psb timer");
01212     psbEle.timerMsg->setId(psbEle.id);
01213 
01214     psbEle.Session_Object = msg->getSession();
01215     psbEle.Sender_Template_Object = msg->getSenderTemplate();
01216     psbEle.Sender_Tspec_Object = msg->getSenderTspec();
01217 
01218     psbEle.Previous_Hop_Address = msg->getNHOP();
01219     //psbEle.LIH = msg->getLIH();
01220 
01221     psbEle.OutInterface = OI;
01222     psbEle.ERO = ERO;
01223 
01224     psbEle.color = msg->getColor();
01225     psbEle.handler = -1;
01226 
01227     PSBList.push_back(psbEle);
01228     PathStateBlock_t *cPSB = &(*(PSBList.end() - 1));
01229 
01230     EV << "created new PSB " << cPSB->id << endl;
01231 
01232     return cPSB;
01233 }

RSVP::ResvStateBlock_t * RSVP::createRSB ( RSVPResvMsg msg  )  [protected]

00942 {
00943     ResvStateBlock_t rsbEle;
00944 
00945     rsbEle.id = ++maxRsbId;
00946 
00947     rsbEle.timeoutMsg = new RsbTimeoutMsg("rsb timeout");
00948     rsbEle.timeoutMsg->setId(rsbEle.id);
00949 
00950     rsbEle.refreshTimerMsg = new RsbRefreshTimerMsg("rsb timer");
00951     rsbEle.refreshTimerMsg->setId(rsbEle.id);
00952 
00953     rsbEle.commitTimerMsg = new RsbCommitTimerMsg("rsb commit");
00954     rsbEle.commitTimerMsg->setId(rsbEle.id);
00955 
00956     rsbEle.Session_Object = msg->getSession();
00957     rsbEle.Next_Hop_Address = msg->getNHOP();
00958     rsbEle.OI = msg->getLIH();
00959 
00960     ASSERT(rsbEle.inLabelVector.size() == rsbEle.FlowDescriptor.size());
00961 
00962     for (unsigned int i = 0; i < msg->getFlowDescriptor().size(); i++)
00963     {
00964         FlowDescriptor_t flow = msg->getFlowDescriptor()[i];
00965         rsbEle.FlowDescriptor.push_back(flow);
00966         rsbEle.inLabelVector.push_back(-1);
00967     }
00968 
00969     RSBList.push_back(rsbEle);
00970     ResvStateBlock_t *rsb = &(*(RSBList.end() - 1));
00971 
00972     EV << "created new RSB " << rsb->id << endl;
00973 
00974     return rsb;
00975 }

void RSVP::delSession ( const cXMLElement &  node  )  [protected]

01862 {
01863     Enter_Method_Silent();
01864 
01865     checkTags(&node, "tunnel_id extended_tunnel_id endpoint paths");
01866 
01867     SessionObj_t sobj;
01868 
01869     sobj.Tunnel_Id = getParameterIntValue(&node, "tunnel_id");
01870     sobj.Extended_Tunnel_Id = getParameterIPAddressValue(&node, "extended_tunnel_id", routerId).getInt();
01871     sobj.DestAddress = getParameterIPAddressValue(&node, "endpoint");
01872 
01873     std::vector<traffic_session_t>::iterator sit = findSession(sobj);
01874     ASSERT(sit != traffic.end());
01875     traffic_session_t *session = &(*sit);
01876 
01877     const cXMLElement *paths = getUniqueChildIfExists(&node, "paths");
01878     cXMLElementList pathList;
01879     if (paths)
01880     {
01881         // only specified paths will be removed, session remains
01882 
01883         checkTags(paths, "path");
01884         pathList = paths->getChildrenByTagName("path");
01885     }
01886 
01887     std::vector<traffic_path_t>::iterator it;
01888     for (it = session->paths.begin(); it != session->paths.end(); it++)
01889     {
01890         bool remove;
01891 
01892         if (paths)
01893         {
01894             remove = false;
01895 
01896             for (cXMLElementList::iterator p=pathList.begin(); p != pathList.end(); p++)
01897             {
01898                 if (it->sender.Lsp_Id != getParameterIntValue(*p, "lspid"))
01899                     continue;
01900 
01901                 // remove path from session
01902 
01903                 remove = true;
01904                 break;
01905             }
01906         }
01907         else
01908         {
01909             // remove all paths
01910 
01911             remove = true;
01912         }
01913 
01914         if (remove)
01915         {
01916             PathStateBlock_t *psb = findPSB(session->sobj, it->sender);
01917             if (psb)
01918             {
01919                 ASSERT(psb->ERO.size() > 0);
01920 
01921                 sendPathTearMessage(psb->ERO[0].node, psb->Session_Object, psb->Sender_Template_Object,
01922                         tedmod->interfaceAddrByPeerAddress(psb->ERO[0].node), routerId, true);
01923 
01924                 removePSB(psb);
01925             }
01926 
01927             session->paths.erase(it--);
01928         }
01929     }
01930 
01931     if (!paths)
01932     {
01933         traffic.erase(sit);
01934     }
01935 }

bool RSVP::doCACCheck ( const SessionObj_t session,
const SenderTspecObj_t tspec,
IPAddress  OI 
) [protected]

00535 {
00536     ASSERT(tedmod->isLocalAddress(OI));
00537 
00538     int k = tedmod->linkIndex(OI);
00539 
00540     double sharedBW = 0.0;
00541 
00542     for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
00543     {
00544         if (it->Session_Object != session)
00545             continue;
00546 
00547         if (it->Flowspec_Object.req_bandwidth <= sharedBW)
00548             continue;
00549 
00550         sharedBW = it->Flowspec_Object.req_bandwidth;
00551     }
00552 
00553     EV << "CACCheck: link=" << OI <<
00554         " requested=" << tspec.req_bandwidth <<
00555         " shared=" << sharedBW <<
00556         " available (immediately)=" << tedmod->ted[k].UnResvBandwidth[7] <<
00557         " available (preemptible)=" << tedmod->ted[k].UnResvBandwidth[session.setupPri] << endl;
00558 
00559     return (tedmod->ted[k].UnResvBandwidth[session.setupPri] + sharedBW >= tspec.req_bandwidth);
00560 }

bool RSVP::evalNextHopInterface ( IPAddress  destAddr,
const EroVector ERO,
IPAddress OI 
) [protected]

01114 {
01115     if (ERO.size() > 0)
01116     {
01117         // explicit routing
01118 
01119         if (ERO[0].L)
01120         {
01121             InterfaceEntry *ie = rt->interfaceForDestAddr(ERO[0].node);
01122 
01123             if (!ie)
01124             {
01125                 EV << "next (loose) hop address " << ERO[0].node << " is currently unroutable" << endl;
01126                 return false;
01127             }
01128 
01129             OI = ie->ipv4()->inetAddress();
01130 
01131         }
01132         else
01133         {
01134             OI = tedmod->interfaceAddrByPeerAddress(ERO[0].node);
01135         }
01136 
01137         IPAddress peer = tedmod->peerByLocalAddress(OI);
01138         HelloState_t *h = findHello(peer);
01139         if (!h)
01140             error("Peer %s on interface %s is not an RSVP peer", peer.str().c_str(), OI.str().c_str());
01141 
01142         // ok, only if next hop is up and running
01143 
01144         return h->ok;
01145     }
01146     else
01147     {
01148         // hop-by-hop routing
01149 
01150         if (!tedmod->isLocalAddress(destAddr))
01151         {
01152             InterfaceEntry *ie = rt->interfaceForDestAddr(destAddr);
01153 
01154             if (!ie)
01155             {
01156                 EV << "destination address " << destAddr << " is currently unroutable" << endl;
01157                 return false;
01158             }
01159 
01160             OI = ie->ipv4()->inetAddress();
01161 
01162             HelloState_t *h = findHello(tedmod->peerByLocalAddress(OI));
01163             if (!h)
01164             {
01165                 // outgoing interface is not LSR, we are egress router
01166 
01167                 OI = IPAddress();
01168 
01169                 return true;
01170             }
01171             else
01172             {
01173                 // outgoing interface is LSR
01174 
01175                 ASSERT(h->ok); // rt->interfaceForDestAddr() wouldn't choose this entry
01176 
01177                 return h->ok;
01178             }
01179         }
01180         else
01181         {
01182             // destAddress is ours, we're egress
01183 
01184             return true;
01185         }
01186     }
01187 }

RSVP::HelloState_t * RSVP::findHello ( IPAddress  peer  )  [protected]

02136 {
02137     for (HelloVector::iterator it = HelloList.begin(); it != HelloList.end(); it++)
02138     {
02139         if (it->peer != peer)
02140             continue;
02141 
02142         return &(*it);
02143     }
02144     return NULL;
02145 }

std::vector< RSVP::traffic_path_t >::iterator RSVP::findPath ( traffic_session_t session,
const SenderTemplateObj_t sender 
) [protected]

00311 {
00312     std::vector<traffic_path_t>::iterator it;
00313     for (it = session->paths.begin(); it != session->paths.end(); it++)
00314     {
00315         if (it->sender != sender)
00316             continue;
00317 
00318         break;
00319     }
00320     return it;
00321 }

RSVP::PathStateBlock_t * RSVP::findPSB ( const SessionObj_t session,
const SenderTemplateObj_t sender 
) [protected]

02092 {
02093     PSBVector::iterator it;
02094     for (it = PSBList.begin(); it != PSBList.end(); it++)
02095     {
02096         if (it->Session_Object != session)
02097             continue;
02098 
02099         if (it->Sender_Template_Object != sender)
02100             continue;
02101 
02102         return &(*it);
02103     }
02104 
02105     return NULL;
02106 }

RSVP::PathStateBlock_t * RSVP::findPsbById ( int  id  )  [protected]

02109 {
02110     for (unsigned int i = 0; i < PSBList.size(); i++)
02111     {
02112         if (PSBList[i].id != id)
02113             continue;
02114 
02115         return &PSBList[i];
02116     }
02117     ASSERT(false);
02118     return NULL; // prevent warning
02119 }

RSVP::ResvStateBlock_t * RSVP::findRSB ( const SessionObj_t session,
const SenderTemplateObj_t sender,
unsigned int &  index 
) [protected]

02065 {
02066     RSBVector::iterator it;
02067 
02068     for (it = RSBList.begin(); it != RSBList.end(); it++)
02069     {
02070         if (it->Session_Object != session)
02071             continue;
02072 
02073         FlowDescriptorVector::iterator fit;
02074         index = 0;
02075         for (fit = it->FlowDescriptor.begin(); fit != it->FlowDescriptor.end(); fit++)
02076         {
02077             if ((SenderTemplateObj_t&)fit->Filter_Spec_Object != sender)
02078             {
02079                 ++index;
02080                 continue;
02081             }
02082 
02083             return &(*it);
02084         }
02085 
02086         // don't break here, may be in different (if outInterface is different)
02087     }
02088     return NULL;
02089 }

RSVP::ResvStateBlock_t * RSVP::findRsbById ( int  id  )  [protected]

02123 {
02124     for (unsigned int i = 0; i < RSBList.size(); i++)
02125     {
02126         if (RSBList[i].id != id)
02127             continue;
02128 
02129         return &RSBList[i];
02130     }
02131     ASSERT(false);
02132     return NULL; // prevent warning
02133 }

std::vector< RSVP::traffic_session_t >::iterator RSVP::findSession ( const SessionObj_t session  )  [protected]

01841 {
01842     std::vector<traffic_session_t>::iterator it;
01843     for (it = traffic.begin(); it != traffic.end(); it++)
01844     {
01845         if (it->sobj != session)
01846             continue;
01847 
01848         break;
01849     }
01850 
01851     return it;
01852 }

int RSVP::getInLabel ( const SessionObj_t session,
const SenderTemplateObj_t sender 
) [private]

00081 {
00082     unsigned int index;
00083     ResvStateBlock_t *rsb = findRSB(session, sender, index);
00084     if (!rsb)
00085         return -1;
00086 
00087     return rsb->inLabelVector[index];
00088 }

void RSVP::handleMessage ( cMessage *  msg  )  [protected, virtual]

01320 {
01321     SignallingMsg *sMsg = dynamic_cast<SignallingMsg*>(msg);
01322     RSVPMessage *rMsg = dynamic_cast<RSVPMessage*>(msg);
01323 
01324     if (sMsg)
01325     {
01326         processSignallingMessage(sMsg);
01327         return;
01328     }
01329     else if (rMsg)
01330     {
01331         processRSVPMessage(rMsg);
01332         return;
01333     }
01334     else
01335         ASSERT(false);
01336 }

void RSVP::initialize ( int  stage  )  [protected, virtual]

00051 {
00052     // we have to wait for stage 2 until interfaces get registered (stage 0)
00053     // and get their auto-assigned IP addresses (stage 2); routerId gets
00054     // assigned in state 3
00055     if (stage==4)
00056     {
00057         tedmod = TEDAccess().get();
00058         rt = RoutingTableAccess().get();
00059         ift = InterfaceTableAccess().get();
00060         routerId = rt->routerId();
00061         lt = LIBTableAccess().get();
00062         nb = NotificationBoardAccess().get();
00063 
00064         rpct = check_and_cast<IRSVPClassifier*>(parentModule()->submodule("classifier"));
00065 
00066         maxPsbId = 0;
00067         maxRsbId = 0;
00068         maxSrcInstance = 0;
00069 
00070         retryInterval = 1.0;
00071 
00072         // setup hello
00073         setupHello();
00074 
00075         // process traffic configuration
00076         readTrafficFromXML(par("traffic").xmlValue());
00077     }
00078 }

virtual int RSVP::numInitStages (  )  const [inline, protected, virtual]

00284 {return 5;}

void RSVP::pathProblem ( PathStateBlock_t psb  )  [protected]

01767 {
01768     ASSERT(psb);
01769     ASSERT(!psb->OutInterface.isUnspecified());
01770 
01771     IPAddress nextHop = tedmod->peerByLocalAddress(psb->OutInterface);
01772 
01773     EV << "sending PathTear to " << nextHop << endl;
01774 
01775     sendPathTearMessage(nextHop, psb->Session_Object, psb->Sender_Template_Object,
01776                         tedmod->interfaceAddrByPeerAddress(nextHop), routerId, true);
01777 
01778     // schedule re-creation if path is permanent
01779 
01780     std::vector<traffic_session_t>::iterator sit = findSession(psb->Session_Object);
01781     ASSERT(sit != traffic.end());
01782     traffic_session_t *s = &(*sit);
01783 
01784     std::vector<traffic_path_t>::iterator pit = findPath(s, psb->Sender_Template_Object);
01785     ASSERT(pit != s->paths.end());
01786     traffic_path_t *p = &(*pit);
01787 
01788     if (p->permanent)
01789     {
01790         EV << "this path is permanent, we will try to re-create it later" << endl;
01791 
01792         sendPathNotify(id(), psb->Session_Object, psb->Sender_Template_Object, PATH_RETRY, retryInterval);
01793 
01794     }
01795     else
01796     {
01797         EV << "removing path from traffic database" << endl;
01798 
01799         sit->paths.erase(pit);
01800     }
01801 
01802     // remove path
01803 
01804     EV << "removing PSB" << endl;
01805 
01806     removePSB(psb);
01807 }

void RSVP::preempt ( IPAddress  OI,
int  priority,
double  bandwidth 
) [protected]

00687 {
00688     ASSERT(tedmod->isLocalAddress(OI));
00689 
00690     unsigned int index = tedmod->linkIndex(OI);
00691 
00692     for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
00693     {
00694         if (it->OI != OI)
00695             continue;
00696 
00697         if (it->Session_Object.holdingPri != priority)
00698             continue;
00699 
00700         if (it->Flowspec_Object.req_bandwidth == 0.0)
00701             continue;
00702 
00703         // preempt RSB
00704 
00705         for (int i = priority; i < 8; i++)
00706             tedmod->ted[index].UnResvBandwidth[i] += it->Flowspec_Object.req_bandwidth;
00707 
00708         bandwidth -= it->Flowspec_Object.req_bandwidth;
00709         it->Flowspec_Object.req_bandwidth = 0.0;
00710 
00711         scheduleCommitTimer(&(*it));
00712 
00713         //
00714 
00715         if (bandwidth <= 0.0)
00716             break;
00717     }
00718 }

void RSVP::print ( RSVPResvMsg r  )  [protected]

02206 {
02207     EV << "RESV_MESSAGE: " << endl;
02208     for (unsigned int i = 0; i < r->getFlowDescriptor().size(); i++)
02209     {
02210         EV << " lspid " << r->getFlowDescriptor()[i].Filter_Spec_Object.Lsp_Id <<
02211             " label " << r->getFlowDescriptor()[i].label << endl;
02212     }
02213 }

void RSVP::print ( RSVPPathMsg p  )  [protected]

02201 {
02202     EV << "PATH_MESSAGE: lspid " << p->getLspId() << " ERO " << vectorToString(p->getERO()) << endl;
02203 }

void RSVP::processCommand ( const cXMLElement &  node  )  [protected, virtual]

Called by ScenarioManager whenever a script command needs to be carried out by the module.

The command is represented by the XML element or element tree. The command name can be obtained as:

 const char *command = node->getTagName()
 

Parameters are XML attributes, e.g. a "neighbour" parameter can be retrieved as:

 const char *attr = node->getAttribute("neighbour")
 

More complex input can be passed in child elements.

See also:
cXMLElement

Implements IScriptable.

01938 {
01939     if (!strcmp(node.getTagName(), "add-session"))
01940     {
01941         addSession(node);
01942     }
01943     else if (!strcmp(node.getTagName(), "del-session"))
01944     {
01945         delSession(node);
01946     }
01947     else
01948         ASSERT(false);
01949 }

void RSVP::processHELLO_TIMEOUT ( HelloTimeoutMsg msg  )  [protected]

00410 {
00411     IPAddress peer = msg->getPeer();
00412 
00413     EV << "hello timeout, considering " << peer << " failed" << endl;
00414 
00415     // update hello state (set to failed and turn hello off)
00416 
00417     HelloState_t *hello = findHello(peer);
00418     ASSERT(hello);
00419     hello->ok = false;
00420     ASSERT(!hello->timeout->isScheduled());
00421     cancelEvent(hello->timer);
00422 
00423     // update TED and routing table
00424 
00425     unsigned int index = tedmod->linkIndex(routerId, peer);
00426     tedmod->ted[index].state = false;
00427     announceLinkChange(index);
00428     tedmod->rebuildRoutingTable();
00429 
00430     // send PATH_ERROR for existing paths
00431 
00432     for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
00433     {
00434         if (it->OutInterface != tedmod->ted[index].local)
00435             continue;
00436 
00437         sendPathErrorMessage(&(*it), PATH_ERR_NEXTHOP_FAILED);
00438     }
00439 }

void RSVP::processHELLO_TIMER ( HelloTimerMsg msg  )  [protected]

00442 {
00443     IPAddress peer = msg->getPeer();
00444 
00445     HelloState_t *h = findHello(peer);
00446     ASSERT(h);
00447 
00448     RSVPHelloMsg *hMsg = new RSVPHelloMsg("hello message");
00449 
00450     hMsg->setSrcInstance(h->srcInstance);
00451     hMsg->setDstInstance(h->dstInstance);
00452 
00453     hMsg->setRequest(h->request);
00454     hMsg->setAck(h->ack);
00455 
00456     int length = 10;
00457 
00458     // see comment elsewhere (in TED.cc)
00459     length /= 10;
00460 
00461     hMsg->setByteLength(length);
00462 
00463     sendToIP(hMsg, peer);
00464 
00465     h->ack = false;
00466 
00467     scheduleAt(simTime() + helloInterval, msg);
00468 }

void RSVP::processHelloMsg ( RSVPHelloMsg msg  )  [protected]

01369 {
01370     EV << "Received RSVP_HELLO" << endl;
01371     //print(msg);
01372 
01373     IPControlInfo *controlInfo = check_and_cast<IPControlInfo*>(msg->controlInfo());
01374     IPAddress sender = controlInfo->srcAddr();
01375     IPAddress peer = tedmod->primaryAddress(sender);
01376 
01377     bool request = msg->getRequest();
01378     bool ack = msg->getAck();
01379 
01380     EV << "hello sender " << peer;
01381     if (request) EV << " REQ";
01382     if (ack) EV << " ACK";
01383     EV << endl;
01384 
01385     int rcvSrcInstance = msg->getSrcInstance();
01386     int rcvDstInstance = msg->getDstInstance();
01387 
01388     delete msg;
01389 
01390     HelloState_t *h = findHello(peer);
01391     ASSERT(h);
01392 
01393     ASSERT(h->srcInstance);
01394     ASSERT(rcvSrcInstance);
01395 
01396     bool failure = false;
01397 
01398     if (h->srcInstance != rcvDstInstance)
01399     {
01400         if (rcvDstInstance != 0)
01401         {
01402             failure = true;
01403         }
01404         else
01405         {
01406             ASSERT(request);
01407         }
01408     }
01409 
01410     if (h->dstInstance != rcvSrcInstance)
01411     {
01412         if (h->dstInstance != 0)
01413         {
01414             failure = true;
01415         }
01416         h->dstInstance = rcvSrcInstance;
01417     }
01418 
01419     if (failure)
01420     {
01421         // mismatch encountered
01422         h->srcInstance = ++maxSrcInstance;
01423     }
01424 
01425     if (failure || !h->ok)
01426     {
01427         h->ok = true;
01428 
01429         EV << "local peer " << peer << " is now considered up and running" << endl;
01430 
01431         recoveryEvent(peer);
01432 
01433         // if peer was considered down, we have stopped sending hellos: resume now
01434         if (!h->timer->isScheduled())
01435             scheduleAt(simTime(), h->timer);
01436     }
01437 
01438     if (request)
01439     {
01440         // immediately respond to a request with an ack
01441         h->ack = true;
01442         h->request = false;
01443 
01444         cancelEvent(h->timer);
01445         scheduleAt(simTime(), h->timer);
01446     }
01447     else
01448     {
01449         // next message will be regular
01450 
01451         h->ack = false;
01452         h->request = false;
01453 
01454         ASSERT(h->timer->isScheduled());
01455     }
01456 
01457     cancelEvent(h->timeout);
01458     scheduleAt(simTime() + helloTimeout, h->timeout);
01459 }

void RSVP::processPATH_NOTIFY ( PathNotifyMsg msg  )  [protected]

01810 {
01811     PathStateBlock_t *psb;
01812 
01813     switch(msg->getStatus())
01814     {
01815         case PATH_RETRY:
01816             createPath(msg->getSession(), msg->getSender());
01817             break;
01818 
01819         case PATH_UNFEASIBLE:
01820         case PATH_PREEMPTED:
01821         case PATH_FAILED:
01822             psb = findPSB(msg->getSession(), msg->getSender());
01823             if (psb)
01824                 pathProblem(psb);
01825             break;
01826 
01827         case PATH_CREATED:
01828             EV << "Path successfully established" << endl;
01829             break;
01830 
01831 
01832         default:
01833             ASSERT(false);
01834     }
01835 
01836     delete msg;
01837 }

void RSVP::processPathErrMsg ( RSVPPathError msg  )  [protected]

01462 {
01463     EV << "Received PATH_ERROR" << endl;
01464     //print(msg);
01465 
01466     //int lspid = msg->getLspId();
01467     int errCode = msg->getErrorCode();
01468 
01469     PathStateBlock_t *psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01470     if (!psb)
01471     {
01472         EV << "matching PSB not found, ignoring error message" << endl;
01473         delete msg;
01474         return;
01475     }
01476 
01477     if (psb->Previous_Hop_Address != routerId)
01478     {
01479         EV << "forwarding error message to PHOP (" << psb->Previous_Hop_Address << ")" << endl;
01480 
01481         msg->removeControlInfo();
01482         sendToIP(msg, psb->Previous_Hop_Address);
01483     }
01484     else
01485     {
01486         EV << "error reached ingress router" << endl;
01487 
01488         switch(errCode)
01489         {
01490             case PATH_ERR_PREEMPTED:
01491                 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_PREEMPTED, 0.0);
01492                 break;
01493 
01494             case PATH_ERR_UNFEASIBLE:
01495                 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_UNFEASIBLE, 0.0);
01496                 break;
01497 
01498             case PATH_ERR_NEXTHOP_FAILED:
01499                 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_FAILED, 0.0);
01500                 break;
01501 
01502             default:
01503                 ASSERT(false);
01504         }
01505 
01506         delete msg;
01507     }
01508 }

void RSVP::processPathMsg ( RSVPPathMsg msg  )  [protected]

01572 {
01573     EV << "Received PATH_MESSAGE" << endl;
01574     print(msg);
01575 
01576     // process ERO *************************************************************
01577 
01578     EroVector ERO = msg->getERO();
01579 
01580     while(ERO.size() > 0 && ERO[0].node == routerId)
01581     {
01582         ERO.erase(ERO.begin());
01583     }
01584 
01585     msg->setERO(ERO);
01586 
01587     // create PSB if doesn't exist yet *****************************************
01588 
01589     PathStateBlock_t *psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01590 
01591     if (!psb)
01592     {
01593         psb = createPSB(msg);
01594         if (!psb)
01595         {
01596             sendPathErrorMessage(msg->getSession(), msg->getSenderTemplate(),
01597                 msg->getSenderTspec(), msg->getNHOP(), PATH_ERR_UNFEASIBLE);
01598             delete msg;
01599             return;
01600         }
01601         scheduleRefreshTimer(psb, 0.0);
01602 
01603         if (tedmod->isLocalAddress(psb->OutInterface))
01604         {
01605             unsigned int index = tedmod->linkIndex(psb->OutInterface);
01606             if (!tedmod->ted[index].state)
01607             {
01608                 sendPathErrorMessage(psb, PATH_ERR_NEXTHOP_FAILED);
01609             }
01610         }
01611     }
01612 
01613     // schedule timer&timeout **************************************************
01614 
01615     scheduleTimeout(psb);
01616 
01617     // create RSB if we're egress and doesn't exist yet ************************
01618 
01619     unsigned int index;
01620     ResvStateBlock_t *rsb = findRSB(msg->getSession(), msg->getSenderTemplate(), index);
01621 
01622     if (!rsb && psb->OutInterface.isUnspecified())
01623     {
01624         ASSERT(ERO.size() == 0);
01625         rsb = createEgressRSB(psb);
01626         ASSERT(rsb);
01627         scheduleCommitTimer(rsb);
01628     }
01629 
01630     if (rsb)
01631         scheduleRefreshTimer(rsb, 0.0);
01632 
01633     delete msg;
01634 }

void RSVP::processPathTearMsg ( RSVPPathTear msg  )  [protected]

01511 {
01512     EV << "Received PATH_TEAR" << endl;
01513     //print(msg);
01514 
01515     int lspid = msg->getLspId();
01516 
01517     PathStateBlock_t *psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01518     if (!psb)
01519     {
01520         EV << "received PATH_TEAR for nonexisting lspid=" << lspid << endl;
01521         delete msg;
01522         return;
01523     }
01524 
01525     // ignore message if backup exists and force flag is not set
01526 
01527     bool modified = false;
01528 
01529     for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
01530     {
01531         if (it->OutInterface.getInt() != lspid)
01532             continue;
01533 
01534         // merging backup exists
01535 
01536         if (!msg->getForce())
01537         {
01538             EV << "merging backup tunnel exists and force flag is not set, ignoring teardown" << endl;
01539             delete msg;
01540             return;
01541         }
01542 
01543         EV << "merging backup must be removed too" << endl;
01544 
01545         removePSB(&(*it));
01546         --it;
01547 
01548         modified = true;
01549     }
01550 
01551     if (modified)
01552         psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01553 
01554     // forward path teardown downstream
01555 
01556     if (psb->ERO.size() > 0)
01557     {
01558         EV << "forward teardown downstream" << endl;
01559 
01560         sendPathTearMessage(psb->ERO[0].node, psb->Session_Object, psb->Sender_Template_Object,
01561             tedmod->interfaceAddrByPeerAddress(psb->ERO[0].node), routerId, msg->getForce());
01562     }
01563 
01564     // remove path state block
01565 
01566     removePSB(psb);
01567 
01568     delete msg;
01569 }

void RSVP::processPSB_TIMEOUT ( PsbTimeoutMsg msg  )  [protected]

00480 {
00481     PathStateBlock_t *psb = findPsbById(msg->getId());
00482     ASSERT(psb);
00483 
00484     if (tedmod->isLocalAddress(psb->OutInterface))
00485     {
00486         ASSERT(psb->OutInterface == tedmod->interfaceAddrByPeerAddress(psb->ERO[0].node));
00487 
00488         sendPathTearMessage(psb->ERO[0].node, psb->Session_Object,
00489             psb->Sender_Template_Object, psb->OutInterface, routerId, false);
00490     }
00491 
00492     removePSB(psb);
00493 }

void RSVP::processPSB_TIMER ( PsbTimerMsg msg  )  [protected]

00471 {
00472     PathStateBlock_t *psb = findPsbById(msg->getId());
00473     ASSERT(psb);
00474 
00475     refreshPath(psb);
00476     scheduleRefreshTimer(psb, PSB_REFRESH_INTERVAL);
00477 }

void RSVP::processResvMsg ( RSVPResvMsg msg  )  [protected]

01637 {
01638     EV << "Received RESV_MESSAGE" << endl;
01639     print(msg);
01640 
01641     IPAddress OI = msg->getLIH();
01642 
01643     // find matching PSB for every flow ****************************************
01644 
01645     for (unsigned int m = 0; m < msg->getFlowDescriptor().size(); m++)
01646     {
01647 
01648         PathStateBlock_t *psb = findPSB(msg->getSession(), (SenderTemplateObj_t&)msg->getFlowDescriptor()[m].Filter_Spec_Object);
01649         if (!psb)
01650         {
01651             EV << "matching PSB not found for lspid=" << msg->getFlowDescriptor()[m].Filter_Spec_Object.Lsp_Id << endl;
01652 
01653             // remove descriptor from message
01654             msg->getFlowDescriptor().erase(msg->getFlowDescriptor().begin() + m);
01655             --m;
01656         }
01657     }
01658 
01659     if (msg->getFlowDescriptor().size() == 0)
01660     {
01661         EV << "no matching PSB found" << endl;
01662         delete msg;
01663         return;
01664     }
01665 
01666     // find matching RSB *******************************************************
01667 
01668     ResvStateBlock_t *rsb = NULL;
01669     for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
01670     {
01671         if (!(msg->isInSession(&it->Session_Object)))
01672             continue;
01673 
01674         if (it->Next_Hop_Address != msg->getNHOP())
01675             continue;
01676 
01677         if (it->OI != msg->getLIH())
01678             continue;
01679 
01680         rsb = &(*it);
01681         break;
01682     }
01683 
01684     if (!rsb)
01685     {
01686         rsb = createRSB(msg);
01687 
01688         scheduleCommitTimer(rsb);
01689 
01690         // reservation is new, propagate upstream immediately
01691         scheduleRefreshTimer(rsb, 0.0);
01692     }
01693     else
01694         updateRSB(rsb, msg);
01695 
01696     scheduleTimeout(rsb);
01697 
01698     delete msg;
01699 }

void RSVP::processRSB_COMMIT_TIMER ( RsbCommitTimerMsg msg  )  [protected]

00513 {
00514     ResvStateBlock_t *rsb = findRsbById(msg->getId());
00515     commitResv(rsb);
00516 }

void RSVP::processRSB_REFRESH_TIMER ( RsbRefreshTimerMsg msg  )  [protected]

00497 {
00498     ResvStateBlock_t *rsb = findRsbById(msg->getId());
00499     if (rsb->commitTimerMsg->isScheduled())
00500     {
00501         // reschedule after commit
00502         scheduleRefreshTimer(rsb, 0.0);
00503     }
00504     else
00505     {
00506         refreshResv(rsb);
00507 
00508         scheduleRefreshTimer(rsb, RSB_REFRESH_INTERVAL);
00509     }
00510 }

void RSVP::processRSB_TIMEOUT ( RsbTimeoutMsg msg  )  [protected]

00519 {
00520     EV << "RSB TIMEOUT RSB " << msg->getId() << endl;
00521 
00522     ResvStateBlock_t *rsb = findRsbById(msg->getId());
00523 
00524     ASSERT(rsb);
00525     ASSERT(tedmod->isLocalAddress(rsb->OI));
00526 
00527     for (unsigned int i = 0; i < rsb->FlowDescriptor.size(); i++)
00528     {
00529         removeRsbFilter(rsb, 0);
00530     }
00531     removeRSB(rsb);
00532 }

void RSVP::processRSVPMessage ( RSVPMessage msg  )  [protected]

01339 {
01340     int kind = msg->getRsvpKind();
01341     switch(kind)
01342     {
01343         case PATH_MESSAGE:
01344             processPathMsg(check_and_cast<RSVPPathMsg*>(msg));
01345             break;
01346 
01347         case RESV_MESSAGE:
01348             processResvMsg(check_and_cast<RSVPResvMsg*>(msg));
01349             break;
01350 
01351         case PTEAR_MESSAGE:
01352             processPathTearMsg(check_and_cast<RSVPPathTear*>(msg));
01353             break;
01354 
01355         case HELLO_MESSAGE:
01356             processHelloMsg(check_and_cast<RSVPHelloMsg*>(msg));
01357             break;
01358 
01359         case PERROR_MESSAGE:
01360             processPathErrMsg(check_and_cast<RSVPPathError*>(msg));
01361             break;
01362 
01363         default:
01364             ASSERT(false);
01365     }
01366 }

void RSVP::processSignallingMessage ( SignallingMsg msg  )  [protected]

01725 {
01726     int command = msg->getCommand();
01727     switch(command)
01728     {
01729         case MSG_PSB_TIMER:
01730             processPSB_TIMER(check_and_cast<PsbTimerMsg*>(msg));
01731             break;
01732 
01733         case MSG_PSB_TIMEOUT:
01734             processPSB_TIMEOUT(check_and_cast<PsbTimeoutMsg*>(msg));
01735             break;
01736 
01737         case MSG_RSB_REFRESH_TIMER:
01738             processRSB_REFRESH_TIMER(check_and_cast<RsbRefreshTimerMsg*>(msg));
01739             break;
01740 
01741         case MSG_RSB_COMMIT_TIMER:
01742             processRSB_COMMIT_TIMER(check_and_cast<RsbCommitTimerMsg*>(msg));
01743             break;
01744 
01745         case MSG_RSB_TIMEOUT:
01746             processRSB_TIMEOUT(check_and_cast<RsbTimeoutMsg*>(msg));
01747             break;
01748 
01749         case MSG_HELLO_TIMER:
01750             processHELLO_TIMER(check_and_cast<HelloTimerMsg*>(msg));
01751             break;
01752 
01753         case MSG_HELLO_TIMEOUT:
01754             processHELLO_TIMEOUT(check_and_cast<HelloTimeoutMsg*>(msg));
01755             break;
01756 
01757         case MSG_PATH_NOTIFY:
01758             processPATH_NOTIFY(check_and_cast<PathNotifyMsg*>(msg));
01759             break;
01760 
01761         default:
01762             ASSERT(false);
01763     }
01764 }

void RSVP::readTrafficFromXML ( const cXMLElement *  traffic  )  [protected]

00148 {
00149     ASSERT(traffic);
00150     ASSERT(!strcmp(traffic->getTagName(), "sessions"));
00151     checkTags(traffic, "session");
00152     cXMLElementList list = traffic->getChildrenByTagName("session");
00153     for (cXMLElementList::iterator it=list.begin(); it != list.end(); it++)
00154         readTrafficSessionFromXML(*it);
00155 }

EroVector RSVP::readTrafficRouteFromXML ( const cXMLElement *  route  )  [protected]

00158 {
00159     checkTags(route, "node lnode");
00160 
00161     EroVector ERO;
00162 
00163     for (cXMLElement *hop = route->getFirstChild(); hop; hop = hop->getNextSibling())
00164     {
00165         EroObj_t h;
00166         if (!strcmp(hop->getTagName(), "node"))
00167         {
00168             h.L = false;
00169             h.node = IPAddressResolver().resolve(hop->getNodeValue()).get4();
00170         }
00171         else if (!strcmp(hop->getTagName(), "lnode"))
00172         {
00173             h.L = true;
00174             h.node = IPAddressResolver().resolve(hop->getNodeValue()).get4();
00175         }
00176         else
00177         {
00178             ASSERT(false);
00179         }
00180         ERO.push_back(h);
00181     }
00182 
00183     return ERO;
00184 }

void RSVP::readTrafficSessionFromXML ( const cXMLElement *  session  )  [protected]

00187 {
00188     checkTags(session, "tunnel_id endpoint setup_pri holding_pri paths");
00189 
00190     traffic_session_t newSession;
00191 
00192     newSession.sobj.Tunnel_Id = getParameterIntValue(session, "tunnel_id");
00193     newSession.sobj.Extended_Tunnel_Id = routerId.getInt();
00194     newSession.sobj.DestAddress = getParameterIPAddressValue(session, "endpoint");
00195 
00196     std::vector<traffic_session_t>::iterator sit = findSession(newSession.sobj);
00197 
00198     bool merge;
00199 
00200     if (sit != traffic.end())
00201     {
00202         // session already exits, add new paths
00203 
00204         merge = true;
00205 
00206         ASSERT(!getUniqueChildIfExists(session, "holding_pri") || getParameterIntValue(session, "holding_pri") == sit->sobj.holdingPri);
00207         ASSERT(!getUniqueChildIfExists(session, "setup_pri") || getParameterIntValue(session, "setup_pri") == sit->sobj.setupPri);
00208 
00209         newSession.sobj.setupPri = sit->sobj.setupPri;
00210         newSession.sobj.holdingPri = sit->sobj.holdingPri;
00211 
00212         sit->sobj = newSession.sobj;
00213     }
00214     else
00215     {
00216         // session not found, create new
00217 
00218         merge = false;
00219 
00220         newSession.sobj.setupPri = getParameterIntValue(session, "setup_pri", 7);
00221         newSession.sobj.holdingPri = getParameterIntValue(session, "holding_pri", 7);
00222     }
00223 
00224     const cXMLElement *paths = getUniqueChild(session, "paths");
00225     checkTags(paths, "path");
00226 
00227     cXMLElementList list = paths->getChildrenByTagName("path");
00228     for (cXMLElementList::iterator it=list.begin(); it != list.end(); it++)
00229     {
00230         cXMLElement *path = *it;
00231         checkTags(path, "sender lspid bandwidth max_delay route permanent owner color");
00232 
00233         int lspid = getParameterIntValue(path, "lspid");;
00234 
00235         std::vector<traffic_path_t>::iterator pit;
00236 
00237         traffic_path_t newPath;
00238 
00239         newPath.sender.SrcAddress = getParameterIPAddressValue(path, "sender", routerId);
00240         newPath.sender.Lsp_Id = lspid;
00241 
00242         // make sure path doesn't exist yet
00243 
00244         if (merge)
00245         {
00246             pit = findPath(&(*sit), newPath.sender);
00247             if (pit != sit->paths.end())
00248             {
00249                 EV << "path " << lspid << " already exists in this session, doing nothing" << endl;
00250                 continue;
00251             }
00252         }
00253         else
00254         {
00255             pit = findPath(&newSession, newPath.sender);
00256             if (pit != newSession.paths.end())
00257             {
00258                 EV << "path " << lspid << " already exists in this session, doing nothing" << endl;
00259                 continue;
00260             }
00261         }
00262 
00263         const char *str = getParameterStrValue(path, "owner", "");
00264         if (strlen(str))
00265         {
00266             cModule *mod = simulation.moduleByPath(str);
00267             newPath.owner = mod->id();
00268         }
00269         else
00270         {
00271             newPath.owner = id();
00272         }
00273 
00274         newPath.permanent = getParameterBoolValue(path, "permanent", true);
00275         newPath.color = getParameterIntValue(path, "color", 0);
00276 
00277         newPath.tspec.req_bandwidth = getParameterDoubleValue(path, "bandwidth", 0.0);
00278         newPath.max_delay = getParameterDoubleValue(path, "max_delay", 0.0);
00279 
00280         const cXMLElement *route = getUniqueChildIfExists(path, "route");
00281         if (route)
00282             newPath.ERO = readTrafficRouteFromXML(route);
00283 
00284         if (merge)
00285         {
00286             EV << "adding new path into an existing session" << endl;
00287 
00288             sit->paths.push_back(newPath);
00289         }
00290         else
00291         {
00292             EV << "adding new path into new session" << endl;
00293 
00294             newSession.paths.push_back(newPath);
00295         }
00296 
00297         // schedule path creation
00298 
00299         sendPathNotify(id(), newSession.sobj, newPath.sender, PATH_RETRY, 0.0);
00300     }
00301 
00302     if (!merge)
00303     {
00304         EV << "adding new session into database" << endl;
00305 
00306         traffic.push_back(newSession);
00307     }
00308 }

void RSVP::recoveryEvent ( IPAddress  peer  )  [protected]

01702 {
01703     // called when peer's operation is restored
01704 
01705     unsigned int index = tedmod->linkIndex(routerId, peer);
01706     bool rtmodified = !tedmod->ted[index].state;
01707     tedmod->ted[index].state = true;
01708     announceLinkChange(index);
01709 
01710     // rebuild routing table if link state changed
01711     if (rtmodified)
01712         tedmod->rebuildRoutingTable();
01713 
01714     // refresh all paths towards this neighbour
01715     for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
01716     {
01717         if (it->OutInterface != tedmod->ted[index].local)
01718             continue;
01719 
01720         scheduleRefreshTimer(&(*it), 0.0);
01721     }
01722 }

void RSVP::refreshPath ( PathStateBlock_t psbEle  )  [protected]

00563 {
00564     EV << "refresh path (PSB " << psbEle->id << ")" << endl;
00565 
00566     IPAddress& OI = psbEle->OutInterface;
00567     EroVector& ERO = psbEle->ERO;
00568 
00569     ASSERT(!OI.isUnspecified());
00570     ASSERT(tedmod->isLocalAddress(OI));
00571 
00572     RSVPPathMsg *pm = new RSVPPathMsg("Path");
00573 
00574     pm->setSession(psbEle->Session_Object);
00575     pm->setSenderTemplate(psbEle->Sender_Template_Object);
00576     pm->setSenderTspec(psbEle->Sender_Tspec_Object);
00577 
00578     RsvpHopObj_t hop;
00579     hop.Logical_Interface_Handle = OI;
00580     hop.Next_Hop_Address = routerId;
00581     pm->setHop(hop);
00582 
00583     pm->setERO(ERO);
00584     pm->setColor(psbEle->color);
00585 
00586     int length = 85 + (ERO.size() * 5);
00587 
00588     pm->setByteLength(length);
00589 
00590     IPAddress nextHop = tedmod->peerByLocalAddress(OI);
00591 
00592     ASSERT(ERO.size() == 0 ||ERO[0].node.equals(nextHop) || ERO[0].L);
00593 
00594     sendToIP(pm, nextHop);
00595 }

void RSVP::refreshResv ( ResvStateBlock_t rsbEle,
IPAddress  PHOP 
) [protected]

00626 {
00627     EV << "refresh reservation (RSB " << rsbEle->id << ") PHOP " << PHOP << endl;
00628 
00629     RSVPResvMsg *msg = new RSVPResvMsg("    Resv");
00630 
00631     FlowDescriptorVector flows;
00632 
00633     msg->setSession(rsbEle->Session_Object);
00634 
00635     RsvpHopObj_t hop;
00636     hop.Logical_Interface_Handle = tedmod->peerRemoteInterface(PHOP);
00637     hop.Next_Hop_Address = PHOP;
00638     msg->setHop(hop);
00639 
00640     for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
00641     {
00642         if (it->Previous_Hop_Address != PHOP)
00643             continue;
00644 
00645         //if (it->LIH != LIH)
00646         //  continue;
00647 
00648         if (it->Session_Object != rsbEle->Session_Object)
00649             continue;
00650 
00651         for (unsigned int c = 0; c < rsbEle->FlowDescriptor.size(); c++)
00652         {
00653             if ((FilterSpecObj_t&)it->Sender_Template_Object != rsbEle->FlowDescriptor[c].Filter_Spec_Object)
00654                 continue;
00655 
00656             ASSERT(rsbEle->inLabelVector.size() == rsbEle->FlowDescriptor.size());
00657 
00658             FlowDescriptor_t flow;
00659             flow.Filter_Spec_Object = (FilterSpecObj_t&)it->Sender_Template_Object;
00660             flow.Flowspec_Object = (FlowSpecObj_t&)it->Sender_Tspec_Object;
00661             flow.RRO = rsbEle->FlowDescriptor[c].RRO;
00662             flow.RRO.push_back(routerId);
00663             flow.label = rsbEle->inLabelVector[c];
00664             flows.push_back(flow);
00665 
00666             break;
00667         }
00668     }
00669 
00670     msg->setFlowDescriptor(flows);
00671 
00672     int fd_length = 0;
00673     for (unsigned int i = 0; i < flows.size(); i++)
00674         fd_length += 28 + (flows[i].RRO.size() * 4);
00675 
00676     int length = 34 + fd_length;
00677 
00678     // see comment elsewhere (in TED.cc)
00679     length /= 10;
00680 
00681     msg->setByteLength(length);
00682 
00683     sendToIP(msg, PHOP);
00684 }

void RSVP::refreshResv ( ResvStateBlock_t rsbEle  )  [protected]

00598 {
00599     EV << "refresh reservation (RSB " << rsbEle->id << ")" << endl;
00600 
00601     IPAddressVector phops;
00602 
00603     for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
00604     {
00605         if (it->OutInterface != rsbEle->OI)
00606             continue;
00607 
00608         for (int i = 0; i < rsbEle->FlowDescriptor.size(); i++)
00609         {
00610             if ((FilterSpecObj_t&)it->Sender_Template_Object != rsbEle->FlowDescriptor[i].Filter_Spec_Object)
00611                 continue;
00612 
00613             if (tedmod->isLocalAddress(it->Previous_Hop_Address))
00614                 continue; // IR nothing to refresh
00615 
00616             if (!find(phops, it->Previous_Hop_Address))
00617                 phops.push_back(it->Previous_Hop_Address);
00618         }
00619 
00620         for (IPAddressVector::iterator it = phops.begin(); it != phops.end(); it++)
00621             refreshResv(rsbEle, *it);
00622     }
00623 }

void RSVP::removePSB ( PathStateBlock_t psb  )  [protected]

01076 {
01077     ASSERT(psb);
01078 
01079     int lspid = psb->Sender_Template_Object.Lsp_Id;
01080 
01081     EV << "removing PSB " << psb->id << " (lspid " << lspid << ")" << endl;
01082 
01083     // remove reservation state if exists **************************************
01084 
01085     unsigned int filterIndex;
01086     ResvStateBlock_t *rsb = findRSB(psb->Session_Object, psb->Sender_Template_Object, filterIndex);
01087     if (rsb)
01088     {
01089         EV << "reservation state present, will be removed too" << endl;
01090 
01091         removeRsbFilter(rsb, filterIndex);
01092     }
01093 
01094     // proceed with actual removal *********************************************
01095 
01096     cancelEvent(psb->timerMsg);
01097     cancelEvent(psb->timeoutMsg);
01098 
01099     delete psb->timerMsg;
01100     delete psb->timeoutMsg;
01101 
01102     for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
01103     {
01104         if (it->id != psb->id)
01105             continue;
01106 
01107         PSBList.erase(it);
01108         return;
01109     }
01110     ASSERT(false);
01111 }

void RSVP::removeRSB ( ResvStateBlock_t rsb  )  [protected]

01044 {
01045     ASSERT(rsb);
01046     ASSERT(rsb->FlowDescriptor.size() == 0);
01047 
01048     EV << "removing empty RSB " << rsb->id << endl;
01049 
01050     cancelEvent(rsb->refreshTimerMsg);
01051     cancelEvent(rsb->commitTimerMsg);
01052     cancelEvent(rsb->timeoutMsg);
01053 
01054     delete rsb->refreshTimerMsg;
01055     delete rsb->commitTimerMsg;
01056     delete rsb->timeoutMsg;
01057 
01058     if (rsb->Flowspec_Object.req_bandwidth > 0)
01059     {
01060         // deallocate resources
01061         allocateResource(rsb->OI, rsb->Session_Object, -rsb->Flowspec_Object.req_bandwidth);
01062     }
01063 
01064     for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
01065     {
01066         if (it->id != rsb->id)
01067             continue;
01068 
01069         RSBList.erase(it);
01070         return;
01071     }
01072     ASSERT(false);
01073 }

void RSVP::removeRsbFilter ( ResvStateBlock_t rsb,
unsigned int  index 
) [protected]

01024 {
01025     ASSERT(rsb);
01026     ASSERT(index < rsb->FlowDescriptor.size());
01027     ASSERT(rsb->inLabelVector.size() == rsb->FlowDescriptor.size());
01028 
01029     int lspid = rsb->FlowDescriptor[index].Filter_Spec_Object.Lsp_Id;
01030     int inLabel = rsb->inLabelVector[index];
01031 
01032     EV << "removing filter (lspid=" << lspid << ")" << endl;
01033 
01034     if (inLabel != -1)
01035         lt->removeLibEntry(inLabel);
01036 
01037     rsb->FlowDescriptor.erase(rsb->FlowDescriptor.begin() + index);
01038     rsb->inLabelVector.erase(rsb->inLabelVector.begin() + index);
01039 
01040     scheduleCommitTimer(rsb);
01041 }

void RSVP::scheduleCommitTimer ( ResvStateBlock_t rsbEle  )  [protected]

02055 {
02056     ASSERT(rsbEle);
02057 
02058     if (rsbEle->commitTimerMsg->isScheduled())
02059         cancelEvent(rsbEle->commitTimerMsg);
02060 
02061     scheduleAt(simTime(), rsbEle->commitTimerMsg);
02062 }

void RSVP::scheduleRefreshTimer ( ResvStateBlock_t rsbEle,
double  delay 
) [protected]

02045 {
02046     ASSERT(rsbEle);
02047 
02048     if (rsbEle->refreshTimerMsg->isScheduled())
02049         cancelEvent(rsbEle->refreshTimerMsg);
02050 
02051     scheduleAt(simTime() + delay, rsbEle->refreshTimerMsg);
02052 }

void RSVP::scheduleRefreshTimer ( PathStateBlock_t psbEle,
double  delay 
) [protected]

02017 {
02018     ASSERT(psbEle);
02019 
02020     if (psbEle->OutInterface.isUnspecified())
02021         return;
02022 
02023     if (!tedmod->isLocalAddress(psbEle->OutInterface))
02024         return;
02025 
02026     if (psbEle->timerMsg->isScheduled())
02027         cancelEvent(psbEle->timerMsg);
02028 
02029     EV << "scheduling PSB " << psbEle->id << " refresh " << (simTime() + delay) << endl;
02030 
02031     scheduleAt(simTime() + delay, psbEle->timerMsg);
02032 }

void RSVP::scheduleTimeout ( ResvStateBlock_t rsbEle  )  [protected]

02035 {
02036     ASSERT(rsbEle);
02037 
02038     if (rsbEle->timeoutMsg->isScheduled())
02039         cancelEvent(rsbEle->timeoutMsg);
02040 
02041     scheduleAt(simTime() + RSB_TIMEOUT_INTERVAL, rsbEle->timeoutMsg);
02042 }

void RSVP::scheduleTimeout ( PathStateBlock_t psbEle  )  [protected]

02007 {
02008     ASSERT(psbEle);
02009 
02010     if (psbEle->timeoutMsg->isScheduled())
02011         cancelEvent(psbEle->timeoutMsg);
02012 
02013     scheduleAt(simTime() + PSB_TIMEOUT_INTERVAL, psbEle->timeoutMsg);
02014 }

void RSVP::sendPathErrorMessage ( SessionObj_t  session,
SenderTemplateObj_t  sender,
SenderTspecObj_t  tspec,
IPAddress  nextHop,
int  errCode 
) [protected]

01975 {
01976     RSVPPathError *msg = new RSVPPathError("PathErr");
01977     msg->setErrorCode(errCode);
01978     msg->setErrorNode(routerId);
01979     msg->setSession(session);
01980     msg->setSenderTemplate(sender);
01981     msg->setSenderTspec(tspec);
01982 
01983     int length = 52;
01984 
01985     // see comment elsewhere (in TED.cc)
01986     length /= 10;
01987 
01988     msg->setByteLength(length);
01989 
01990     sendToIP(msg, nextHop);
01991 }

void RSVP::sendPathErrorMessage ( PathStateBlock_t psb,
int  errCode 
) [protected]

01970 {
01971     sendPathErrorMessage(psb->Session_Object, psb->Sender_Template_Object, psb->Sender_Tspec_Object, psb->Previous_Hop_Address, errCode);
01972 }

void RSVP::sendPathNotify ( int  handler,
const SessionObj_t session,
const SenderTemplateObj_t sender,
int  status,
double  delay 
) [protected]

00388 {
00389     if (handler < 0)
00390         return; // handler not specified
00391 
00392     cModule *mod = simulation.module(handler);
00393 
00394     if (!mod)
00395         return; // handler no longer exists
00396 
00397     PathNotifyMsg *msg = new PathNotifyMsg("path notify");
00398 
00399     msg->setSession(session);
00400     msg->setSender(sender);
00401     msg->setStatus(status);
00402 
00403     if (handler == id())
00404         scheduleAt(simTime() + delay, msg);
00405     else
00406         sendDirect(msg, delay, mod, "from_rsvp");
00407 }

void RSVP::sendPathTearMessage ( IPAddress  peerIP,
const SessionObj_t session,
const SenderTemplateObj_t sender,
IPAddress  LIH,
IPAddress  NHOP,
bool  force 
) [protected]

01952 {
01953     RSVPPathTear *msg = new RSVPPathTear("PathTear");
01954     msg->setSenderTemplate(sender);
01955     msg->setSession(session);
01956     RsvpHopObj_t hop;
01957     hop.Logical_Interface_Handle = LIH;
01958     hop.Next_Hop_Address = NHOP;
01959     msg->setHop(hop);
01960     msg->setForce(force);
01961 
01962     int length = 44;
01963 
01964     msg->setByteLength(length);
01965 
01966     sendToIP(msg, peerIP);
01967 }

void RSVP::sendToIP ( cMessage *  msg,
IPAddress  destAddr 
) [protected]

01995 {
01996     IPControlInfo *controlInfo = new IPControlInfo();
01997     controlInfo->setDestAddr(destAddr);
01998     controlInfo->setProtocol(IP_PROT_RSVP);
01999     msg->setControlInfo(controlInfo);
02000 
02001     msg->addPar("color") = RSVP_TRAFFIC;
02002 
02003     send(msg, "to_ip");
02004 }

void RSVP::setupHello (  )  [protected]

00324 {
00325     helloInterval = par("helloInterval").doubleValue();
00326     helloTimeout = par("helloTimeout").doubleValue();
00327 
00328     cStringTokenizer tokenizer(par("peers"));
00329     const char *token;
00330     while ((token = tokenizer.nextToken())!=NULL)
00331     {
00332         ASSERT(ift->interfaceByName(token));
00333 
00334         IPAddress peer = tedmod->peerByLocalAddress(ift->interfaceByName(token)->ipv4()->inetAddress());
00335 
00336         HelloState_t h;
00337 
00338         h.timer = new HelloTimerMsg("hello timer");
00339         h.timer->setPeer(peer);
00340 
00341         h.timeout = new HelloTimeoutMsg("hello timeout");
00342         h.timeout->setPeer(peer);
00343 
00344         h.peer = peer;
00345 
00346         if (helloInterval > 0.0)
00347         {
00348             // peer is down until we know he is ok
00349 
00350             h.ok = false;
00351         }
00352         else
00353         {
00354             // don't use HELLO at all, consider all peers running all the time
00355 
00356             h.ok = true;
00357         }
00358 
00359         HelloList.push_back(h);
00360 
00361         if (helloInterval > 0.0)
00362         {
00363             startHello(peer, exponential(helloInterval));
00364         }
00365     }
00366 }

void RSVP::startHello ( IPAddress  peer,
double  delay 
) [protected]

00369 {
00370     EV << "scheduling hello start in " << delay << " seconds" << endl;
00371 
00372     HelloState_t *h = findHello(peer);
00373     ASSERT(h);
00374 
00375     ASSERT(!h->timer->isScheduled());
00376     ASSERT(!h->timeout->isScheduled());
00377     ASSERT(!h->ok);
00378 
00379     h->srcInstance = ++maxSrcInstance;
00380     h->dstInstance = 0;
00381     h->request = true;
00382     h->ack = false;
00383 
00384     scheduleAt(simTime() + delay, h->timer);
00385 }

void RSVP::updateRSB ( ResvStateBlock_t rsb,
RSVPResvMsg msg 
) [protected]

00978 {
00979     ASSERT(rsb);
00980 
00981     for (unsigned int k = 0; k < msg->getFlowDescriptor().size(); k++)
00982     {
00983         FlowDescriptor_t flow = msg->getFlowDescriptor()[k];
00984 
00985         unsigned int m;
00986         for (m = 0; m < rsb->FlowDescriptor.size(); m++)
00987         {
00988             if (rsb->FlowDescriptor[m].Filter_Spec_Object == flow.Filter_Spec_Object)
00989             {
00990                 // sender found
00991                 EV << "sender (lspid=" << flow.Filter_Spec_Object.Lsp_Id << ") found in RSB" << endl;
00992 
00993                 if (rsb->FlowDescriptor[m].label != flow.label)
00994                 {
00995                     EV << "label modified (new label="  << flow.label << ")" << endl;
00996 
00997                     rsb->FlowDescriptor[m].label = flow.label;
00998 
00999                     // label must be updated in lib table
01000 
01001                     scheduleCommitTimer(rsb);
01002                 }
01003 
01004                 break;
01005             }
01006         }
01007         if (m == rsb->FlowDescriptor.size())
01008         {
01009             // sender not found
01010             EV << "sender (lspid=" << flow.Filter_Spec_Object.Lsp_Id << ") not found in RSB, adding..." << endl;
01011 
01012             rsb->FlowDescriptor.push_back(flow);
01013             rsb->inLabelVector.push_back(-1);
01014 
01015             // resv is new and must be forwarded
01016 
01017             scheduleCommitTimer(rsb);
01018             scheduleRefreshTimer(rsb, 0.0);
01019         }
01020     }
01021 }


Friends And Related Function Documentation

friend class SimpleClassifier [friend]


Member Data Documentation

double RSVP::helloInterval [private]

HelloVector RSVP::HelloList [private]

double RSVP::helloTimeout [private]

InterfaceTable* RSVP::ift [private]

LIBTable* RSVP::lt [private]

int RSVP::maxPsbId [private]

int RSVP::maxRsbId [private]

int RSVP::maxSrcInstance [private]

NotificationBoard* RSVP::nb [private]

PSBVector RSVP::PSBList [private]

double RSVP::retryInterval [private]

IPAddress RSVP::routerId [private]

IRSVPClassifier* RSVP::rpct [private]

RSBVector RSVP::RSBList [private]

RoutingTable* RSVP::rt [private]

TED* RSVP::tedmod [private]

std::vector<traffic_session_t> RSVP::traffic [private]


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:20:23 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7