INET Framework for OMNeT++/OMNEST
inet::AODVRouting Class Reference

#include <AODVRouting.h>

Inheritance diagram for inet::AODVRouting:
inet::ILifecycle inet::INetfilter::IHook

Classes

class  RREQIdentifier
 
class  RREQIdentifierCompare
 

Public Member Functions

 AODVRouting ()
 
virtual ~AODVRouting ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::INetfilter::IHook
virtual ~IHook ()
 

Protected Member Functions

void handleMessage (cMessage *msg) override
 
void initialize (int stage) override
 
virtual int numInitStages () const override
 
void startRouteDiscovery (const L3Address &target, unsigned int timeToLive=0)
 
void completeRouteDiscovery (const L3Address &target)
 
bool hasOngoingRouteDiscovery (const L3Address &destAddr)
 
void cancelRouteDiscovery (const L3Address &destAddr)
 
void updateRoutingTable (IRoute *route, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
 
IRoutecreateRoute (const L3Address &destAddr, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
 
bool updateValidRouteLifeTime (const L3Address &destAddr, simtime_t lifetime)
 
void scheduleExpungeRoutes ()
 
void expungeRoutes ()
 
AODVRREPACKcreateRREPACK ()
 
AODVRREPcreateHelloMessage ()
 
AODVRREQcreateRREQ (const L3Address &destAddr)
 
AODVRREPcreateRREP (AODVRREQ *rreq, IRoute *destRoute, IRoute *originatorRoute, const L3Address &sourceAddr)
 
AODVRREPcreateGratuitousRREP (AODVRREQ *rreq, IRoute *originatorRoute)
 
AODVRERRcreateRERR (const std::vector< UnreachableNode > &unreachableNodes)
 
void handleRREP (AODVRREP *rrep, const L3Address &sourceAddr)
 
void handleRREQ (AODVRREQ *rreq, const L3Address &sourceAddr, unsigned int timeToLive)
 
void handleRERR (AODVRERR *rerr, const L3Address &sourceAddr)
 
void handleHelloMessage (AODVRREP *helloMessage)
 
void handleRREPACK (AODVRREPACK *rrepACK, const L3Address &neighborAddr)
 
void sendRREQ (AODVRREQ *rreq, const L3Address &destAddr, unsigned int timeToLive)
 
void sendRREPACK (AODVRREPACK *rrepACK, const L3Address &destAddr)
 
void sendRREP (AODVRREP *rrep, const L3Address &destAddr, unsigned int timeToLive)
 
void sendGRREP (AODVRREP *grrep, const L3Address &destAddr, unsigned int timeToLive)
 
void forwardRREP (AODVRREP *rrep, const L3Address &destAddr, unsigned int timeToLive)
 
void forwardRREQ (AODVRREQ *rreq, unsigned int timeToLive)
 
void handleRREPACKTimer ()
 
void handleBlackListTimer ()
 
void sendHelloMessagesIfNeeded ()
 
void handleWaitForRREP (WaitForRREP *rrepTimer)
 
void sendRERRWhenNoRouteToForward (const L3Address &unreachableAddr)
 
void handleLinkBreakSendRERR (const L3Address &unreachableAddr)
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
Result ensureRouteForDatagram (INetworkDatagram *datagram)
 
virtual Result datagramPreRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the first hook called by the network protocol before it routes a datagram that was received from the lower layer. More...
 
virtual Result datagramForwardHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the second hook called by the network protocol before it sends a datagram to the lower layer. More...
 
virtual Result datagramPostRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the last hook called by the network protocol before it sends a datagram to the lower layer. More...
 
virtual Result datagramLocalInHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry) override
 This is the last hook called by the network protocol before it sends a datagram to the upper layer. More...
 
virtual Result datagramLocalOutHook (INetworkDatagram *datagram, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the first hook called by the network protocol before it routes a datagram that was received from the upper layer. More...
 
void delayDatagram (INetworkDatagram *datagram)
 
L3Address getSelfIPAddress () const
 
void sendAODVPacket (AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
 
void clearState ()
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 

Protected Attributes

IL3AddressTypeaddressType = nullptr
 
cModule * host = nullptr
 
IRoutingTableroutingTable = nullptr
 
IInterfaceTableinterfaceTable = nullptr
 
INetfilternetworkProtocol = nullptr
 
unsigned int rerrRatelimit = 0
 
unsigned int aodvUDPPort = 0
 
bool askGratuitousRREP = false
 
bool useHelloMessages = false
 
simtime_t maxJitter
 
simtime_t activeRouteTimeout
 
simtime_t helloInterval
 
unsigned int netDiameter = 0
 
unsigned int rreqRetries = 0
 
unsigned int rreqRatelimit = 0
 
unsigned int timeoutBuffer = 0
 
unsigned int ttlStart = 0
 
unsigned int ttlIncrement = 0
 
unsigned int ttlThreshold = 0
 
unsigned int localAddTTL = 0
 
unsigned int allowedHelloLoss = 0
 
simtime_t nodeTraversalTime
 
cPar * jitterPar = nullptr
 
cPar * periodicJitter = nullptr
 
simtime_t deletePeriod
 
simtime_t myRouteTimeout
 
simtime_t blacklistTimeout
 
simtime_t netTraversalTime
 
simtime_t nextHopWait
 
simtime_t pathDiscoveryTime
 
unsigned int rreqId = 0
 
unsigned int sequenceNum = 0
 
std::map< L3Address, WaitForRREP * > waitForRREPTimers
 
std::map< RREQIdentifier, simtime_t, RREQIdentifierComparerreqsArrivalTime
 
L3Address failedNextHop
 
std::map< L3Address, simtime_t > blacklist
 
unsigned int rerrCount = 0
 
unsigned int rreqCount = 0
 
simtime_t lastBroadcastTime
 
std::map< L3Address, unsigned int > addressToRreqRetries
 
cMessage * helloMsgTimer = nullptr
 
cMessage * expungeTimer = nullptr
 
cMessage * counterTimer = nullptr
 
cMessage * rrepAckTimer = nullptr
 
cMessage * blacklistTimer = nullptr
 
simtime_t rebootTime
 
bool isOperational = false
 
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
 

Additional Inherited Members

- Public Types inherited from inet::INetfilter::IHook
enum  Type {
  PREROUTING, LOCALIN, FORWARD, POSTROUTING,
  LOCALOUT
}
 
enum  Result { ACCEPT, DROP, QUEUE, STOLEN }
 

Constructor & Destructor Documentation

inet::AODVRouting::AODVRouting ( )
246 {
247 }
inet::AODVRouting::~AODVRouting ( )
virtual
1718 {
1719  clearState();
1720  delete helloMsgTimer;
1721  delete expungeTimer;
1722  delete counterTimer;
1723  delete rrepAckTimer;
1724  delete blacklistTimer;
1725 }
cMessage * expungeTimer
Definition: AODVRouting.h:123
cMessage * rrepAckTimer
Definition: AODVRouting.h:125
cMessage * helloMsgTimer
Definition: AODVRouting.h:122
cMessage * blacklistTimer
Definition: AODVRouting.h:126
cMessage * counterTimer
Definition: AODVRouting.h:124
void clearState()
Definition: AODVRouting.cc:1259

Member Function Documentation

void inet::AODVRouting::cancelRouteDiscovery ( const L3Address destAddr)
protected

Referenced by handleWaitForRREP().

1620 {
1621  ASSERT(hasOngoingRouteDiscovery(destAddr));
1622  auto lt = targetAddressToDelayedPackets.lower_bound(destAddr);
1623  auto ut = targetAddressToDelayedPackets.upper_bound(destAddr);
1624  for (auto it = lt; it != ut; it++)
1625  networkProtocol->dropQueuedDatagram(const_cast<const INetworkDatagram *>(it->second));
1626 
1627  targetAddressToDelayedPackets.erase(lt, ut);
1628 
1629  auto waitRREPIter = waitForRREPTimers.find(destAddr);
1630  ASSERT(waitRREPIter != waitForRREPTimers.end());
1631  cancelAndDelete(waitRREPIter->second);
1632  waitForRREPTimers.erase(waitRREPIter);
1633 }
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: AODVRouting.h:133
std::map< L3Address, WaitForRREP * > waitForRREPTimers
Definition: AODVRouting.h:112
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
virtual void dropQueuedDatagram(const INetworkDatagram *daragram)=0
Requests the network layer to drop the datagram, because it&#39;s no longer needed.
INetfilter * networkProtocol
Definition: AODVRouting.h:77
void inet::AODVRouting::clearState ( )
protected

Referenced by handleOperationStage(), and ~AODVRouting().

1260 {
1262  addressToRreqRetries.clear();
1263  for (auto & elem : waitForRREPTimers)
1264  cancelAndDelete(elem.second);
1265 
1266  // FIXME: Drop the queued datagrams.
1267  //for (auto it = targetAddressToDelayedPackets.begin(); it != targetAddressToDelayedPackets.end(); it++)
1268  // networkProtocol->dropQueuedDatagram(const_cast<const INetworkDatagram *>(it->second));
1269 
1271 
1272  waitForRREPTimers.clear();
1273  rreqsArrivalTime.clear();
1274 
1275  if (useHelloMessages)
1276  cancelEvent(helloMsgTimer);
1277  if (expungeTimer)
1278  cancelEvent(expungeTimer);
1279  if (counterTimer)
1280  cancelEvent(counterTimer);
1281  if (blacklistTimer)
1282  cancelEvent(blacklistTimer);
1283  if (rrepAckTimer)
1284  cancelEvent(rrepAckTimer);
1285 }
cMessage * expungeTimer
Definition: AODVRouting.h:123
unsigned int sequenceNum
Definition: AODVRouting.h:111
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: AODVRouting.h:133
unsigned int rreqId
Definition: AODVRouting.h:110
cMessage * rrepAckTimer
Definition: AODVRouting.h:125
std::map< L3Address, WaitForRREP * > waitForRREPTimers
Definition: AODVRouting.h:112
unsigned int rreqCount
Definition: AODVRouting.h:117
cMessage * helloMsgTimer
Definition: AODVRouting.h:122
std::map< L3Address, unsigned int > addressToRreqRetries
Definition: AODVRouting.h:119
cMessage * blacklistTimer
Definition: AODVRouting.h:126
std::map< RREQIdentifier, simtime_t, RREQIdentifierCompare > rreqsArrivalTime
Definition: AODVRouting.h:113
cMessage * counterTimer
Definition: AODVRouting.h:124
unsigned int rerrCount
Definition: AODVRouting.h:116
bool useHelloMessages
Definition: AODVRouting.h:83
void inet::AODVRouting::completeRouteDiscovery ( const L3Address target)
protected

Referenced by handleRREP().

1327 {
1328  EV_DETAIL << "Completing route discovery, originator " << getSelfIPAddress() << ", target " << target << endl;
1329  ASSERT(hasOngoingRouteDiscovery(target));
1330 
1331  auto lt = targetAddressToDelayedPackets.lower_bound(target);
1332  auto ut = targetAddressToDelayedPackets.upper_bound(target);
1333 
1334  // reinject the delayed datagrams
1335  for (auto it = lt; it != ut; it++) {
1336  INetworkDatagram *datagram = it->second;
1337  EV_DETAIL << "Sending queued datagram: source " << datagram->getSourceAddress() << ", destination " << datagram->getDestinationAddress() << endl;
1338  networkProtocol->reinjectQueuedDatagram(const_cast<const INetworkDatagram *>(datagram));
1339  }
1340 
1341  // clear the multimap
1342  targetAddressToDelayedPackets.erase(lt, ut);
1343 
1344  // we have a route for the destination, thus we must cancel the WaitForRREPTimer events
1345  auto waitRREPIter = waitForRREPTimers.find(target);
1346  ASSERT(waitRREPIter != waitForRREPTimers.end());
1347  cancelAndDelete(waitRREPIter->second);
1348  waitForRREPTimers.erase(waitRREPIter);
1349 }
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: AODVRouting.h:133
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
std::map< L3Address, WaitForRREP * > waitForRREPTimers
Definition: AODVRouting.h:112
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
INetfilter * networkProtocol
Definition: AODVRouting.h:77
virtual void reinjectQueuedDatagram(const INetworkDatagram *datagram)=0
Requests the network layer to restart the processing of the datagram.
AODVRREP * inet::AODVRouting::createGratuitousRREP ( AODVRREQ rreq,
IRoute originatorRoute 
)
protected

Referenced by handleRREQ().

518 {
519  ASSERT(originatorRoute != nullptr);
520  AODVRREP *grrep = new AODVRREP("AODV-GRREP");
521  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(originatorRoute->getProtocolData());
522 
523  // Hop Count The Hop Count as indicated in the
524  // node's route table entry for the
525  // originator
526  //
527  // Destination IP Address The IP address of the node that
528  // originated the RREQ
529  //
530  // Destination Sequence Number The Originator Sequence Number from
531  // the RREQ
532  //
533  // Originator IP Address The IP address of the Destination
534  // node in the RREQ
535  //
536  // Lifetime The remaining lifetime of the route
537  // towards the originator of the RREQ,
538  // as known by the intermediate node.
539 
540  grrep->setPacketType(RREP);
541  grrep->setHopCount(originatorRoute->getMetric());
542  grrep->setDestAddr(rreq->getOriginatorAddr());
543  grrep->setDestSeqNum(rreq->getOriginatorSeqNum());
544  grrep->setOriginatorAddr(rreq->getDestAddr());
545  grrep->setLifeTime(routeData->getLifeTime());
546 
547  grrep->setByteLength(20);
548  return grrep;
549 }
Definition: AODVControlPackets_m.h:69
AODVRREP * inet::AODVRouting::createHelloMessage ( )
protected

Referenced by sendHelloMessagesIfNeeded().

1362 {
1363  // called a Hello message, with the RREP
1364  // message fields set as follows:
1365  //
1366  // Destination IP Address The node's IP address.
1367  //
1368  // Destination Sequence Number The node's latest sequence number.
1369  //
1370  // Hop Count 0
1371  //
1372  // Lifetime ALLOWED_HELLO_LOSS *HELLO_INTERVAL
1373 
1374  AODVRREP *helloMessage = new AODVRREP("AODV-HelloMsg");
1375  helloMessage->setPacketType(RREP);
1376  helloMessage->setDestAddr(getSelfIPAddress());
1377  helloMessage->setDestSeqNum(sequenceNum);
1378  helloMessage->setHopCount(0);
1379  helloMessage->setLifeTime(allowedHelloLoss * helloInterval);
1380  helloMessage->setByteLength(20);
1381 
1382  return helloMessage;
1383 }
unsigned int sequenceNum
Definition: AODVRouting.h:111
Definition: AODVControlPackets_m.h:69
unsigned int allowedHelloLoss
Definition: AODVRouting.h:95
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
simtime_t helloInterval
Definition: AODVRouting.h:86
AODVRERR * inet::AODVRouting::createRERR ( const std::vector< UnreachableNode > &  unreachableNodes)
protected

Referenced by handleLinkBreakSendRERR(), handleRERR(), and sendRERRWhenNoRouteToForward().

1145 {
1146  AODVRERR *rerr = new AODVRERR("AODV-RERR");
1147  unsigned int destCount = unreachableNodes.size();
1148 
1149  rerr->setPacketType(RERR);
1150  rerr->setDestCount(destCount);
1151  rerr->setUnreachableNodesArraySize(destCount);
1152 
1153  for (unsigned int i = 0; i < destCount; i++) {
1154  UnreachableNode node;
1155  node.addr = unreachableNodes[i].addr;
1156  node.seqNum = unreachableNodes[i].seqNum;
1157  rerr->setUnreachableNodes(i, node);
1158  }
1159 
1160  rerr->setByteLength(4 + 4 * 2 * destCount);
1161  return rerr;
1162 }
Definition: AODVControlPackets_m.h:70
IRoute * inet::AODVRouting::createRoute ( const L3Address destAddr,
const L3Address nextHop,
unsigned int  hopCount,
bool  hasValidDestNum,
unsigned int  destSeqNum,
bool  isActive,
simtime_t  lifeTime 
)
protected

Referenced by handleHelloMessage(), handleRREP(), and handleRREQ().

972 {
973  IRoute *newRoute = routingTable->createRoute();
974  AODVRouteData *newProtocolData = new AODVRouteData();
975 
976  newProtocolData->setHasValidDestNum(hasValidDestNum);
977 
978  // active route
979  newProtocolData->setIsActive(isActive);
980 
981  // A route towards a destination that has a routing table entry
982  // that is marked as valid. Only active routes can be used to
983  // forward data packets.
984 
985  newProtocolData->setLifeTime(lifeTime);
986  newProtocolData->setDestSeqNum(destSeqNum);
987 
988  InterfaceEntry *ifEntry = interfaceTable->getInterfaceByName("wlan0"); // TODO: IMPLEMENT: multiple interfaces
989  if (ifEntry)
990  newRoute->setInterface(ifEntry);
991 
992  newRoute->setDestination(destAddr);
993  newRoute->setSourceType(IRoute::AODV);
994  newRoute->setSource(this);
995  newRoute->setProtocolData(newProtocolData);
996  newRoute->setMetric(hopCount);
997  newRoute->setNextHop(nextHop);
998  newRoute->setPrefixLength(addressType->getMaxPrefixLength()); // TODO:
999 
1000  EV_DETAIL << "Adding new route " << newRoute << endl;
1001  routingTable->addRoute(newRoute);
1003  return newRoute;
1004 }
IL3AddressType * addressType
Definition: AODVRouting.h:71
IInterfaceTable * interfaceTable
Definition: AODVRouting.h:76
virtual void addRoute(IRoute *entry)=0
Adds a route to the routing table.
virtual InterfaceEntry * getInterfaceByName(const char *name) const =0
Returns an interface given by its name.
void scheduleExpungeRoutes()
Definition: AODVRouting.cc:1490
virtual IRoute * createRoute()=0
managed by AODV routing
Definition: IRoute.h:52
IRoutingTable * routingTable
Definition: AODVRouting.h:75
virtual int getMaxPrefixLength() const =0
AODVRREP * inet::AODVRouting::createRREP ( AODVRREQ rreq,
IRoute destRoute,
IRoute originatorRoute,
const L3Address sourceAddr 
)
protected

Referenced by handleRREQ().

438 {
439  AODVRREP *rrep = new AODVRREP("AODV-RREP");
440  rrep->setPacketType(RREP);
441 
442  // When generating a RREP message, a node copies the Destination IP
443  // Address and the Originator Sequence Number from the RREQ message into
444  // the corresponding fields in the RREP message.
445 
446  rrep->setDestAddr(rreq->getDestAddr());
447  rrep->setOriginatorSeqNum(rreq->getOriginatorSeqNum());
448 
449  // OriginatorAddr = The IP address of the node which originated the RREQ
450  // for which the route is supplied.
451  rrep->setOriginatorAddr(rreq->getOriginatorAddr());
452 
453  // Processing is slightly different, depending on whether the node is
454  // itself the requested destination (see section 6.6.1), or instead
455  // if it is an intermediate node with an fresh enough route to the destination
456  // (see section 6.6.2).
457 
458  if (rreq->getDestAddr() == getSelfIPAddress()) { // node is itself the requested destination
459  // If the generating node is the destination itself, it MUST increment
460  // its own sequence number by one if the sequence number in the RREQ
461  // packet is equal to that incremented value.
462 
463  if (!rreq->getUnknownSeqNumFlag() && sequenceNum + 1 == rreq->getDestSeqNum())
464  sequenceNum++;
465 
466  // The destination node places its (perhaps newly incremented)
467  // sequence number into the Destination Sequence Number field of
468  // the RREP,
469  rrep->setDestSeqNum(sequenceNum);
470 
471  // and enters the value zero in the Hop Count field
472  // of the RREP.
473  rrep->setHopCount(0);
474 
475  // The destination node copies the value MY_ROUTE_TIMEOUT
476  // into the Lifetime field of the RREP.
477  rrep->setLifeTime(myRouteTimeout);
478  }
479  else { // intermediate node
480  // it copies its known sequence number for the destination into
481  // the Destination Sequence Number field in the RREP message.
482  AODVRouteData *destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
483  AODVRouteData *originatorRouteData = check_and_cast<AODVRouteData *>(originatorRoute->getProtocolData());
484  rrep->setDestSeqNum(destRouteData->getDestSeqNum());
485 
486  // The intermediate node updates the forward route entry by placing the
487  // last hop node (from which it received the RREQ, as indicated by the
488  // source IP address field in the IP header) into the precursor list for
489  // the forward route entry -- i.e., the entry for the Destination IP
490  // Address.
491  destRouteData->addPrecursor(lastHopAddr);
492 
493  // The intermediate node also updates its route table entry
494  // for the node originating the RREQ by placing the next hop towards the
495  // destination in the precursor list for the reverse route entry --
496  // i.e., the entry for the Originator IP Address field of the RREQ
497  // message data.
498 
499  originatorRouteData->addPrecursor(destRoute->getNextHopAsGeneric());
500 
501  // The intermediate node places its distance in hops from the
502  // destination (indicated by the hop count in the routing table)
503  // Hop Count field in the RREP.
504 
505  rrep->setHopCount(destRoute->getMetric());
506 
507  // The Lifetime field of the RREP is calculated by subtracting the
508  // current time from the expiration time in its route table entry.
509 
510  rrep->setLifeTime(destRouteData->getLifeTime() - simTime());
511  }
512 
513  rrep->setByteLength(20);
514  return rrep;
515 }
unsigned int sequenceNum
Definition: AODVRouting.h:111
Definition: AODVControlPackets_m.h:69
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
simtime_t myRouteTimeout
Definition: AODVRouting.h:103
AODVRREPACK * inet::AODVRouting::createRREPACK ( )
protected

Referenced by handleRREP().

1651 {
1652  AODVRREPACK *rrepACK = new AODVRREPACK("AODV-RREPACK");
1653  rrepACK->setPacketType(RREPACK);
1654  rrepACK->setByteLength(2);
1655  return rrepACK;
1656 }
Definition: AODVControlPackets_m.h:71
AODVRREQ * inet::AODVRouting::createRREQ ( const L3Address destAddr)
protected

Referenced by handleWaitForRREP(), and startRouteDiscovery().

383 {
384  AODVRREQ *rreqPacket = new AODVRREQ("AODV-RREQ");
385 
386  rreqPacket->setGratuitousRREPFlag(askGratuitousRREP);
387  IRoute *lastKnownRoute = routingTable->findBestMatchingRoute(destAddr);
388 
389  rreqPacket->setPacketType(RREQ);
390 
391  // The Originator Sequence Number in the RREQ message is the
392  // node's own sequence number, which is incremented prior to
393  // insertion in a RREQ.
394  sequenceNum++;
395 
396  rreqPacket->setOriginatorSeqNum(sequenceNum);
397 
398  if (lastKnownRoute && lastKnownRoute->getSource() == this) {
399  // The Destination Sequence Number field in the RREQ message is the last
400  // known destination sequence number for this destination and is copied
401  // from the Destination Sequence Number field in the routing table.
402 
403  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(lastKnownRoute->getProtocolData());
404  if (routeData && routeData->hasValidDestNum()) {
405  rreqPacket->setDestSeqNum(routeData->getDestSeqNum());
406  rreqPacket->setUnknownSeqNumFlag(false);
407  }
408  else
409  rreqPacket->setUnknownSeqNumFlag(true);
410  }
411  else
412  rreqPacket->setUnknownSeqNumFlag(true); // If no sequence number is known, the unknown sequence number flag MUST be set.
413 
414  rreqPacket->setOriginatorAddr(getSelfIPAddress());
415  rreqPacket->setDestAddr(destAddr);
416 
417  // The RREQ ID field is incremented by one from the last RREQ ID used
418  // by the current node. Each node maintains only one RREQ ID.
419  rreqId++;
420  rreqPacket->setRreqId(rreqId);
421 
422  // The Hop Count field is set to zero.
423  rreqPacket->setHopCount(0);
424 
425  // Before broadcasting the RREQ, the originating node buffers the RREQ
426  // ID and the Originator IP address (its own address) of the RREQ for
427  // PATH_DISCOVERY_TIME.
428  // In this way, when the node receives the packet again from its neighbors,
429  // it will not reprocess and re-forward the packet.
430 
431  RREQIdentifier rreqIdentifier(getSelfIPAddress(), rreqId);
432  rreqsArrivalTime[rreqIdentifier] = simTime();
433  rreqPacket->setByteLength(24);
434  return rreqPacket;
435 }
unsigned int sequenceNum
Definition: AODVRouting.h:111
unsigned int rreqId
Definition: AODVRouting.h:110
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
bool askGratuitousRREP
Definition: AODVRouting.h:82
std::map< RREQIdentifier, simtime_t, RREQIdentifierCompare > rreqsArrivalTime
Definition: AODVRouting.h:113
Definition: AODVControlPackets_m.h:68
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
INetfilter::IHook::Result inet::AODVRouting::datagramForwardHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
overrideprotectedvirtual

This is the second hook called by the network protocol before it sends a datagram to the lower layer.

This is done after the datagramPreRoutingHook or the datagramLocalInHook is called and the datagram is routed.

Implements inet::INetfilter::IHook.

1521 {
1522  // TODO: Implement: Actions After Reboot
1523  // If the node receives a data packet for some other destination, it SHOULD
1524  // broadcast a RERR as described in subsection 6.11 and MUST reset the waiting
1525  // timer to expire after current time plus DELETE_PERIOD.
1526 
1527  Enter_Method("datagramForwardHook");
1528  const L3Address& destAddr = datagram->getDestinationAddress();
1529  const L3Address& sourceAddr = datagram->getSourceAddress();
1530  IRoute *ipSource = routingTable->findBestMatchingRoute(sourceAddr);
1531 
1532  if (destAddr.isBroadcast() || routingTable->isLocalAddress(destAddr) || destAddr.isMulticast()) {
1533  if (routingTable->isLocalAddress(destAddr) && ipSource && ipSource->getSource() == this)
1534  updateValidRouteLifeTime(ipSource->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1535 
1536  return ACCEPT;
1537  }
1538 
1539  // TODO: IMPLEMENT: check if the datagram is a data packet or we take control packets as data packets
1540 
1541  IRoute *routeDest = routingTable->findBestMatchingRoute(destAddr);
1542  AODVRouteData *routeDestData = routeDest ? dynamic_cast<AODVRouteData *>(routeDest->getProtocolData()) : nullptr;
1543 
1544  // Each time a route is used to forward a data packet, its Active Route
1545  // Lifetime field of the source, destination and the next hop on the
1546  // path to the destination is updated to be no less than the current
1547  // time plus ACTIVE_ROUTE_TIMEOUT
1548 
1549  updateValidRouteLifeTime(sourceAddr, simTime() + activeRouteTimeout);
1550  updateValidRouteLifeTime(destAddr, simTime() + activeRouteTimeout);
1551 
1552  if (routeDest && routeDest->getSource() == this)
1553  updateValidRouteLifeTime(routeDest->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1554 
1555  // Since the route between each originator and destination pair is expected
1556  // to be symmetric, the Active Route Lifetime for the previous hop, along the
1557  // reverse path back to the IP source, is also updated to be no less than the
1558  // current time plus ACTIVE_ROUTE_TIMEOUT.
1559 
1560  if (ipSource && ipSource->getSource() == this)
1561  updateValidRouteLifeTime(ipSource->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1562 
1563  EV_INFO << "We can't forward datagram because we have no active route for " << destAddr << endl;
1564  if (routeDest && routeDestData && !routeDestData->isActive()) { // exists but is not active
1565  // A node initiates processing for a RERR message in three situations:
1566  // (ii) if it gets a data packet destined to a node for which it
1567  // does not have an active route and is not repairing (if
1568  // using local repair)
1569 
1570  // TODO: check if it is not repairing (if using local repair)
1571 
1572  // 1. The destination sequence number of this routing entry, if it
1573  // exists and is valid, is incremented for cases (i) and (ii) above,
1574  // and copied from the incoming RERR in case (iii) above.
1575 
1576  if (routeDestData->hasValidDestNum())
1577  routeDestData->setDestSeqNum(routeDestData->getDestSeqNum() + 1);
1578 
1579  // 2. The entry is invalidated by marking the route entry as invalid <- it is invalid
1580 
1581  // 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
1582  // Before this time, the entry SHOULD NOT be deleted.
1583  routeDestData->setLifeTime(simTime() + deletePeriod);
1584 
1585  sendRERRWhenNoRouteToForward(destAddr);
1586  }
1587  else if (!routeDest || routeDest->getSource() != this) // doesn't exist at all
1588  sendRERRWhenNoRouteToForward(destAddr);
1589 
1590  return ACCEPT;
1591 }
bool updateValidRouteLifeTime(const L3Address &destAddr, simtime_t lifetime)
Definition: AODVRouting.cc:1635
void sendRERRWhenNoRouteToForward(const L3Address &unreachableAddr)
Definition: AODVRouting.cc:1593
virtual bool isLocalAddress(const L3Address &dest) const =0
Checks if the address is a local one, i.e.
simtime_t deletePeriod
Definition: AODVRouting.h:102
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
simtime_t activeRouteTimeout
Definition: AODVRouting.h:85
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
virtual Result inet::AODVRouting::datagramLocalInHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry 
)
inlineoverrideprotectedvirtual

This is the last hook called by the network protocol before it sends a datagram to the upper layer.

This is done after the datagramPreRoutingHook is called and the datagram is routed.

Implements inet::INetfilter::IHook.

194 { return ACCEPT; }
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
virtual Result inet::AODVRouting::datagramLocalOutHook ( INetworkDatagram datagram,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
inlineoverrideprotectedvirtual

This is the first hook called by the network protocol before it routes a datagram that was received from the upper layer.

The nextHopAddress is ignored when the outputInterfaceEntry is a nullptr. After this is done

Implements inet::INetfilter::IHook.

195 { Enter_Method("datagramLocalOutHook"); return ensureRouteForDatagram(datagram); }
Result ensureRouteForDatagram(INetworkDatagram *datagram)
Definition: AODVRouting.cc:189
virtual Result inet::AODVRouting::datagramPostRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
inlineoverrideprotectedvirtual

This is the last hook called by the network protocol before it sends a datagram to the lower layer.

Implements inet::INetfilter::IHook.

193 { return ACCEPT; }
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
virtual Result inet::AODVRouting::datagramPreRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
inlineoverrideprotectedvirtual

This is the first hook called by the network protocol before it routes a datagram that was received from the lower layer.

The nextHopAddress is ignored when the outputInterfaceEntry is nullptr.

Implements inet::INetfilter::IHook.

191 { Enter_Method("datagramPreRoutingHook"); return ensureRouteForDatagram(datagram); }
Result ensureRouteForDatagram(INetworkDatagram *datagram)
Definition: AODVRouting.cc:189
void inet::AODVRouting::delayDatagram ( INetworkDatagram datagram)
protected

Referenced by ensureRouteForDatagram().

269 {
270  EV_DETAIL << "Queuing datagram, source " << datagram->getSourceAddress() << ", destination " << datagram->getDestinationAddress() << endl;
271  const L3Address& target = datagram->getDestinationAddress();
272  targetAddressToDelayedPackets.insert(std::pair<L3Address, INetworkDatagram *>(target, datagram));
273 }
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: AODVRouting.h:133
INetfilter::IHook::Result inet::AODVRouting::ensureRouteForDatagram ( INetworkDatagram datagram)
protected
190 {
191  Enter_Method("datagramPreRoutingHook");
192  const L3Address& destAddr = datagram->getDestinationAddress();
193  const L3Address& sourceAddr = datagram->getSourceAddress();
194 
195  if (destAddr.isBroadcast() || routingTable->isLocalAddress(destAddr) || destAddr.isMulticast())
196  return ACCEPT;
197  else {
198  EV_INFO << "Finding route for source " << sourceAddr << " with destination " << destAddr << endl;
199  IRoute *route = routingTable->findBestMatchingRoute(destAddr);
200  AODVRouteData *routeData = route ? dynamic_cast<AODVRouteData *>(route->getProtocolData()) : nullptr;
201  bool isActive = routeData && routeData->isActive();
202  if (isActive && !route->getNextHopAsGeneric().isUnspecified()) {
203  EV_INFO << "Active route found: " << route << endl;
204 
205  // Each time a route is used to forward a data packet, its Active Route
206  // Lifetime field of the source, destination and the next hop on the
207  // path to the destination is updated to be no less than the current
208  // time plus ACTIVE_ROUTE_TIMEOUT.
209 
210  updateValidRouteLifeTime(destAddr, simTime() + activeRouteTimeout);
211  updateValidRouteLifeTime(route->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
212 
213  return ACCEPT;
214  }
215  else if (sourceAddr.isUnspecified() || routingTable->isLocalAddress(sourceAddr)) {
216  bool isInactive = routeData && !routeData->isActive();
217  // A node disseminates a RREQ when it determines that it needs a route
218  // to a destination and does not have one available. This can happen if
219  // the destination is previously unknown to the node, or if a previously
220  // valid route to the destination expires or is marked as invalid.
221 
222  EV_INFO << (isInactive ? "Inactive" : "Missing") << " route for destination " << destAddr << endl;
223 
224  delayDatagram(datagram);
225 
226  if (!hasOngoingRouteDiscovery(destAddr)) {
227  // When a new route to the same destination is required at a later time
228  // (e.g., upon route loss), the TTL in the RREQ IP header is initially
229  // set to the Hop Count plus TTL_INCREMENT.
230  if (isInactive)
231  startRouteDiscovery(destAddr, route->getMetric() + ttlIncrement);
232  else
233  startRouteDiscovery(destAddr);
234  }
235  else
236  EV_DETAIL << "Route discovery is in progress, originator " << getSelfIPAddress() << " target " << destAddr << endl;
237 
238  return QUEUE;
239  }
240  else
241  return ACCEPT;
242  }
243 }
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
void delayDatagram(INetworkDatagram *datagram)
Definition: AODVRouting.cc:268
bool updateValidRouteLifeTime(const L3Address &destAddr, simtime_t lifetime)
Definition: AODVRouting.cc:1635
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
virtual bool isLocalAddress(const L3Address &dest) const =0
Checks if the address is a local one, i.e.
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
unsigned int ttlIncrement
Definition: AODVRouting.h:92
simtime_t activeRouteTimeout
Definition: AODVRouting.h:85
void startRouteDiscovery(const L3Address &target, unsigned int timeToLive=0)
Definition: AODVRouting.cc:254
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
void inet::AODVRouting::expungeRoutes ( )
protected

Referenced by handleMessage().

1456 {
1457  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1458  IRoute *route = routingTable->getRoute(i);
1459  if (route->getSource() == this) {
1460  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1461  ASSERT(routeData != nullptr);
1462  if (routeData->getLifeTime() <= simTime()) {
1463  if (routeData->isActive()) {
1464  EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and set to inactive. It will be deleted after DELETE_PERIOD time" << endl;
1465  // An expired routing table entry SHOULD NOT be expunged before
1466  // (current_time + DELETE_PERIOD) (see section 6.11). Otherwise, the
1467  // soft state corresponding to the route (e.g., last known hop count)
1468  // will be lost.
1469  routeData->setIsActive(false);
1470  routeData->setLifeTime(simTime() + deletePeriod);
1471  }
1472  else {
1473  // Any routing table entry waiting for a RREP SHOULD NOT be expunged
1474  // before (current_time + 2 * NET_TRAVERSAL_TIME).
1475  if (hasOngoingRouteDiscovery(route->getDestinationAsGeneric())) {
1476  EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and is inactive, but we are waiting for a RREP to this destination, so we extend its lifetime with 2 * NET_TRAVERSAL_TIME" << endl;
1477  routeData->setLifeTime(simTime() + 2 * netTraversalTime);
1478  }
1479  else {
1480  EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and is inactive and we are not expecting any RREP to this destination, so we delete this route" << endl;
1481  routingTable->deleteRoute(route);
1482  }
1483  }
1484  }
1485  }
1486  }
1488 }
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
virtual bool deleteRoute(IRoute *entry)=0
Deletes the given route from the routing table.
simtime_t netTraversalTime
Definition: AODVRouting.h:105
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
simtime_t deletePeriod
Definition: AODVRouting.h:102
void scheduleExpungeRoutes()
Definition: AODVRouting.cc:1490
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::forwardRREP ( AODVRREP rrep,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected

Referenced by handleRREP().

1310 {
1311  EV_INFO << "Forwarding the Route Reply to the node " << rrep->getOriginatorAddr() << " which originated the Route Request" << endl;
1312 
1313  // RFC 5148:
1314  // When a node forwards a message, it SHOULD be jittered by delaying it
1315  // by a random duration. This delay SHOULD be generated uniformly in an
1316  // interval between zero and MAXJITTER.
1317  sendAODVPacket(rrep, destAddr, 100, jitterPar->doubleValue());
1318 }
cPar * jitterPar
Definition: AODVRouting.h:97
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
void inet::AODVRouting::forwardRREQ ( AODVRREQ rreq,
unsigned int  timeToLive 
)
protected

Referenced by handleRREQ().

1321 {
1322  EV_INFO << "Forwarding the Route Request message with TTL= " << timeToLive << endl;
1323  sendAODVPacket(rreq, addressType->getBroadcastAddress(), timeToLive, jitterPar->doubleValue());
1324 }
IL3AddressType * addressType
Definition: AODVRouting.h:71
cPar * jitterPar
Definition: AODVRouting.h:97
virtual L3Address getBroadcastAddress() const =0
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
L3Address inet::AODVRouting::getSelfIPAddress ( ) const
protected

Referenced by completeRouteDiscovery(), createHelloMessage(), createRREP(), createRREQ(), ensureRouteForDatagram(), handleRREP(), handleRREQ(), initialize(), sendAODVPacket(), and startRouteDiscovery().

264 {
266 }
IRoutingTable * routingTable
Definition: AODVRouting.h:75
virtual L3Address getRouterIdAsGeneric() const =0
Returns routerId.
void inet::AODVRouting::handleBlackListTimer ( )
protected

Referenced by handleMessage().

1698 {
1699  simtime_t nextTime = SimTime::getMaxTime();
1700 
1701  for (auto it = blacklist.begin(); it != blacklist.end(); ) {
1702  auto current = it++;
1703 
1704  // Nodes are removed from the blacklist set after a BLACKLIST_TIMEOUT period
1705  if (current->second <= simTime()) {
1706  EV_DETAIL << "Blacklist lifetime has expired for " << current->first << " removing it from the blacklisted addresses" << endl;
1707  blacklist.erase(current);
1708  }
1709  else if (nextTime > current->second)
1710  nextTime = current->second;
1711  }
1712 
1713  if (nextTime != SimTime::getMaxTime())
1714  scheduleAt(nextTime, blacklistTimer);
1715 }
std::map< L3Address, simtime_t > blacklist
Definition: AODVRouting.h:115
cMessage * blacklistTimer
Definition: AODVRouting.h:126
void inet::AODVRouting::handleHelloMessage ( AODVRREP helloMessage)
protected

Referenced by handleRREP().

1418 {
1419  const L3Address& helloOriginatorAddr = helloMessage->getDestAddr();
1420  IRoute *routeHelloOriginator = routingTable->findBestMatchingRoute(helloOriginatorAddr);
1421 
1422  // Whenever a node receives a Hello message from a neighbor, the node
1423  // SHOULD make sure that it has an active route to the neighbor, and
1424  // create one if necessary. If a route already exists, then the
1425  // Lifetime for the route should be increased, if necessary, to be at
1426  // least ALLOWED_HELLO_LOSS * HELLO_INTERVAL. The route to the
1427  // neighbor, if it exists, MUST subsequently contain the latest
1428  // Destination Sequence Number from the Hello message. The current node
1429  // can now begin using this route to forward data packets. Routes that
1430  // are created by hello messages and not used by any other active routes
1431  // will have empty precursor lists and would not trigger a RERR message
1432  // if the neighbor moves away and a neighbor timeout occurs.
1433 
1434  unsigned int latestDestSeqNum = helloMessage->getDestSeqNum();
1435  simtime_t newLifeTime = simTime() + allowedHelloLoss * helloInterval;
1436 
1437  if (!routeHelloOriginator || routeHelloOriginator->getSource() != this)
1438  createRoute(helloOriginatorAddr, helloOriginatorAddr, 1, true, latestDestSeqNum, true, newLifeTime);
1439  else {
1440  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(routeHelloOriginator->getProtocolData());
1441  simtime_t lifeTime = routeData->getLifeTime();
1442  updateRoutingTable(routeHelloOriginator, helloOriginatorAddr, 1, true, latestDestSeqNum, true, std::max(lifeTime, newLifeTime));
1443  }
1444 
1445  // TODO: This feature has not implemented yet.
1446  // A node MAY determine connectivity by listening for packets from its
1447  // set of neighbors. If, within the past DELETE_PERIOD, it has received
1448  // a Hello message from a neighbor, and then for that neighbor does not
1449  // receive any packets (Hello messages or otherwise) for more than
1450  // ALLOWED_HELLO_LOSS * HELLO_INTERVAL milliseconds, the node SHOULD
1451  // assume that the link to this neighbor is currently lost. When this
1452  // happens, the node SHOULD proceed as in Section 6.11.
1453 }
unsigned int allowedHelloLoss
Definition: AODVRouting.h:95
void updateRoutingTable(IRoute *route, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: AODVRouting.cc:712
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
simtime_t helloInterval
Definition: AODVRouting.h:86
IRoute * createRoute(const L3Address &destAddr, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: AODVRouting.cc:969
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::handleLinkBreakSendRERR ( const L3Address unreachableAddr)
protected

Referenced by receiveSignal().

1058 {
1059  // For case (i), the node first makes a list of unreachable destinations
1060  // consisting of the unreachable neighbor and any additional
1061  // destinations (or subnets, see section 7) in the local routing table
1062  // that use the unreachable neighbor as the next hop.
1063 
1064  // Just before transmitting the RERR, certain updates are made on the
1065  // routing table that may affect the destination sequence numbers for
1066  // the unreachable destinations. For each one of these destinations,
1067  // the corresponding routing table entry is updated as follows:
1068  //
1069  // 1. The destination sequence number of this routing entry, if it
1070  // exists and is valid, is incremented for cases (i) and (ii) above,
1071  // and copied from the incoming RERR in case (iii) above.
1072  //
1073  // 2. The entry is invalidated by marking the route entry as invalid
1074  //
1075  // 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
1076  // Before this time, the entry SHOULD NOT be deleted.
1077 
1078  IRoute *unreachableRoute = routingTable->findBestMatchingRoute(unreachableAddr);
1079 
1080  if (!unreachableRoute || unreachableRoute->getSource() != this)
1081  return;
1082 
1083  std::vector<UnreachableNode> unreachableNodes;
1084  AODVRouteData *unreachableRouteData = check_and_cast<AODVRouteData *>(unreachableRoute->getProtocolData());
1085 
1086  if (unreachableRouteData->isActive()) {
1087  UnreachableNode node;
1088  node.addr = unreachableAddr;
1089  node.seqNum = unreachableRouteData->getDestSeqNum();
1090  unreachableNodes.push_back(node);
1091  }
1092 
1093  // For case (i), the node first makes a list of unreachable destinations
1094  // consisting of the unreachable neighbor and any additional destinations
1095  // (or subnets, see section 7) in the local routing table that use the
1096  // unreachable neighbor as the next hop.
1097 
1098  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1099  IRoute *route = routingTable->getRoute(i);
1100 
1101  AODVRouteData *routeData = dynamic_cast<AODVRouteData *>(route->getProtocolData());
1102  if (routeData && routeData->isActive() && route->getNextHopAsGeneric() == unreachableAddr) {
1103  if (routeData->hasValidDestNum())
1104  routeData->setDestSeqNum(routeData->getDestSeqNum() + 1);
1105 
1106  EV_DETAIL << "Marking route to " << route->getDestinationAsGeneric() << " as inactive" << endl;
1107 
1108  routeData->setIsActive(false);
1109  routeData->setLifeTime(simTime() + deletePeriod);
1111 
1112  UnreachableNode node;
1113  node.addr = route->getDestinationAsGeneric();
1114  node.seqNum = routeData->getDestSeqNum();
1115  unreachableNodes.push_back(node);
1116  }
1117  }
1118 
1119  // The neighboring node(s) that should receive the RERR are all those
1120  // that belong to a precursor list of at least one of the unreachable
1121  // destination(s) in the newly created RERR. In case there is only one
1122  // unique neighbor that needs to receive the RERR, the RERR SHOULD be
1123  // unicast toward that neighbor. Otherwise the RERR is typically sent
1124  // to the local broadcast address (Destination IP == 255.255.255.255,
1125  // TTL == 1) with the unreachable destinations, and their corresponding
1126  // destination sequence numbers, included in the packet.
1127 
1128  if (rerrCount >= rerrRatelimit) {
1129  EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1130  return;
1131  }
1132 
1133  if (unreachableNodes.empty())
1134  return;
1135 
1136  AODVRERR *rerr = createRERR(unreachableNodes);
1137  rerrCount++;
1138 
1139  // broadcast
1140  EV_INFO << "Broadcasting Route Error message with TTL=1" << endl;
1141  sendAODVPacket(rerr, addressType->getBroadcastAddress(), 1, jitterPar->doubleValue());
1142 }
virtual L3Address getDestinationAsGeneric() const =0
Destination address prefix to match.
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
IL3AddressType * addressType
Definition: AODVRouting.h:71
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
cPar * jitterPar
Definition: AODVRouting.h:97
simtime_t deletePeriod
Definition: AODVRouting.h:102
unsigned int rerrRatelimit
Definition: AODVRouting.h:80
unsigned int rerrCount
Definition: AODVRouting.h:116
AODVRERR * createRERR(const std::vector< UnreachableNode > &unreachableNodes)
Definition: AODVRouting.cc:1144
void scheduleExpungeRoutes()
Definition: AODVRouting.cc:1490
virtual L3Address getBroadcastAddress() const =0
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::handleMessage ( cMessage *  msg)
overrideprotected
126 {
127  if (!isOperational) {
128  if (msg->isSelfMessage())
129  throw cRuntimeError("Model error: self msg '%s' received when isOperational is false", msg->getName());
130 
131  EV_ERROR << "Application is turned off, dropping '" << msg->getName() << "' message\n";
132  delete msg;
133  return;
134  }
135 
136  if (msg->isSelfMessage()) {
137  if (dynamic_cast<WaitForRREP *>(msg))
138  handleWaitForRREP((WaitForRREP *)msg);
139  else if (msg == helloMsgTimer)
141  else if (msg == expungeTimer)
142  expungeRoutes();
143  else if (msg == counterTimer) {
144  rreqCount = rerrCount = 0;
145  scheduleAt(simTime() + 1, counterTimer);
146  }
147  else if (msg == rrepAckTimer)
149  else if (msg == blacklistTimer)
151  else
152  throw cRuntimeError("Unknown self message");
153  }
154  else if (ICMPMessage *icmpPacket = dynamic_cast<ICMPMessage *>(msg)) {
155  // ICMP packet arrived, dropped
156  delete icmpPacket;
157  }
158  else {
159  UDPPacket *udpPacket = check_and_cast<UDPPacket *>(msg);
160  AODVControlPacket *ctrlPacket = check_and_cast<AODVControlPacket *>(udpPacket->decapsulate());
161  INetworkProtocolControlInfo *udpProtocolCtrlInfo = check_and_cast<INetworkProtocolControlInfo *>(udpPacket->getControlInfo());
162  L3Address sourceAddr = udpProtocolCtrlInfo->getSourceAddress();
163  unsigned int arrivalPacketTTL = udpProtocolCtrlInfo->getHopLimit();
164 
165  switch (ctrlPacket->getPacketType()) {
166  case RREQ:
167  handleRREQ(check_and_cast<AODVRREQ *>(ctrlPacket), sourceAddr, arrivalPacketTTL);
168  break;
169 
170  case RREP:
171  handleRREP(check_and_cast<AODVRREP *>(ctrlPacket), sourceAddr);
172  break;
173 
174  case RERR:
175  handleRERR(check_and_cast<AODVRERR *>(ctrlPacket), sourceAddr);
176  break;
177 
178  case RREPACK:
179  handleRREPACK(check_and_cast<AODVRREPACK *>(ctrlPacket), sourceAddr);
180  break;
181 
182  default:
183  throw cRuntimeError("AODV Control Packet arrived with undefined packet type: %d", ctrlPacket->getPacketType());
184  }
185  delete udpPacket;
186  }
187 }
cMessage * expungeTimer
Definition: AODVRouting.h:123
void handleRREPACK(AODVRREPACK *rrepACK, const L3Address &neighborAddr)
Definition: AODVRouting.cc:1664
Definition: AODVControlPackets_m.h:69
bool isOperational
Definition: AODVRouting.h:130
void handleRREP(AODVRREP *rrep, const L3Address &sourceAddr)
Definition: AODVRouting.cc:551
cMessage * rrepAckTimer
Definition: AODVRouting.h:125
unsigned int rreqCount
Definition: AODVRouting.h:117
void handleRREPACKTimer()
Definition: AODVRouting.cc:1684
void handleRREQ(AODVRREQ *rreq, const L3Address &sourceAddr, unsigned int timeToLive)
Definition: AODVRouting.cc:763
void handleRERR(AODVRERR *rerr, const L3Address &sourceAddr)
Definition: AODVRouting.cc:1164
cMessage * helloMsgTimer
Definition: AODVRouting.h:122
Definition: AODVControlPackets_m.h:71
cMessage * blacklistTimer
Definition: AODVRouting.h:126
void sendHelloMessagesIfNeeded()
Definition: AODVRouting.cc:1385
cMessage * counterTimer
Definition: AODVRouting.h:124
unsigned int rerrCount
Definition: AODVRouting.h:116
Definition: AODVControlPackets_m.h:68
Definition: AODVControlPackets_m.h:70
void handleBlackListTimer()
Definition: AODVRouting.cc:1697
void handleWaitForRREP(WaitForRREP *rrepTimer)
Definition: AODVRouting.cc:1287
void expungeRoutes()
Definition: AODVRouting.cc:1455
bool inet::AODVRouting::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

1228 {
1229  Enter_Method_Silent();
1230  if (dynamic_cast<NodeStartOperation *>(operation)) {
1232  isOperational = true;
1233  rebootTime = simTime();
1234 
1235  if (useHelloMessages)
1236  scheduleAt(simTime() + helloInterval - periodicJitter->doubleValue(), helloMsgTimer);
1237 
1238  scheduleAt(simTime() + 1, counterTimer);
1239  }
1240  }
1241  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
1243  isOperational = false;
1244  clearState();
1245  }
1246  }
1247  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
1249  isOperational = false;
1250  clearState();
1251  }
1252  }
1253  else
1254  throw cRuntimeError("Unsupported lifecycle operation '%s'", operation->getClassName());
1255 
1256  return true;
1257 }
bool isOperational
Definition: AODVRouting.h:130
cMessage * helloMsgTimer
Definition: AODVRouting.h:122
Stage
Definition: NodeOperations.h:71
cPar * periodicJitter
Definition: AODVRouting.h:98
Stage
Definition: NodeOperations.h:126
simtime_t helloInterval
Definition: AODVRouting.h:86
cMessage * counterTimer
Definition: AODVRouting.h:124
Stage
Definition: NodeOperations.h:46
simtime_t rebootTime
Definition: AODVRouting.h:129
void clearState()
Definition: AODVRouting.cc:1259
Definition: NodeOperations.h:127
bool useHelloMessages
Definition: AODVRouting.h:83
void inet::AODVRouting::handleRERR ( AODVRERR rerr,
const L3Address sourceAddr 
)
protected

Referenced by handleMessage().

1165 {
1166  EV_INFO << "AODV Route Error arrived with source addr: " << sourceAddr << endl;
1167 
1168  // A node initiates processing for a RERR message in three situations:
1169  // (iii) if it receives a RERR from a neighbor for one or more
1170  // active routes.
1171  unsigned int unreachableArraySize = rerr->getUnreachableNodesArraySize();
1172  std::vector<UnreachableNode> unreachableNeighbors;
1173 
1174  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1175  IRoute *route = routingTable->getRoute(i);
1176  AODVRouteData *routeData = route ? dynamic_cast<AODVRouteData *>(route->getProtocolData()) : nullptr;
1177 
1178  if (!routeData)
1179  continue;
1180 
1181  // For case (iii), the list should consist of those destinations in the RERR
1182  // for which there exists a corresponding entry in the local routing
1183  // table that has the transmitter of the received RERR as the next hop.
1184 
1185  if (routeData->isActive() && route->getNextHopAsGeneric() == sourceAddr) {
1186  for (unsigned int j = 0; j < unreachableArraySize; j++) {
1187  if (route->getDestinationAsGeneric() == rerr->getUnreachableNodes(j).addr) {
1188  // 1. The destination sequence number of this routing entry, if it
1189  // exists and is valid, is incremented for cases (i) and (ii) above,
1190  // ! and copied from the incoming RERR in case (iii) above.
1191 
1192  routeData->setDestSeqNum(rerr->getUnreachableNodes(j).seqNum);
1193  routeData->setIsActive(false); // it means invalid, see 3. AODV Terminology p.3. in RFC 3561
1194  routeData->setLifeTime(simTime() + deletePeriod);
1195 
1196  // The RERR should contain those destinations that are part of
1197  // the created list of unreachable destinations and have a non-empty
1198  // precursor list.
1199 
1200  if (routeData->getPrecursorList().size() > 0) {
1201  UnreachableNode node;
1202  node.addr = route->getDestinationAsGeneric();
1203  node.seqNum = routeData->getDestSeqNum();
1204  unreachableNeighbors.push_back(node);
1205  }
1207  }
1208  }
1209  }
1210  }
1211 
1212  if (rerrCount >= rerrRatelimit) {
1213  EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1214  delete rerr;
1215  return;
1216  }
1217 
1218  if (unreachableNeighbors.size() > 0 && (simTime() > rebootTime + deletePeriod || rebootTime == 0)) {
1219  EV_INFO << "Sending RERR to inform our neighbors about link breaks." << endl;
1220  AODVRERR *newRERR = createRERR(unreachableNeighbors);
1221  sendAODVPacket(newRERR, addressType->getBroadcastAddress(), 1, 0);
1222  rerrCount++;
1223  }
1224  delete rerr;
1225 }
virtual L3Address getDestinationAsGeneric() const =0
Destination address prefix to match.
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
IL3AddressType * addressType
Definition: AODVRouting.h:71
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
simtime_t deletePeriod
Definition: AODVRouting.h:102
unsigned int rerrRatelimit
Definition: AODVRouting.h:80
unsigned int rerrCount
Definition: AODVRouting.h:116
AODVRERR * createRERR(const std::vector< UnreachableNode > &unreachableNodes)
Definition: AODVRouting.cc:1144
void scheduleExpungeRoutes()
Definition: AODVRouting.cc:1490
simtime_t rebootTime
Definition: AODVRouting.h:129
virtual L3Address getBroadcastAddress() const =0
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::handleRREP ( AODVRREP rrep,
const L3Address sourceAddr 
)
protected

Referenced by handleMessage().

552 {
553  EV_INFO << "AODV Route Reply arrived with source addr: " << sourceAddr << " originator addr: " << rrep->getOriginatorAddr()
554  << " destination addr: " << rrep->getDestAddr() << endl;
555 
556  if (rrep->getOriginatorAddr().isUnspecified()) {
557  EV_INFO << "This Route Reply is a Hello Message" << endl;
558  handleHelloMessage(rrep);
559  delete rrep;
560  return;
561  }
562  // When a node receives a RREP message, it searches (using longest-
563  // prefix matching) for a route to the previous hop.
564 
565  // If needed, a route is created for the previous hop,
566  // but without a valid sequence number (see section 6.2)
567 
568  IRoute *previousHopRoute = routingTable->findBestMatchingRoute(sourceAddr);
569 
570  if (!previousHopRoute || previousHopRoute->getSource() != this) {
571  // create without valid sequence number
572  previousHopRoute = createRoute(sourceAddr, sourceAddr, 1, false, rrep->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
573  }
574  else
575  updateRoutingTable(previousHopRoute, sourceAddr, 1, false, rrep->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
576 
577  // Next, the node then increments the hop count value in the RREP by one,
578  // to account for the new hop through the intermediate node
579  unsigned int newHopCount = rrep->getHopCount() + 1;
580  rrep->setHopCount(newHopCount);
581 
582  // Then the forward route for this destination is created if it does not
583  // already exist.
584 
585  IRoute *destRoute = routingTable->findBestMatchingRoute(rrep->getDestAddr());
586  AODVRouteData *destRouteData = nullptr;
587  simtime_t lifeTime = rrep->getLifeTime();
588  unsigned int destSeqNum = rrep->getDestSeqNum();
589 
590  if (destRoute && destRoute->getSource() == this) { // already exists
591  destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
592  // Upon comparison, the existing entry is updated only in the following circumstances:
593 
594  // (i) the sequence number in the routing table is marked as
595  // invalid in route table entry.
596 
597  if (!destRouteData->hasValidDestNum()) {
598  updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
599 
600  // If the route table entry to the destination is created or updated,
601  // then the following actions occur:
602  //
603  // - the route is marked as active,
604  //
605  // - the destination sequence number is marked as valid,
606  //
607  // - the next hop in the route entry is assigned to be the node from
608  // which the RREP is received, which is indicated by the source IP
609  // address field in the IP header,
610  //
611  // - the hop count is set to the value of the New Hop Count,
612  //
613  // - the expiry time is set to the current time plus the value of the
614  // Lifetime in the RREP message,
615  //
616  // - and the destination sequence number is the Destination Sequence
617  // Number in the RREP message.
618  }
619  // (ii) the Destination Sequence Number in the RREP is greater than
620  // the node's copy of the destination sequence number and the
621  // known value is valid, or
622  else if (destSeqNum > destRouteData->getDestSeqNum()) {
623  updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
624  }
625  else {
626  // (iii) the sequence numbers are the same, but the route is
627  // marked as inactive, or
628  if (destSeqNum == destRouteData->getDestSeqNum() && !destRouteData->isActive()) {
629  updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
630  }
631  // (iv) the sequence numbers are the same, and the New Hop Count is
632  // smaller than the hop count in route table entry.
633  else if (destSeqNum == destRouteData->getDestSeqNum() && newHopCount < (unsigned int)destRoute->getMetric()) {
634  updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
635  }
636  }
637  }
638  else { // create forward route for the destination: this path will be used by the originator to send data packets
639  destRoute = createRoute(rrep->getDestAddr(), sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
640  destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
641  }
642 
643  // If the current node is not the node indicated by the Originator IP
644  // Address in the RREP message AND a forward route has been created or
645  // updated as described above, the node consults its route table entry
646  // for the originating node to determine the next hop for the RREP
647  // packet, and then forwards the RREP towards the originator using the
648  // information in that route table entry.
649 
650  IRoute *originatorRoute = routingTable->findBestMatchingRoute(rrep->getOriginatorAddr());
651  if (getSelfIPAddress() != rrep->getOriginatorAddr()) {
652  // If a node forwards a RREP over a link that is likely to have errors or
653  // be unidirectional, the node SHOULD set the 'A' flag to require that the
654  // recipient of the RREP acknowledge receipt of the RREP by sending a RREP-ACK
655  // message back (see section 6.8).
656 
657  if (originatorRoute && originatorRoute->getSource() == this) {
658  AODVRouteData *originatorRouteData = check_and_cast<AODVRouteData *>(originatorRoute->getProtocolData());
659 
660  // Also, at each node the (reverse) route used to forward a
661  // RREP has its lifetime changed to be the maximum of (existing-
662  // lifetime, (current time + ACTIVE_ROUTE_TIMEOUT).
663 
664  simtime_t existingLifeTime = originatorRouteData->getLifeTime();
665  originatorRouteData->setLifeTime(std::max(simTime() + activeRouteTimeout, existingLifeTime));
666 
667  if (simTime() > rebootTime + deletePeriod || rebootTime == 0) {
668  // If a node forwards a RREP over a link that is likely to have errors
669  // or be unidirectional, the node SHOULD set the 'A' flag to require that
670  // the recipient of the RREP acknowledge receipt of the RREP by sending a
671  // RREP-ACK message back (see section 6.8).
672 
673  if (rrep->getAckRequiredFlag()) {
674  AODVRREPACK *rrepACK = createRREPACK();
675  sendRREPACK(rrepACK, sourceAddr);
676  rrep->setAckRequiredFlag(false);
677  }
678 
679  // When any node transmits a RREP, the precursor list for the
680  // corresponding destination node is updated by adding to it
681  // the next hop node to which the RREP is forwarded.
682 
683  destRouteData->addPrecursor(originatorRoute->getNextHopAsGeneric());
684 
685  // Finally, the precursor list for the next hop towards the
686  // destination is updated to contain the next hop towards the
687  // source (originator).
688 
689  IRoute *nextHopToDestRoute = routingTable->findBestMatchingRoute(destRoute->getNextHopAsGeneric());
690  if (nextHopToDestRoute && nextHopToDestRoute->getSource() == this) {
691  AODVRouteData *nextHopToDestRouteData = check_and_cast<AODVRouteData *>(nextHopToDestRoute->getProtocolData());
692  nextHopToDestRouteData->addPrecursor(originatorRoute->getNextHopAsGeneric());
693  }
694  AODVRREP *outgoingRREP = rrep->dup();
695  forwardRREP(outgoingRREP, originatorRoute->getNextHopAsGeneric(), 100);
696  }
697  }
698  else
699  EV_ERROR << "Reverse route doesn't exist. Dropping the RREP message" << endl;
700  }
701  else {
702  if (hasOngoingRouteDiscovery(rrep->getDestAddr())) {
703  EV_INFO << "The Route Reply has arrived for our Route Request to node " << rrep->getDestAddr() << endl;
704  updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
705  completeRouteDiscovery(rrep->getDestAddr());
706  }
707  }
708 
709  delete rrep;
710 }
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
void updateRoutingTable(IRoute *route, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: AODVRouting.cc:712
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
void forwardRREP(AODVRREP *rrep, const L3Address &destAddr, unsigned int timeToLive)
Definition: AODVRouting.cc:1309
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
simtime_t deletePeriod
Definition: AODVRouting.h:102
void sendRREPACK(AODVRREPACK *rrepACK, const L3Address &destAddr)
Definition: AODVRouting.cc:1658
IRoute * createRoute(const L3Address &destAddr, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: AODVRouting.cc:969
simtime_t rebootTime
Definition: AODVRouting.h:129
void completeRouteDiscovery(const L3Address &target)
Definition: AODVRouting.cc:1326
simtime_t activeRouteTimeout
Definition: AODVRouting.h:85
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
AODVRREPACK * createRREPACK()
Definition: AODVRouting.cc:1650
void handleHelloMessage(AODVRREP *helloMessage)
Definition: AODVRouting.cc:1417
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::handleRREPACK ( AODVRREPACK rrepACK,
const L3Address neighborAddr 
)
protected

Referenced by handleMessage().

1665 {
1666  // Note that the RREP-ACK packet does not contain any information about
1667  // which RREP it is acknowledging. The time at which the RREP-ACK is
1668  // received will likely come just after the time when the RREP was sent
1669  // with the 'A' bit.
1670  if (rrepAckTimer->isScheduled()) {
1671  EV_INFO << "RREP-ACK arrived from " << neighborAddr << endl;
1672 
1673  IRoute *route = routingTable->findBestMatchingRoute(neighborAddr);
1674  if (route && route->getSource() == this) {
1675  EV_DETAIL << "Marking route " << route << " as active" << endl;
1676  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1677  routeData->setIsActive(true);
1678  cancelEvent(rrepAckTimer);
1679  }
1680  }
1681  delete rrepACK;
1682 }
cMessage * rrepAckTimer
Definition: AODVRouting.h:125
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::handleRREPACKTimer ( )
protected

Referenced by handleMessage().

1685 {
1686  // when a node detects that its transmission of a RREP message has failed,
1687  // it remembers the next-hop of the failed RREP in a "blacklist" set.
1688 
1689  EV_INFO << "RREP-ACK didn't arrived within timeout. Adding " << failedNextHop << " to the blacklist" << endl;
1690 
1691  blacklist[failedNextHop] = simTime() + blacklistTimeout; // lifetime
1692 
1693  if (!blacklistTimer->isScheduled())
1694  scheduleAt(simTime() + blacklistTimeout, blacklistTimer);
1695 }
simtime_t blacklistTimeout
Definition: AODVRouting.h:104
std::map< L3Address, simtime_t > blacklist
Definition: AODVRouting.h:115
L3Address failedNextHop
Definition: AODVRouting.h:114
cMessage * blacklistTimer
Definition: AODVRouting.h:126
void inet::AODVRouting::handleRREQ ( AODVRREQ rreq,
const L3Address sourceAddr,
unsigned int  timeToLive 
)
protected

Referenced by handleMessage().

764 {
765  EV_INFO << "AODV Route Request arrived with source addr: " << sourceAddr << " originator addr: " << rreq->getOriginatorAddr()
766  << " destination addr: " << rreq->getDestAddr() << endl;
767 
768  // A node ignores all RREQs received from any node in its blacklist set.
769 
770  auto blackListIt = blacklist.find(sourceAddr);
771  if (blackListIt != blacklist.end()) {
772  EV_INFO << "The sender node " << sourceAddr << " is in our blacklist. Ignoring the Route Request" << endl;
773  delete rreq;
774  return;
775  }
776 
777  // When a node receives a RREQ, it first creates or updates a route to
778  // the previous hop without a valid sequence number (see section 6.2).
779 
780  IRoute *previousHopRoute = routingTable->findBestMatchingRoute(sourceAddr);
781 
782  if (!previousHopRoute || previousHopRoute->getSource() != this) {
783  // create without valid sequence number
784  previousHopRoute = createRoute(sourceAddr, sourceAddr, 1, false, rreq->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
785  }
786  else
787  updateRoutingTable(previousHopRoute, sourceAddr, 1, false, rreq->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
788 
789  // then checks to determine whether it has received a RREQ with the same
790  // Originator IP Address and RREQ ID within at least the last PATH_DISCOVERY_TIME.
791  // If such a RREQ has been received, the node silently discards the newly received RREQ.
792 
793  RREQIdentifier rreqIdentifier(rreq->getOriginatorAddr(), rreq->getRreqId());
794  auto checkRREQArrivalTime = rreqsArrivalTime.find(rreqIdentifier);
795  if (checkRREQArrivalTime != rreqsArrivalTime.end() && simTime() - checkRREQArrivalTime->second <= pathDiscoveryTime) {
796  EV_WARN << "The same packet has arrived within PATH_DISCOVERY_TIME= " << pathDiscoveryTime << ". Discarding it" << endl;
797  delete rreq;
798  return;
799  }
800 
801  // update or create
802  rreqsArrivalTime[rreqIdentifier] = simTime();
803 
804  // First, it first increments the hop count value in the RREQ by one, to
805  // account for the new hop through the intermediate node.
806 
807  rreq->setHopCount(rreq->getHopCount() + 1);
808 
809  // Then the node searches for a reverse route to the Originator IP Address (see
810  // section 6.2), using longest-prefix matching.
811 
812  IRoute *reverseRoute = routingTable->findBestMatchingRoute(rreq->getOriginatorAddr());
813 
814  // If need be, the route is created, or updated using the Originator Sequence Number from the
815  // RREQ in its routing table.
816  //
817  // When the reverse route is created or updated, the following actions on
818  // the route are also carried out:
819  //
820  // 1. the Originator Sequence Number from the RREQ is compared to the
821  // corresponding destination sequence number in the route table entry
822  // and copied if greater than the existing value there
823  //
824  // 2. the valid sequence number field is set to true;
825  //
826  // 3. the next hop in the routing table becomes the node from which the
827  // RREQ was received (it is obtained from the source IP address in
828  // the IP header and is often not equal to the Originator IP Address
829  // field in the RREQ message);
830  //
831  // 4. the hop count is copied from the Hop Count in the RREQ message;
832  //
833  // Whenever a RREQ message is received, the Lifetime of the reverse
834  // route entry for the Originator IP address is set to be the maximum of
835  // (ExistingLifetime, MinimalLifetime), where
836  //
837  // MinimalLifetime = (current time + 2*NET_TRAVERSAL_TIME - 2*HopCount*NODE_TRAVERSAL_TIME).
838 
839  unsigned int hopCount = rreq->getHopCount();
840  simtime_t minimalLifeTime = simTime() + 2 * netTraversalTime - 2 * hopCount * nodeTraversalTime;
841  simtime_t newLifeTime = std::max(simTime(), minimalLifeTime);
842  int rreqSeqNum = rreq->getOriginatorSeqNum();
843  if (!reverseRoute || reverseRoute->getSource() != this) { // create
844  // This reverse route will be needed if the node receives a RREP back to the
845  // node that originated the RREQ (identified by the Originator IP Address).
846  reverseRoute = createRoute(rreq->getOriginatorAddr(), sourceAddr, hopCount, true, rreqSeqNum, true, newLifeTime);
847  }
848  else {
849  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(reverseRoute->getProtocolData());
850  int routeSeqNum = routeData->getDestSeqNum();
851  int newSeqNum = std::max(routeSeqNum, rreqSeqNum);
852  int newHopCount = rreq->getHopCount(); // Note: already incremented by 1.
853  int routeHopCount = reverseRoute->getMetric();
854  // The route is only updated if the new sequence number is either
855  //
856  // (i) higher than the destination sequence number in the route
857  // table, or
858  //
859  // (ii) the sequence numbers are equal, but the hop count (of the
860  // new information) plus one, is smaller than the existing hop
861  // count in the routing table, or
862  //
863  // (iii) the sequence number is unknown.
864 
865  if (rreqSeqNum > routeSeqNum ||
866  (rreqSeqNum == routeSeqNum && newHopCount < routeHopCount) ||
867  rreq->getUnknownSeqNumFlag())
868  {
869  updateRoutingTable(reverseRoute, sourceAddr, hopCount, true, newSeqNum, true, newLifeTime);
870  }
871  }
872 
873  // A node generates a RREP if either:
874  //
875  // (i) it is itself the destination, or
876  //
877  // (ii) it has an active route to the destination, the destination
878  // sequence number in the node's existing route table entry
879  // for the destination is valid and greater than or equal to
880  // the Destination Sequence Number of the RREQ (comparison
881  // using signed 32-bit arithmetic), and the "destination only"
882  // ('D') flag is NOT set.
883 
884  // After a node receives a RREQ and responds with a RREP, it discards
885  // the RREQ. If the RREQ has the 'G' flag set, and the intermediate
886  // node returns a RREP to the originating node, it MUST also unicast a
887  // gratuitous RREP to the destination node.
888 
889  IRoute *destRoute = routingTable->findBestMatchingRoute(rreq->getDestAddr());
890  AODVRouteData *destRouteData = destRoute ? dynamic_cast<AODVRouteData *>(destRoute->getProtocolData()) : nullptr;
891 
892  // check (i)
893  if (rreq->getDestAddr() == getSelfIPAddress()) {
894  EV_INFO << "I am the destination node for which the route was requested" << endl;
895 
896  // create RREP
897  AODVRREP *rrep = createRREP(rreq, destRoute, reverseRoute, sourceAddr);
898 
899  // send to the originator
900  sendRREP(rrep, rreq->getOriginatorAddr(), 255);
901 
902  delete rreq;
903  return; // discard RREQ, in this case, we do not forward it.
904  }
905 
906  // check (ii)
907  if (destRouteData && destRouteData->isActive() && destRouteData->hasValidDestNum() &&
908  destRouteData->getDestSeqNum() >= rreq->getDestSeqNum())
909  {
910  EV_INFO << "I am an intermediate node who has information about a route to " << rreq->getDestAddr() << endl;
911 
912  if (destRoute->getNextHopAsGeneric() == sourceAddr) {
913  EV_WARN << "This RREP would make a loop. Dropping it" << endl;
914 
915  delete rreq;
916  return;
917  }
918 
919  // create RREP
920  AODVRREP *rrep = createRREP(rreq, destRoute, reverseRoute, sourceAddr);
921 
922  // send to the originator
923  sendRREP(rrep, rreq->getOriginatorAddr(), 255);
924 
925  if (rreq->getGratuitousRREPFlag()) {
926  // The gratuitous RREP is then sent to the next hop along the path to
927  // the destination node, just as if the destination node had already
928  // issued a RREQ for the originating node and this RREP was produced in
929  // response to that (fictitious) RREQ.
930 
931  IRoute *originatorRoute = routingTable->findBestMatchingRoute(rreq->getOriginatorAddr());
932  AODVRREP *grrep = createGratuitousRREP(rreq, originatorRoute);
933  sendGRREP(grrep, rreq->getDestAddr(), 100);
934  }
935 
936  delete rreq;
937  return; // discard RREQ, in this case, we also do not forward it.
938  }
939  // If a node does not generate a RREP (following the processing rules in
940  // section 6.6), and if the incoming IP header has TTL larger than 1,
941  // the node updates and broadcasts the RREQ to address 255.255.255.255
942  // on each of its configured interfaces (see section 6.14). To update
943  // the RREQ, the TTL or hop limit field in the outgoing IP header is
944  // decreased by one, and the Hop Count field in the RREQ message is
945  // incremented by one, to account for the new hop through the
946  // intermediate node. (!) Lastly, the Destination Sequence number for the
947  // requested destination is set to the maximum of the corresponding
948  // value received in the RREQ message, and the destination sequence
949  // value currently maintained by the node for the requested destination.
950  // However, the forwarding node MUST NOT modify its maintained value for
951  // the destination sequence number, even if the value received in the
952  // incoming RREQ is larger than the value currently maintained by the
953  // forwarding node.
954 
955  if (timeToLive > 0 && (simTime() > rebootTime + deletePeriod || rebootTime == 0)) {
956  if (destRouteData)
957  rreq->setDestSeqNum(std::max(destRouteData->getDestSeqNum(), rreq->getDestSeqNum()));
958  rreq->setUnknownSeqNumFlag(false);
959 
960  AODVRREQ *outgoingRREQ = rreq->dup();
961  forwardRREQ(outgoingRREQ, timeToLive);
962  }
963  else
964  EV_WARN << "Can't forward the RREQ because of its small (<= 1) TTL: " << timeToLive << " or the AODV reboot has not completed yet" << endl;
965 
966  delete rreq;
967 }
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
simtime_t nodeTraversalTime
Definition: AODVRouting.h:96
std::map< L3Address, simtime_t > blacklist
Definition: AODVRouting.h:115
simtime_t pathDiscoveryTime
Definition: AODVRouting.h:107
simtime_t netTraversalTime
Definition: AODVRouting.h:105
void updateRoutingTable(IRoute *route, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: AODVRouting.cc:712
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
simtime_t deletePeriod
Definition: AODVRouting.h:102
AODVRREP * createRREP(AODVRREQ *rreq, IRoute *destRoute, IRoute *originatorRoute, const L3Address &sourceAddr)
Definition: AODVRouting.cc:437
void forwardRREQ(AODVRREQ *rreq, unsigned int timeToLive)
Definition: AODVRouting.cc:1320
std::map< RREQIdentifier, simtime_t, RREQIdentifierCompare > rreqsArrivalTime
Definition: AODVRouting.h:113
IRoute * createRoute(const L3Address &destAddr, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: AODVRouting.cc:969
simtime_t rebootTime
Definition: AODVRouting.h:129
simtime_t activeRouteTimeout
Definition: AODVRouting.h:85
void sendGRREP(AODVRREP *grrep, const L3Address &destAddr, unsigned int timeToLive)
Definition: AODVRouting.cc:1351
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
AODVRREP * createGratuitousRREP(AODVRREQ *rreq, IRoute *originatorRoute)
Definition: AODVRouting.cc:517
void sendRREP(AODVRREP *rrep, const L3Address &destAddr, unsigned int timeToLive)
Definition: AODVRouting.cc:347
void inet::AODVRouting::handleWaitForRREP ( WaitForRREP rrepTimer)
protected

Referenced by handleMessage().

1288 {
1289  EV_INFO << "We didn't get any Route Reply within RREP timeout" << endl;
1290  L3Address destAddr = rrepTimer->getDestAddr();
1291 
1292  ASSERT(addressToRreqRetries.find(destAddr) != addressToRreqRetries.end());
1293  if (addressToRreqRetries[destAddr] == rreqRetries) {
1294  cancelRouteDiscovery(destAddr);
1295  EV_WARN << "Re-discovery attempts for node " << destAddr << " reached RREQ_RETRIES= " << rreqRetries << " limit. Stop sending RREQ." << endl;
1296  return;
1297  }
1298 
1299  AODVRREQ *rreq = createRREQ(destAddr);
1300 
1301  // the node MAY try again to discover a route by broadcasting another
1302  // RREQ, up to a maximum of RREQ_RETRIES times at the maximum TTL value.
1303  if (rrepTimer->getLastTTL() == netDiameter) // netDiameter is the maximum TTL value
1304  addressToRreqRetries[destAddr]++;
1305 
1307 }
IL3AddressType * addressType
Definition: AODVRouting.h:71
void sendRREQ(AODVRREQ *rreq, const L3Address &destAddr, unsigned int timeToLive)
Definition: AODVRouting.cc:275
AODVRREQ * createRREQ(const L3Address &destAddr)
Definition: AODVRouting.cc:382
std::map< L3Address, unsigned int > addressToRreqRetries
Definition: AODVRouting.h:119
unsigned int netDiameter
Definition: AODVRouting.h:87
void cancelRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:1619
unsigned int rreqRetries
Definition: AODVRouting.h:88
virtual L3Address getBroadcastAddress() const =0
bool inet::AODVRouting::hasOngoingRouteDiscovery ( const L3Address destAddr)
protected

Referenced by cancelRouteDiscovery(), completeRouteDiscovery(), ensureRouteForDatagram(), expungeRoutes(), handleRREP(), sendRREQ(), and startRouteDiscovery().

250 {
251  return waitForRREPTimers.find(target) != waitForRREPTimers.end();
252 }
std::map< L3Address, WaitForRREP * > waitForRREPTimers
Definition: AODVRouting.h:112
void inet::AODVRouting::initialize ( int  stage)
overrideprotected
57 {
58  if (stage == INITSTAGE_LOCAL) {
59  lastBroadcastTime = SIMTIME_ZERO;
60  rebootTime = SIMTIME_ZERO;
61  rreqId = sequenceNum = 0;
62  rreqCount = rerrCount = 0;
63  host = getContainingNode(this);
64  routingTable = getModuleFromPar<IRoutingTable>(par("routingTableModule"), this);
65  interfaceTable = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
66  networkProtocol = getModuleFromPar<INetfilter>(par("networkProtocolModule"), this);
67 
68  aodvUDPPort = par("udpPort");
69  askGratuitousRREP = par("askGratuitousRREP");
70  useHelloMessages = par("useHelloMessages");
71  activeRouteTimeout = par("activeRouteTimeout");
72  helloInterval = par("helloInterval");
73  allowedHelloLoss = par("allowedHelloLoss");
74  netDiameter = par("netDiameter");
75  nodeTraversalTime = par("nodeTraversalTime");
76  rerrRatelimit = par("rerrRatelimit");
77  rreqRetries = par("rreqRetries");
78  rreqRatelimit = par("rreqRatelimit");
79  timeoutBuffer = par("timeoutBuffer");
80  ttlStart = par("ttlStart");
81  ttlIncrement = par("ttlIncrement");
82  ttlThreshold = par("ttlThreshold");
83  localAddTTL = par("localAddTTL");
84  jitterPar = &par("jitter");
85  periodicJitter = &par("periodicJitter");
86 
87  myRouteTimeout = par("myRouteTimeout");
88  deletePeriod = par("deletePeriod");
89  blacklistTimeout = par("blacklistTimeout");
90  netTraversalTime = par("netTraversalTime");
91  nextHopWait = par("nextHopWait");
92  pathDiscoveryTime = par("pathDiscoveryTime");
93  }
94  else if (stage == INITSTAGE_ROUTING_PROTOCOLS) {
95  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(host->getSubmodule("status"));
96  isOperational = !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
97 
99  IPSocket socket(gate("ipOut"));
100  socket.registerProtocol(IP_PROT_MANET);
101  networkProtocol->registerHook(0, this);
102  host->subscribe(NF_LINK_BREAK, this);
103 
104  if (useHelloMessages) {
105  helloMsgTimer = new cMessage("HelloMsgTimer");
106 
107  // RFC 5148:
108  // Jitter SHOULD be applied by reducing this delay by a random amount, so that
109  // the delay between consecutive transmissions of messages of the same type is
110  // equal to (MESSAGE_INTERVAL - jitter), where jitter is the random value.
111  if (isOperational)
112  scheduleAt(simTime() + helloInterval - periodicJitter->doubleValue(), helloMsgTimer);
113  }
114 
115  expungeTimer = new cMessage("ExpungeTimer");
116  counterTimer = new cMessage("CounterTimer");
117  rrepAckTimer = new cMessage("RREPACKTimer");
118  blacklistTimer = new cMessage("BlackListTimer");
119 
120  if (isOperational)
121  scheduleAt(simTime() + 1, counterTimer);
122  }
123 }
cMessage * expungeTimer
Definition: AODVRouting.h:123
unsigned int aodvUDPPort
Definition: AODVRouting.h:81
unsigned int sequenceNum
Definition: AODVRouting.h:111
simtime_t blacklistTimeout
Definition: AODVRouting.h:104
unsigned int rreqId
Definition: AODVRouting.h:110
unsigned int allowedHelloLoss
Definition: AODVRouting.h:95
bool isOperational
Definition: AODVRouting.h:130
IL3AddressType * addressType
Definition: AODVRouting.h:71
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
simsignal_t NF_LINK_BREAK
Definition: NotifierConsts.cc:43
simtime_t nodeTraversalTime
Definition: AODVRouting.h:96
IInterfaceTable * interfaceTable
Definition: AODVRouting.h:76
simtime_t pathDiscoveryTime
Definition: AODVRouting.h:107
simtime_t netTraversalTime
Definition: AODVRouting.h:105
cMessage * rrepAckTimer
Definition: AODVRouting.h:125
unsigned int rreqCount
Definition: AODVRouting.h:117
unsigned int ttlThreshold
Definition: AODVRouting.h:93
bool askGratuitousRREP
Definition: AODVRouting.h:82
simtime_t nextHopWait
Definition: AODVRouting.h:106
cPar * jitterPar
Definition: AODVRouting.h:97
Initialization of routing protocols.
Definition: InitStages.h:101
simtime_t deletePeriod
Definition: AODVRouting.h:102
cMessage * helloMsgTimer
Definition: AODVRouting.h:122
unsigned int localAddTTL
Definition: AODVRouting.h:94
Definition: IPProtocolId_m.h:93
cPar * periodicJitter
Definition: AODVRouting.h:98
simtime_t helloInterval
Definition: AODVRouting.h:86
Local initializations.
Definition: InitStages.h:35
simtime_t myRouteTimeout
Definition: AODVRouting.h:103
cMessage * blacklistTimer
Definition: AODVRouting.h:126
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:65
unsigned int netDiameter
Definition: AODVRouting.h:87
IL3AddressType * getAddressType() const
Definition: L3Address.cc:60
unsigned int rerrRatelimit
Definition: AODVRouting.h:80
simtime_t lastBroadcastTime
Definition: AODVRouting.h:118
cMessage * counterTimer
Definition: AODVRouting.h:124
unsigned int rerrCount
Definition: AODVRouting.h:116
unsigned int ttlStart
Definition: AODVRouting.h:91
unsigned int rreqRetries
Definition: AODVRouting.h:88
simtime_t rebootTime
Definition: AODVRouting.h:129
unsigned int ttlIncrement
Definition: AODVRouting.h:92
simtime_t activeRouteTimeout
Definition: AODVRouting.h:85
unsigned int rreqRatelimit
Definition: AODVRouting.h:89
virtual void registerHook(int priority, IHook *hook)=0
Adds the provided hook to the list of registered hooks that will be called by the network layer when ...
INetfilter * networkProtocol
Definition: AODVRouting.h:77
cModule * host
Definition: AODVRouting.h:74
IRoutingTable * routingTable
Definition: AODVRouting.h:75
bool useHelloMessages
Definition: AODVRouting.h:83
unsigned int timeoutBuffer
Definition: AODVRouting.h:90
Definition: NodeStatus.h:40
virtual int inet::AODVRouting::numInitStages ( ) const
inlineoverrideprotectedvirtual
138 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::AODVRouting::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprotectedvirtual
1007 {
1008  Enter_Method("receiveChangeNotification");
1009  if (signalID == NF_LINK_BREAK) {
1010  EV_DETAIL << "Received link break signal" << endl;
1011  // XXX: This is a hack for supporting both IdealMac and Ieee80211Mac. etc
1012  cPacket *frame = check_and_cast<cPacket *>(obj);
1013  INetworkDatagram *datagram = nullptr;
1014  if (false
1015 #ifdef WITH_IEEE80211
1016  || dynamic_cast<ieee80211::Ieee80211Frame *>(frame)
1017 #endif // ifdef WITH_IEEE80211
1018 #ifdef WITH_IDEALWIRELESS
1019  || dynamic_cast<IdealMacFrame *>(frame)
1020 #endif // ifdef WITH_IDEALWIRELESS
1021 #ifdef WITH_CSMA
1022  || dynamic_cast<CSMAFrame *>(frame)
1023 #endif // ifdef WITH_CSMA
1024 #ifdef WITH_CSMACA
1025  || dynamic_cast<CsmaCaMacFrame *>(frame)
1026 #endif // ifdef WITH_CSMACA
1027 #ifdef WITH_LMAC
1028  || dynamic_cast<LMacFrame *>(frame)
1029 #endif // ifdef WITH_LMAC
1030 #ifdef WITH_BMAC
1031  || dynamic_cast<BMacFrame *>(frame)
1032 #endif // ifdef WITH_BMAC
1033  )
1034  datagram = dynamic_cast<INetworkDatagram *>(frame->getEncapsulatedPacket());
1035  else
1036  throw cRuntimeError("Unknown packet type in NF_LINK_BREAK signal");
1037  if (datagram) {
1038  L3Address unreachableAddr = datagram->getDestinationAddress();
1039  if (unreachableAddr.getAddressType() == addressType) {
1040  // A node initiates processing for a RERR message in three situations:
1041  //
1042  // (i) if it detects a link break for the next hop of an active
1043  // route in its routing table while transmitting data (and
1044  // route repair, if attempted, was unsuccessful), or
1045 
1046  // TODO: Implement: local repair
1047 
1048  IRoute *route = routingTable->findBestMatchingRoute(unreachableAddr);
1049 
1050  if (route && route->getSource() == this)
1051  handleLinkBreakSendRERR(route->getNextHopAsGeneric());
1052  }
1053  }
1054  }
1055 }
IL3AddressType * addressType
Definition: AODVRouting.h:71
simsignal_t NF_LINK_BREAK
Definition: NotifierConsts.cc:43
#define WITH_LMAC
Definition: features.h:73
#define WITH_CSMA
Definition: features.h:25
void handleLinkBreakSendRERR(const L3Address &unreachableAddr)
Definition: AODVRouting.cc:1057
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::scheduleExpungeRoutes ( )
protected

Referenced by createRoute(), expungeRoutes(), handleLinkBreakSendRERR(), handleRERR(), and updateRoutingTable().

1491 {
1492  simtime_t nextExpungeTime = SimTime::getMaxTime();
1493  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1494  IRoute *route = routingTable->getRoute(i);
1495 
1496  if (route->getSource() == this) {
1497  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1498  ASSERT(routeData != nullptr);
1499 
1500  if (routeData->getLifeTime() < nextExpungeTime)
1501  nextExpungeTime = routeData->getLifeTime();
1502  }
1503  }
1504  if (nextExpungeTime == SimTime::getMaxTime()) {
1505  if (expungeTimer->isScheduled())
1506  cancelEvent(expungeTimer);
1507  }
1508  else {
1509  if (!expungeTimer->isScheduled())
1510  scheduleAt(nextExpungeTime, expungeTimer);
1511  else {
1512  if (expungeTimer->getArrivalTime() != nextExpungeTime) {
1513  cancelEvent(expungeTimer);
1514  scheduleAt(nextExpungeTime, expungeTimer);
1515  }
1516  }
1517  }
1518 }
cMessage * expungeTimer
Definition: AODVRouting.h:123
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::sendAODVPacket ( AODVControlPacket packet,
const L3Address destAddr,
unsigned int  timeToLive,
double  delay 
)
protected

Referenced by forwardRREP(), forwardRREQ(), handleLinkBreakSendRERR(), handleRERR(), sendGRREP(), sendHelloMessagesIfNeeded(), sendRERRWhenNoRouteToForward(), sendRREP(), sendRREPACK(), and sendRREQ().

733 {
734  ASSERT(timeToLive != 0);
735 
736  INetworkProtocolControlInfo *networkProtocolControlInfo = addressType->createNetworkProtocolControlInfo();
737 
738  networkProtocolControlInfo->setHopLimit(timeToLive);
739 
740  networkProtocolControlInfo->setTransportProtocol(IP_PROT_MANET);
741  networkProtocolControlInfo->setDestinationAddress(destAddr);
742  networkProtocolControlInfo->setSourceAddress(getSelfIPAddress());
743 
744  // TODO: Implement: support for multiple interfaces
745  InterfaceEntry *ifEntry = interfaceTable->getInterfaceByName("wlan0");
746  networkProtocolControlInfo->setInterfaceId(ifEntry->getInterfaceId());
747 
748  UDPPacket *udpPacket = new UDPPacket(packet->getName());
749  udpPacket->encapsulate(packet);
750  udpPacket->setSourcePort(aodvUDPPort);
751  udpPacket->setDestinationPort(aodvUDPPort);
752  udpPacket->setControlInfo(dynamic_cast<cObject *>(networkProtocolControlInfo));
753 
754  if (destAddr.isBroadcast())
755  lastBroadcastTime = simTime();
756 
757  if (delay == 0)
758  send(udpPacket, "ipOut");
759  else
760  sendDelayed(udpPacket, delay, "ipOut");
761 }
unsigned int aodvUDPPort
Definition: AODVRouting.h:81
virtual void setHopLimit(short hopLimit)=0
IL3AddressType * addressType
Definition: AODVRouting.h:71
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
IInterfaceTable * interfaceTable
Definition: AODVRouting.h:76
virtual InterfaceEntry * getInterfaceByName(const char *name) const =0
Returns an interface given by its name.
virtual void setInterfaceId(int id)
Definition: InterfaceEntry.h:155
Definition: IPProtocolId_m.h:93
simtime_t lastBroadcastTime
Definition: AODVRouting.h:118
virtual INetworkProtocolControlInfo * createNetworkProtocolControlInfo() const =0
void inet::AODVRouting::sendGRREP ( AODVRREP grrep,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected

Referenced by handleRREQ().

1352 {
1353  EV_INFO << "Sending gratuitous Route Reply to " << destAddr << endl;
1354 
1355  IRoute *destRoute = routingTable->findBestMatchingRoute(destAddr);
1356  const L3Address& nextHop = destRoute->getNextHopAsGeneric();
1357 
1358  sendAODVPacket(grrep, nextHop, timeToLive, 0);
1359 }
virtual L3Address getNextHopAsGeneric() const =0
Next hop address.
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::sendHelloMessagesIfNeeded ( )
protected

Referenced by handleMessage().

1386 {
1387  ASSERT(useHelloMessages);
1388  // Every HELLO_INTERVAL milliseconds, the node checks whether it has
1389  // sent a broadcast (e.g., a RREQ or an appropriate layer 2 message)
1390  // within the last HELLO_INTERVAL. If it has not, it MAY broadcast
1391  // a RREP with TTL = 1
1392 
1393  // A node SHOULD only use hello messages if it is part of an
1394  // active route.
1395  bool hasActiveRoute = false;
1396 
1397  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1398  IRoute *route = routingTable->getRoute(i);
1399  if (route->getSource() == this) {
1400  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1401  if (routeData->isActive()) {
1402  hasActiveRoute = true;
1403  break;
1404  }
1405  }
1406  }
1407 
1408  if (hasActiveRoute && (lastBroadcastTime == 0 || simTime() - lastBroadcastTime > helloInterval)) {
1409  EV_INFO << "It is hello time, broadcasting Hello Messages with TTL=1" << endl;
1410  AODVRREP *helloMessage = createHelloMessage();
1411  sendAODVPacket(helloMessage, addressType->getBroadcastAddress(), 1, 0);
1412  }
1413 
1414  scheduleAt(simTime() + helloInterval - periodicJitter->doubleValue(), helloMsgTimer);
1415 }
AODVRREP * createHelloMessage()
Definition: AODVRouting.cc:1361
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
IL3AddressType * addressType
Definition: AODVRouting.h:71
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
cMessage * helloMsgTimer
Definition: AODVRouting.h:122
cPar * periodicJitter
Definition: AODVRouting.h:98
simtime_t helloInterval
Definition: AODVRouting.h:86
simtime_t lastBroadcastTime
Definition: AODVRouting.h:118
virtual L3Address getBroadcastAddress() const =0
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
IRoutingTable * routingTable
Definition: AODVRouting.h:75
bool useHelloMessages
Definition: AODVRouting.h:83
void inet::AODVRouting::sendRERRWhenNoRouteToForward ( const L3Address unreachableAddr)
protected

Referenced by datagramForwardHook().

1594 {
1595  if (rerrCount >= rerrRatelimit) {
1596  EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1597  return;
1598  }
1599  std::vector<UnreachableNode> unreachableNodes;
1600  UnreachableNode node;
1601  node.addr = unreachableAddr;
1602 
1603  IRoute *unreachableRoute = routingTable->findBestMatchingRoute(unreachableAddr);
1604  AODVRouteData *unreachableRouteData = unreachableRoute ? dynamic_cast<AODVRouteData *>(unreachableRoute->getProtocolData()) : nullptr;
1605 
1606  if (unreachableRouteData && unreachableRouteData->hasValidDestNum())
1607  node.seqNum = unreachableRouteData->getDestSeqNum();
1608  else
1609  node.seqNum = 0;
1610 
1611  unreachableNodes.push_back(node);
1612  AODVRERR *rerr = createRERR(unreachableNodes);
1613 
1614  rerrCount++;
1615  EV_INFO << "Broadcasting Route Error message with TTL=1" << endl;
1616  sendAODVPacket(rerr, addressType->getBroadcastAddress(), 1, jitterPar->doubleValue()); // TODO: unicast if there exists a route to the source
1617 }
IL3AddressType * addressType
Definition: AODVRouting.h:71
cPar * jitterPar
Definition: AODVRouting.h:97
unsigned int rerrRatelimit
Definition: AODVRouting.h:80
unsigned int rerrCount
Definition: AODVRouting.h:116
AODVRERR * createRERR(const std::vector< UnreachableNode > &unreachableNodes)
Definition: AODVRouting.cc:1144
virtual L3Address getBroadcastAddress() const =0
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::sendRREP ( AODVRREP rrep,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected

Referenced by handleRREQ().

348 {
349  EV_INFO << "Sending Route Reply to " << destAddr << endl;
350 
351  // When any node transmits a RREP, the precursor list for the
352  // corresponding destination node is updated by adding to it
353  // the next hop node to which the RREP is forwarded.
354 
355  IRoute *destRoute = routingTable->findBestMatchingRoute(destAddr);
356  const L3Address& nextHop = destRoute->getNextHopAsGeneric();
357  AODVRouteData *destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
358  destRouteData->addPrecursor(nextHop);
359 
360  // The node we received the Route Request for is our neighbor,
361  // it is probably an unidirectional link
362  if (destRoute->getMetric() == 1) {
363  // It is possible that a RREP transmission may fail, especially if the
364  // RREQ transmission triggering the RREP occurs over a unidirectional
365  // link.
366 
367  rrep->setAckRequiredFlag(true);
368 
369  // when a node detects that its transmission of a RREP message has failed,
370  // it remembers the next-hop of the failed RREP in a "blacklist" set.
371 
372  failedNextHop = nextHop;
373 
374  if (rrepAckTimer->isScheduled())
375  cancelEvent(rrepAckTimer);
376 
377  scheduleAt(simTime() + nextHopWait, rrepAckTimer);
378  }
379  sendAODVPacket(rrep, nextHop, timeToLive, 0);
380 }
cMessage * rrepAckTimer
Definition: AODVRouting.h:125
simtime_t nextHopWait
Definition: AODVRouting.h:106
L3Address failedNextHop
Definition: AODVRouting.h:114
virtual L3Address getNextHopAsGeneric() const =0
Next hop address.
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75
void inet::AODVRouting::sendRREPACK ( AODVRREPACK rrepACK,
const L3Address destAddr 
)
protected

Referenced by handleRREP().

1659 {
1660  EV_INFO << "Sending Route Reply ACK to " << destAddr << endl;
1661  sendAODVPacket(rrepACK, destAddr, 100, 0);
1662 }
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
void inet::AODVRouting::sendRREQ ( AODVRREQ rreq,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected

Referenced by handleWaitForRREP(), and startRouteDiscovery().

276 {
277  // In an expanding ring search, the originating node initially uses a TTL =
278  // TTL_START in the RREQ packet IP header and sets the timeout for
279  // receiving a RREP to RING_TRAVERSAL_TIME milliseconds.
280  // RING_TRAVERSAL_TIME is calculated as described in section 10. The
281  // TTL_VALUE used in calculating RING_TRAVERSAL_TIME is set equal to the
282  // value of the TTL field in the IP header. If the RREQ times out
283  // without a corresponding RREP, the originator broadcasts the RREQ
284  // again with the TTL incremented by TTL_INCREMENT. This continues
285  // until the TTL set in the RREQ reaches TTL_THRESHOLD, beyond which a
286  // TTL = NET_DIAMETER is used for each attempt.
287 
288  if (rreqCount >= rreqRatelimit) {
289  EV_WARN << "A node should not originate more than RREQ_RATELIMIT RREQ messages per second. Canceling sending RREQ" << endl;
290  delete rreq;
291  return;
292  }
293 
294  auto rrepTimer = waitForRREPTimers.find(rreq->getDestAddr());
295  WaitForRREP *rrepTimerMsg = nullptr;
296  if (rrepTimer != waitForRREPTimers.end()) {
297  rrepTimerMsg = rrepTimer->second;
298  unsigned int lastTTL = rrepTimerMsg->getLastTTL();
299  rrepTimerMsg->setDestAddr(rreq->getDestAddr());
300 
301  // The Hop Count stored in an invalid routing table entry indicates the
302  // last known hop count to that destination in the routing table. When
303  // a new route to the same destination is required at a later time
304  // (e.g., upon route loss), the TTL in the RREQ IP header is initially
305  // set to the Hop Count plus TTL_INCREMENT. Thereafter, following each
306  // timeout the TTL is incremented by TTL_INCREMENT until TTL =
307  // TTL_THRESHOLD is reached. Beyond this TTL = NET_DIAMETER is used.
308  // Once TTL = NET_DIAMETER, the timeout for waiting for the RREP is set
309  // to NET_TRAVERSAL_TIME, as specified in section 6.3.
310 
311  if (timeToLive != 0) {
312  rrepTimerMsg->setLastTTL(timeToLive);
313  rrepTimerMsg->setFromInvalidEntry(true);
314  cancelEvent(rrepTimerMsg);
315  }
316  else if (lastTTL + ttlIncrement < ttlThreshold) {
317  ASSERT(!rrepTimerMsg->isScheduled());
318  timeToLive = lastTTL + ttlIncrement;
319  rrepTimerMsg->setLastTTL(lastTTL + ttlIncrement);
320  }
321  else {
322  ASSERT(!rrepTimerMsg->isScheduled());
323  timeToLive = netDiameter;
324  rrepTimerMsg->setLastTTL(netDiameter);
325  }
326  }
327  else {
328  rrepTimerMsg = new WaitForRREP();
329  waitForRREPTimers[rreq->getDestAddr()] = rrepTimerMsg;
330  ASSERT(hasOngoingRouteDiscovery(rreq->getDestAddr()));
331 
332  timeToLive = ttlStart;
333  rrepTimerMsg->setLastTTL(ttlStart);
334  rrepTimerMsg->setFromInvalidEntry(false);
335  rrepTimerMsg->setDestAddr(rreq->getDestAddr());
336  }
337 
338  // Each time, the timeout for receiving a RREP is RING_TRAVERSAL_TIME.
339  simtime_t ringTraversalTime = 2.0 * nodeTraversalTime * (timeToLive + timeoutBuffer);
340  scheduleAt(simTime() + ringTraversalTime, rrepTimerMsg);
341 
342  EV_INFO << "Sending a Route Request with target " << rreq->getDestAddr() << " and TTL= " << timeToLive << endl;
343  sendAODVPacket(rreq, destAddr, timeToLive, jitterPar->doubleValue());
344  rreqCount++;
345 }
simtime_t nodeTraversalTime
Definition: AODVRouting.h:96
std::map< L3Address, WaitForRREP * > waitForRREPTimers
Definition: AODVRouting.h:112
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
unsigned int rreqCount
Definition: AODVRouting.h:117
unsigned int ttlThreshold
Definition: AODVRouting.h:93
cPar * jitterPar
Definition: AODVRouting.h:97
unsigned int netDiameter
Definition: AODVRouting.h:87
unsigned int ttlStart
Definition: AODVRouting.h:91
unsigned int ttlIncrement
Definition: AODVRouting.h:92
void sendAODVPacket(AODVControlPacket *packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: AODVRouting.cc:732
unsigned int rreqRatelimit
Definition: AODVRouting.h:89
unsigned int timeoutBuffer
Definition: AODVRouting.h:90
void inet::AODVRouting::startRouteDiscovery ( const L3Address target,
unsigned int  timeToLive = 0 
)
protected

Referenced by ensureRouteForDatagram().

255 {
256  EV_INFO << "Starting route discovery with originator " << getSelfIPAddress() << " and destination " << target << endl;
257  ASSERT(!hasOngoingRouteDiscovery(target));
258  AODVRREQ *rreq = createRREQ(target);
259  addressToRreqRetries[target] = 0;
260  sendRREQ(rreq, addressType->getBroadcastAddress(), timeToLive);
261 }
IL3AddressType * addressType
Definition: AODVRouting.h:71
L3Address getSelfIPAddress() const
Definition: AODVRouting.cc:263
void sendRREQ(AODVRREQ *rreq, const L3Address &destAddr, unsigned int timeToLive)
Definition: AODVRouting.cc:275
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: AODVRouting.cc:249
AODVRREQ * createRREQ(const L3Address &destAddr)
Definition: AODVRouting.cc:382
std::map< L3Address, unsigned int > addressToRreqRetries
Definition: AODVRouting.h:119
virtual L3Address getBroadcastAddress() const =0
void inet::AODVRouting::updateRoutingTable ( IRoute route,
const L3Address nextHop,
unsigned int  hopCount,
bool  hasValidDestNum,
unsigned int  destSeqNum,
bool  isActive,
simtime_t  lifeTime 
)
protected

Referenced by handleHelloMessage(), handleRREP(), and handleRREQ().

713 {
714  EV_DETAIL << "Updating existing route: " << route << endl;
715 
716  route->setNextHop(nextHop);
717  route->setMetric(hopCount);
718 
719  AODVRouteData *routingData = check_and_cast<AODVRouteData *>(route->getProtocolData());
720  ASSERT(routingData != nullptr);
721 
722  routingData->setLifeTime(lifeTime);
723  routingData->setDestSeqNum(destSeqNum);
724  routingData->setIsActive(isActive);
725  routingData->setHasValidDestNum(hasValidDestNum);
726 
727  EV_DETAIL << "Route updated: " << route << endl;
728 
730 }
void scheduleExpungeRoutes()
Definition: AODVRouting.cc:1490
bool inet::AODVRouting::updateValidRouteLifeTime ( const L3Address destAddr,
simtime_t  lifetime 
)
protected

Referenced by datagramForwardHook(), and ensureRouteForDatagram().

1636 {
1637  IRoute *route = routingTable->findBestMatchingRoute(destAddr);
1638  if (route && route->getSource() == this) {
1639  AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1640  if (routeData->isActive()) {
1641  simtime_t newLifeTime = std::max(routeData->getLifeTime(), lifetime);
1642  EV_DETAIL << "Updating " << route << " lifetime to " << newLifeTime << endl;
1643  routeData->setLifeTime(newLifeTime);
1644  return true;
1645  }
1646  }
1647  return false;
1648 }
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
IRoutingTable * routingTable
Definition: AODVRouting.h:75

Member Data Documentation

simtime_t inet::AODVRouting::activeRouteTimeout
protected
std::map<L3Address, unsigned int> inet::AODVRouting::addressToRreqRetries
protected
unsigned int inet::AODVRouting::allowedHelloLoss = 0
protected
unsigned int inet::AODVRouting::aodvUDPPort = 0
protected

Referenced by initialize(), and sendAODVPacket().

bool inet::AODVRouting::askGratuitousRREP = false
protected

Referenced by createRREQ(), and initialize().

std::map<L3Address, simtime_t> inet::AODVRouting::blacklist
protected
simtime_t inet::AODVRouting::blacklistTimeout
protected

Referenced by handleRREPACKTimer(), and initialize().

cMessage* inet::AODVRouting::blacklistTimer = nullptr
protected
cMessage* inet::AODVRouting::counterTimer = nullptr
protected
simtime_t inet::AODVRouting::deletePeriod
protected
cMessage* inet::AODVRouting::expungeTimer = nullptr
protected
L3Address inet::AODVRouting::failedNextHop
protected

Referenced by handleRREPACKTimer(), and sendRREP().

simtime_t inet::AODVRouting::helloInterval
protected
cMessage* inet::AODVRouting::helloMsgTimer = nullptr
protected
cModule* inet::AODVRouting::host = nullptr
protected

Referenced by initialize().

IInterfaceTable* inet::AODVRouting::interfaceTable = nullptr
protected
bool inet::AODVRouting::isOperational = false
protected
cPar* inet::AODVRouting::jitterPar = nullptr
protected
simtime_t inet::AODVRouting::lastBroadcastTime
protected
unsigned int inet::AODVRouting::localAddTTL = 0
protected

Referenced by initialize().

simtime_t inet::AODVRouting::maxJitter
protected
simtime_t inet::AODVRouting::myRouteTimeout
protected

Referenced by createRREP(), and initialize().

unsigned int inet::AODVRouting::netDiameter = 0
protected
simtime_t inet::AODVRouting::netTraversalTime
protected
INetfilter* inet::AODVRouting::networkProtocol = nullptr
protected
simtime_t inet::AODVRouting::nextHopWait
protected

Referenced by initialize(), and sendRREP().

simtime_t inet::AODVRouting::nodeTraversalTime
protected

Referenced by handleRREQ(), initialize(), and sendRREQ().

simtime_t inet::AODVRouting::pathDiscoveryTime
protected

Referenced by handleRREQ(), and initialize().

cPar* inet::AODVRouting::periodicJitter = nullptr
protected
simtime_t inet::AODVRouting::rebootTime
protected
unsigned int inet::AODVRouting::rerrCount = 0
protected
unsigned int inet::AODVRouting::rerrRatelimit = 0
protected
cMessage* inet::AODVRouting::rrepAckTimer = nullptr
protected
unsigned int inet::AODVRouting::rreqCount = 0
protected
unsigned int inet::AODVRouting::rreqId = 0
protected

Referenced by clearState(), createRREQ(), and initialize().

unsigned int inet::AODVRouting::rreqRatelimit = 0
protected

Referenced by initialize(), and sendRREQ().

unsigned int inet::AODVRouting::rreqRetries = 0
protected

Referenced by handleWaitForRREP(), and initialize().

std::map<RREQIdentifier, simtime_t, RREQIdentifierCompare> inet::AODVRouting::rreqsArrivalTime
protected

Referenced by clearState(), createRREQ(), and handleRREQ().

unsigned int inet::AODVRouting::sequenceNum = 0
protected
std::multimap<L3Address, INetworkDatagram *> inet::AODVRouting::targetAddressToDelayedPackets
protected
unsigned int inet::AODVRouting::timeoutBuffer = 0
protected

Referenced by initialize(), and sendRREQ().

unsigned int inet::AODVRouting::ttlIncrement = 0
protected
unsigned int inet::AODVRouting::ttlStart = 0
protected

Referenced by initialize(), and sendRREQ().

unsigned int inet::AODVRouting::ttlThreshold = 0
protected

Referenced by initialize(), and sendRREQ().

bool inet::AODVRouting::useHelloMessages = false
protected
std::map<L3Address, WaitForRREP *> inet::AODVRouting::waitForRREPTimers
protected

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