INET Framework for OMNeT++/OMNEST
inet::aodv::Aodv Class Reference

#include <Aodv.h>

Inheritance diagram for inet::aodv::Aodv:
inet::RoutingProtocolBase inet::NetfilterBase::HookBase inet::UdpSocket::ICallback inet::OperationalBase inet::INetfilter::IHook inet::OperationalMixin< cSimpleModule > inet::ILifecycle

Classes

class  RreqIdentifier
 
class  RreqIdentifierCompare
 

Public Member Functions

 Aodv ()
 
virtual ~Aodv ()
 
- Public Member Functions inherited from inet::RoutingProtocolBase
 RoutingProtocolBase ()
 
- Public Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual ~OperationalMixin ()
 }@ More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::NetfilterBase::HookBase
virtual ~HookBase ()
 
void registeredTo (INetfilter *nf)
 
void unregisteredFrom (INetfilter *nf)
 
bool isRegisteredHook (INetfilter *nf)
 
- Public Member Functions inherited from inet::INetfilter::IHook
virtual ~IHook ()
 
- Public Member Functions inherited from inet::UdpSocket::ICallback
virtual ~ICallback ()
 

Protected Member Functions

void handleMessageWhenUp (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 ()
 
const Ptr< RrepAckcreateRREPACK ()
 
const Ptr< RrepcreateHelloMessage ()
 
const Ptr< RreqcreateRREQ (const L3Address &destAddr)
 
const Ptr< RrepcreateRREP (const Ptr< Rreq > &rreq, IRoute *destRoute, IRoute *originatorRoute, const L3Address &sourceAddr)
 
const Ptr< RrepcreateGratuitousRREP (const Ptr< Rreq > &rreq, IRoute *originatorRoute)
 
const Ptr< RerrcreateRERR (const std::vector< UnreachableNode > &unreachableNodes)
 
void handleRREP (const Ptr< Rrep > &rrep, const L3Address &sourceAddr)
 
void handleRREQ (const Ptr< Rreq > &rreq, const L3Address &sourceAddr, unsigned int timeToLive)
 
void handleRERR (const Ptr< const Rerr > &rerr, const L3Address &sourceAddr)
 
void handleHelloMessage (const Ptr< Rrep > &helloMessage)
 
void handleRREPACK (const Ptr< const RrepAck > &rrepACK, const L3Address &neighborAddr)
 
void sendRREQ (const Ptr< Rreq > &rreq, const L3Address &destAddr, unsigned int timeToLive)
 
void sendRREPACK (const Ptr< RrepAck > &rrepACK, const L3Address &destAddr)
 
void sendRREP (const Ptr< Rrep > &rrep, const L3Address &destAddr, unsigned int timeToLive)
 
void sendGRREP (const Ptr< Rrep > &grrep, const L3Address &destAddr, unsigned int timeToLive)
 
void forwardRREP (const Ptr< Rrep > &rrep, const L3Address &destAddr, unsigned int timeToLive)
 
void forwardRREQ (const Ptr< Rreq > &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 (Packet *datagram)
 
virtual Result datagramPreRoutingHook (Packet *datagram) 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 (Packet *datagram) override
 This is the second hook called by the network protocol before it sends a datagram to the lower layer. More...
 
virtual Result datagramPostRoutingHook (Packet *datagram) override
 This is the last hook called by the network protocol before it sends a datagram to the lower layer. More...
 
virtual Result datagramLocalInHook (Packet *datagram) override
 This is the last hook called by the network protocol before it sends a datagram to the upper layer. More...
 
virtual Result datagramLocalOutHook (Packet *datagram) 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 (Packet *datagram)
 
L3Address getSelfIPAddress () const
 
void sendAODVPacket (const Ptr< AodvControlPacket > &packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
 
void processPacket (Packet *pk)
 
void clearState ()
 
void checkIpVersionAndPacketTypeCompatibility (AodvControlPacketType packetType)
 
virtual void socketDataArrived (UdpSocket *socket, Packet *packet) override
 Notifies about data arrival, packet ownership is transferred to the callee. More...
 
virtual void socketErrorArrived (UdpSocket *socket, Indication *indication) override
 Notifies about error indication arrival, indication ownership is transferred to the callee. More...
 
virtual void socketClosed (UdpSocket *socket) override
 Notifies about socket closed, indication ownership is transferred to the callee. More...
 
virtual void handleStartOperation (LifecycleOperation *operation) override
 
virtual void handleStopOperation (LifecycleOperation *operation) override
 
virtual void handleCrashOperation (LifecycleOperation *operation) override
 
- Protected Member Functions inherited from inet::RoutingProtocolBase
virtual bool isInitializeStage (int stage) const override
 
virtual bool isModuleStartStage (int stage) const override
 
virtual bool isModuleStopStage (int stage) const override
 
- Protected Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual int numInitStages () const override
 
virtual void refreshDisplay () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void handleMessageWhenDown (cMessage *msg)
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual State getInitialOperationalState () const
 Returns initial operational state: OPERATING or NOT_OPERATING. More...
 
virtual void handleActiveOperationTimeout (cMessage *message)
 
virtual bool isUp () const
 utility functions More...
 
virtual bool isDown () const
 
virtual void setOperationalState (State newState)
 
virtual void scheduleOperationTimeout (simtime_t timeout)
 
virtual void setupActiveOperation (LifecycleOperation *operation, IDoneCallback *doneCallback, State)
 
virtual void delayActiveOperationFinish (simtime_t timeout)
 
virtual void startActiveOperationExtraTime (simtime_t delay=SIMTIME_ZERO)
 
virtual void startActiveOperationExtraTimeOrFinish (simtime_t extraTime)
 
virtual void finishActiveOperation ()
 

Protected Attributes

IL3AddressTypeaddressType = nullptr
 
cModule * host = nullptr
 
ModuleRefByPar< IRoutingTableroutingTable
 
ModuleRefByPar< IInterfaceTableinterfaceTable
 
ModuleRefByPar< INetfilternetworkProtocol
 
UdpSocket socket
 
bool usingIpv6 = false
 
unsigned int rerrRatelimit = 0
 
unsigned int aodvUDPPort = 0
 
bool askGratuitousRREP = false
 
bool useHelloMessages = false
 
bool destinationOnlyFlag = 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
 
std::multimap< L3Address, Packet * > targetAddressToDelayedPackets
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 
- Protected Attributes inherited from inet::NetfilterBase::HookBase
std::vector< INetfilter * > netfilters
 

Additional Inherited Members

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

Constructor & Destructor Documentation

◆ Aodv()

inet::aodv::Aodv::Aodv ( )
241 {
242 }

◆ ~Aodv()

inet::aodv::Aodv::~Aodv ( )
virtual
1699 {
1700  clearState();
1701  delete helloMsgTimer;
1702  delete expungeTimer;
1703  delete counterTimer;
1704  delete rrepAckTimer;
1705  delete blacklistTimer;
1706 }

Member Function Documentation

◆ cancelRouteDiscovery()

void inet::aodv::Aodv::cancelRouteDiscovery ( const L3Address destAddr)
protected
1603 {
1604  ASSERT(hasOngoingRouteDiscovery(destAddr));
1605  auto lt = targetAddressToDelayedPackets.lower_bound(destAddr);
1606  auto ut = targetAddressToDelayedPackets.upper_bound(destAddr);
1607  for (auto it = lt; it != ut; it++)
1608  networkProtocol->dropQueuedDatagram(const_cast<const Packet *>(it->second));
1609 
1610  targetAddressToDelayedPackets.erase(lt, ut);
1611 
1612  auto waitRREPIter = waitForRREPTimers.find(destAddr);
1613  ASSERT(waitRREPIter != waitForRREPTimers.end());
1614  cancelAndDelete(waitRREPIter->second);
1615  waitForRREPTimers.erase(waitRREPIter);
1616 }

Referenced by handleWaitForRREP().

◆ checkIpVersionAndPacketTypeCompatibility()

void inet::aodv::Aodv::checkIpVersionAndPacketTypeCompatibility ( AodvControlPacketType  packetType)
protected
120 {
121  switch (packetType) {
122  case RREQ:
123  case RREP:
124  case RERR:
125  case RREPACK:
126  if (usingIpv6)
127  throw cRuntimeError("AODV Control Packet arrived with non-IPv6 packet type %d, but AODV configured for IPv6 routing", packetType);
128  break;
129 
130  case RREQ_IPv6:
131  case RREP_IPv6:
132  case RERR_IPv6:
133  case RREPACK_IPv6:
134  if (!usingIpv6)
135  throw cRuntimeError("AODV Control Packet arrived with IPv6 packet type %d, but AODV configured for non-IPv6 routing", packetType);
136  break;
137 
138  default:
139  throw cRuntimeError("AODV Control Packet arrived with undefined packet type: %d", packetType);
140  }
141 }

Referenced by processPacket().

◆ clearState()

void inet::aodv::Aodv::clearState ( )
protected
1241 {
1243  addressToRreqRetries.clear();
1244  for (auto& elem : waitForRREPTimers)
1245  cancelAndDelete(elem.second);
1246 
1247  // FIXME Drop the queued datagrams.
1248 // for (auto it = targetAddressToDelayedPackets.begin(); it != targetAddressToDelayedPackets.end(); it++)
1249 // networkProtocol->dropQueuedDatagram(const_cast<const Packet *>(it->second));
1250 
1252 
1253  waitForRREPTimers.clear();
1254  rreqsArrivalTime.clear();
1255 
1256  if (useHelloMessages)
1257  cancelEvent(helloMsgTimer);
1258  if (expungeTimer)
1259  cancelEvent(expungeTimer);
1260  if (counterTimer)
1261  cancelEvent(counterTimer);
1262  if (blacklistTimer)
1263  cancelEvent(blacklistTimer);
1264  if (rrepAckTimer)
1265  cancelEvent(rrepAckTimer);
1266 }

Referenced by handleCrashOperation(), handleStopOperation(), and ~Aodv().

◆ completeRouteDiscovery()

void inet::aodv::Aodv::completeRouteDiscovery ( const L3Address target)
protected
1308 {
1309  EV_DETAIL << "Completing route discovery, originator " << getSelfIPAddress() << ", target " << target << endl;
1310  ASSERT(hasOngoingRouteDiscovery(target));
1311 
1312  auto lt = targetAddressToDelayedPackets.lower_bound(target);
1313  auto ut = targetAddressToDelayedPackets.upper_bound(target);
1314 
1315  // reinject the delayed datagrams
1316  for (auto it = lt; it != ut; it++) {
1317  Packet *datagram = it->second;
1318  const auto& networkHeader = getNetworkProtocolHeader(datagram);
1319  EV_DETAIL << "Sending queued datagram: source " << networkHeader->getSourceAddress() << ", destination " << networkHeader->getDestinationAddress() << endl;
1320  networkProtocol->reinjectQueuedDatagram(const_cast<const Packet *>(datagram));
1321  }
1322 
1323  // clear the multimap
1324  targetAddressToDelayedPackets.erase(lt, ut);
1325 
1326  // we have a route for the destination, thus we must cancel the WaitForRREPTimer events
1327  auto waitRREPIter = waitForRREPTimers.find(target);
1328  ASSERT(waitRREPIter != waitForRREPTimers.end());
1329  cancelAndDelete(waitRREPIter->second);
1330  waitForRREPTimers.erase(waitRREPIter);
1331 }

Referenced by handleRREP().

◆ createGratuitousRREP()

const Ptr< Rrep > inet::aodv::Aodv::createGratuitousRREP ( const Ptr< Rreq > &  rreq,
IRoute originatorRoute 
)
protected
516 {
517  ASSERT(originatorRoute != nullptr);
518  auto grrep = makeShared<Rrep>(); // TODO "AODV-GRREP");
519  grrep->setPacketType(usingIpv6 ? RREP_IPv6 : RREP);
520  grrep->setChunkLength(usingIpv6 ? B(44) : B(20));
521 
522  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(originatorRoute->getProtocolData());
523 
524  // Hop Count The Hop Count as indicated in the
525  // node's route table entry for the
526  // originator
527  //
528  // Destination IP Address The IP address of the node that
529  // originated the RREQ
530  //
531  // Destination Sequence Number The Originator Sequence Number from
532  // the RREQ
533  //
534  // Originator IP Address The IP address of the Destination
535  // node in the RREQ
536  //
537  // Lifetime The remaining lifetime of the route
538  // towards the originator of the RREQ,
539  // as known by the intermediate node.
540 
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  return grrep;
547 }

Referenced by handleRREQ().

◆ createHelloMessage()

const Ptr< Rrep > inet::aodv::Aodv::createHelloMessage ( )
protected
1344 {
1345  // called a Hello message, with the RREP
1346  // message fields set as follows:
1347  //
1348  // Destination IP Address The node's IP address.
1349  //
1350  // Destination Sequence Number The node's latest sequence number.
1351  //
1352  // Hop Count 0
1353  //
1354  // Lifetime ALLOWED_HELLO_LOSS *HELLO_INTERVAL
1355 
1356  auto helloMessage = makeShared<Rrep>(); // TODO "AODV-HelloMsg");
1357  helloMessage->setPacketType(usingIpv6 ? RREP_IPv6 : RREP);
1358  helloMessage->setChunkLength(usingIpv6 ? B(44) : B(20));
1359 
1360  helloMessage->setDestAddr(getSelfIPAddress());
1361  helloMessage->setDestSeqNum(sequenceNum);
1362  helloMessage->setHopCount(0);
1363  helloMessage->setLifeTime(allowedHelloLoss * helloInterval);
1364 
1365  return helloMessage;
1366 }

Referenced by sendHelloMessagesIfNeeded().

◆ createRERR()

const Ptr< Rerr > inet::aodv::Aodv::createRERR ( const std::vector< UnreachableNode > &  unreachableNodes)
protected
1129 {
1130  auto rerr = makeShared<Rerr>(); // TODO "AODV-RERR");
1131  rerr->setPacketType(usingIpv6 ? RERR_IPv6 : RERR);
1132 
1133  unsigned int destCount = unreachableNodes.size();
1134  rerr->setUnreachableNodesArraySize(destCount);
1135 
1136  for (unsigned int i = 0; i < destCount; i++) {
1137  UnreachableNode node;
1138  node.addr = unreachableNodes[i].addr;
1139  node.seqNum = unreachableNodes[i].seqNum;
1140  rerr->setUnreachableNodes(i, node);
1141  }
1142 
1143  rerr->setChunkLength(B(4 + destCount * (usingIpv6 ? (4 + 16) : (4 + 4))));
1144 
1145  return rerr;
1146 }

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

◆ createRoute()

IRoute * inet::aodv::Aodv::createRoute ( const L3Address destAddr,
const L3Address nextHop,
unsigned int  hopCount,
bool  hasValidDestNum,
unsigned int  destSeqNum,
bool  isActive,
simtime_t  lifeTime 
)
protected
979 {
980  // create a new route
981  IRoute *newRoute = routingTable->createRoute();
982 
983  // adding generic fields
984  newRoute->setDestination(destAddr);
985  newRoute->setNextHop(nextHop);
986  newRoute->setPrefixLength(addressType->getMaxPrefixLength()); // TODO
987  newRoute->setMetric(hopCount);
988  NetworkInterface *ifEntry = interfaceTable->findInterfaceByName(par("interface")); // TODO IMPLEMENT: multiple interfaces
989  if (ifEntry)
990  newRoute->setInterface(ifEntry);
991  newRoute->setSourceType(IRoute::AODV);
992  newRoute->setSource(this);
993 
994  // A route towards a destination that has a routing table entry
995  // that is marked as valid. Only active routes can be used to
996  // forward data packets.
997 
998  // adding protocol-specific fields
999  AodvRouteData *newProtocolData = new AodvRouteData();
1000  newProtocolData->setIsActive(isActive);
1001  newProtocolData->setHasValidDestNum(hasValidDestNum);
1002  newProtocolData->setDestSeqNum(destSeqNum);
1003  newProtocolData->setLifeTime(lifeTime);
1004  newRoute->setProtocolData(newProtocolData);
1005 
1006  EV_DETAIL << "Adding new route " << newRoute << endl;
1007  routingTable->addRoute(newRoute);
1008 
1010  return newRoute;
1011 }

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

◆ createRREP()

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

Referenced by handleRREQ().

◆ createRREPACK()

const Ptr< RrepAck > inet::aodv::Aodv::createRREPACK ( )
protected
1634 {
1635  auto rrepAck = makeShared<RrepAck>(); // TODO "AODV-RREPACK");
1636  rrepAck->setPacketType(usingIpv6 ? RREPACK_IPv6 : RREPACK);
1637  return rrepAck;
1638 }

Referenced by handleRREP().

◆ createRREQ()

const Ptr< Rreq > inet::aodv::Aodv::createRREQ ( const L3Address destAddr)
protected
375 {
376  auto rreqPacket = makeShared<Rreq>(); // TODO "AODV-RREQ");
377  rreqPacket->setPacketType(usingIpv6 ? RREQ_IPv6 : RREQ);
378  rreqPacket->setChunkLength(usingIpv6 ? B(48) : B(24));
379 
380  rreqPacket->setGratuitousRREPFlag(askGratuitousRREP);
381  IRoute *lastKnownRoute = routingTable->findBestMatchingRoute(destAddr);
382 
383  // The Originator Sequence Number in the RREQ message is the
384  // node's own sequence number, which is incremented prior to
385  // insertion in a RREQ.
386  sequenceNum++;
387 
388  rreqPacket->setOriginatorSeqNum(sequenceNum);
389 
390  if (lastKnownRoute && lastKnownRoute->getSource() == this) {
391  // The Destination Sequence Number field in the RREQ message is the last
392  // known destination sequence number for this destination and is copied
393  // from the Destination Sequence Number field in the routing table.
394 
395  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(lastKnownRoute->getProtocolData());
396  if (routeData && routeData->hasValidDestNum()) {
397  rreqPacket->setDestSeqNum(routeData->getDestSeqNum());
398  rreqPacket->setUnknownSeqNumFlag(false);
399  }
400  else
401  rreqPacket->setUnknownSeqNumFlag(true);
402  }
403  else
404  rreqPacket->setUnknownSeqNumFlag(true); // If no sequence number is known, the unknown sequence number flag MUST be set.
405 
406  rreqPacket->setOriginatorAddr(getSelfIPAddress());
407  rreqPacket->setDestAddr(destAddr);
408 
409  // The RREQ ID field is incremented by one from the last RREQ ID used
410  // by the current node. Each node maintains only one RREQ ID.
411  rreqId++;
412  rreqPacket->setRreqId(rreqId);
413 
414  // The Hop Count field is set to zero.
415  rreqPacket->setHopCount(0);
416 
417  // Destination only flag (D) indicates that only the
418  // destination may respond to this RREQ.
419  rreqPacket->setDestOnlyFlag(destinationOnlyFlag);
420 
421  // Before broadcasting the RREQ, the originating node buffers the RREQ
422  // ID and the Originator IP address (its own address) of the RREQ for
423  // PATH_DISCOVERY_TIME.
424  // In this way, when the node receives the packet again from its neighbors,
425  // it will not reprocess and re-forward the packet.
426 
427  RreqIdentifier rreqIdentifier(getSelfIPAddress(), rreqId);
428  rreqsArrivalTime[rreqIdentifier] = simTime();
429  return rreqPacket;
430 }

Referenced by handleWaitForRREP(), and startRouteDiscovery().

◆ datagramForwardHook()

INetfilter::IHook::Result inet::aodv::Aodv::datagramForwardHook ( Packet datagram)
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.

1503 {
1504  // TODO Implement: Actions After Reboot
1505  // If the node receives a data packet for some other destination, it SHOULD
1506  // broadcast a RERR as described in subsection 6.11 and MUST reset the waiting
1507  // timer to expire after current time plus DELETE_PERIOD.
1508 
1509  Enter_Method("datagramForwardHook");
1510  const auto& networkHeader = getNetworkProtocolHeader(datagram);
1511  const L3Address& destAddr = networkHeader->getDestinationAddress();
1512  const L3Address& sourceAddr = networkHeader->getSourceAddress();
1513  IRoute *ipSource = routingTable->findBestMatchingRoute(sourceAddr);
1514 
1515  if (destAddr.isBroadcast() || routingTable->isLocalAddress(destAddr) || destAddr.isMulticast()) {
1516  if (routingTable->isLocalAddress(destAddr) && ipSource && ipSource->getSource() == this)
1517  updateValidRouteLifeTime(ipSource->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1518 
1519  return ACCEPT;
1520  }
1521 
1522  // TODO IMPLEMENT: check if the datagram is a data packet or we take control packets as data packets
1523 
1524  IRoute *routeDest = routingTable->findBestMatchingRoute(destAddr);
1525  AodvRouteData *routeDestData = routeDest ? dynamic_cast<AodvRouteData *>(routeDest->getProtocolData()) : nullptr;
1526 
1527  // Each time a route is used to forward a data packet, its Active Route
1528  // Lifetime field of the source, destination and the next hop on the
1529  // path to the destination is updated to be no less than the current
1530  // time plus ACTIVE_ROUTE_TIMEOUT
1531 
1532  updateValidRouteLifeTime(sourceAddr, simTime() + activeRouteTimeout);
1533  updateValidRouteLifeTime(destAddr, simTime() + activeRouteTimeout);
1534 
1535  if (routeDest && routeDest->getSource() == this)
1536  updateValidRouteLifeTime(routeDest->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1537 
1538  // Since the route between each originator and destination pair is expected
1539  // to be symmetric, the Active Route Lifetime for the previous hop, along the
1540  // reverse path back to the IP source, is also updated to be no less than the
1541  // current time plus ACTIVE_ROUTE_TIMEOUT.
1542 
1543  if (ipSource && ipSource->getSource() == this)
1544  updateValidRouteLifeTime(ipSource->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1545 
1546  EV_INFO << "We can't forward datagram because we have no active route for " << destAddr << endl;
1547  if (routeDest && routeDestData && !routeDestData->isActive()) { // exists but is not active
1548  // A node initiates processing for a RERR message in three situations:
1549  // (ii) if it gets a data packet destined to a node for which it
1550  // does not have an active route and is not repairing (if
1551  // using local repair)
1552 
1553  // TODO check if it is not repairing (if using local repair)
1554 
1555  // 1. The destination sequence number of this routing entry, if it
1556  // exists and is valid, is incremented for cases (i) and (ii) above,
1557  // and copied from the incoming RERR in case (iii) above.
1558 
1559  if (routeDestData->hasValidDestNum())
1560  routeDestData->setDestSeqNum(routeDestData->getDestSeqNum() + 1);
1561 
1562  // 2. The entry is invalidated by marking the route entry as invalid <- it is invalid
1563 
1564  // 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
1565  // Before this time, the entry SHOULD NOT be deleted.
1566  routeDestData->setLifeTime(simTime() + deletePeriod);
1567 
1568  sendRERRWhenNoRouteToForward(destAddr);
1569  }
1570  else if (!routeDest || routeDest->getSource() != this) // doesn't exist at all
1571  sendRERRWhenNoRouteToForward(destAddr);
1572 
1573  return ACCEPT;
1574 }

◆ datagramLocalInHook()

virtual Result inet::aodv::Aodv::datagramLocalInHook ( Packet datagram)
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.

189 { return ACCEPT; }

◆ datagramLocalOutHook()

virtual Result inet::aodv::Aodv::datagramLocalOutHook ( Packet datagram)
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 outputNetworkInterface is a nullptr. After this is done

Implements inet::INetfilter::IHook.

190 { Enter_Method("datagramLocalOutHook"); return ensureRouteForDatagram(datagram); }

◆ datagramPostRoutingHook()

virtual Result inet::aodv::Aodv::datagramPostRoutingHook ( Packet datagram)
inlineoverrideprotectedvirtual

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

Implements inet::INetfilter::IHook.

188 { return ACCEPT; }

◆ datagramPreRoutingHook()

virtual Result inet::aodv::Aodv::datagramPreRoutingHook ( Packet datagram)
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 outputNetworkInterface is nullptr.

Implements inet::INetfilter::IHook.

186 { Enter_Method("datagramPreRoutingHook"); return ensureRouteForDatagram(datagram); }

◆ delayDatagram()

void inet::aodv::Aodv::delayDatagram ( Packet datagram)
protected
264 {
265  const auto& networkHeader = getNetworkProtocolHeader(datagram);
266  EV_DETAIL << "Queuing datagram, source " << networkHeader->getSourceAddress() << ", destination " << networkHeader->getDestinationAddress() << endl;
267  const L3Address& target = networkHeader->getDestinationAddress();
268  targetAddressToDelayedPackets.insert(std::pair<L3Address, Packet *>(target, datagram));
269 }

Referenced by ensureRouteForDatagram().

◆ ensureRouteForDatagram()

INetfilter::IHook::Result inet::aodv::Aodv::ensureRouteForDatagram ( Packet datagram)
protected
187 {
188  const auto& networkHeader = getNetworkProtocolHeader(datagram);
189  const L3Address& destAddr = networkHeader->getDestinationAddress();
190  const L3Address& sourceAddr = networkHeader->getSourceAddress();
191 
192  if (destAddr.isBroadcast() || routingTable->isLocalAddress(destAddr) || destAddr.isMulticast())
193  return ACCEPT;
194  else {
195  EV_INFO << "Finding route for source " << sourceAddr << " with destination " << destAddr << endl;
196  IRoute *route = routingTable->findBestMatchingRoute(destAddr);
197  AodvRouteData *routeData = route ? dynamic_cast<AodvRouteData *>(route->getProtocolData()) : nullptr;
198  bool isActive = routeData && routeData->isActive();
199  if (isActive && !route->getNextHopAsGeneric().isUnspecified()) {
200  EV_INFO << "Active route found: " << route << endl;
201 
202  // Each time a route is used to forward a data packet, its Active Route
203  // Lifetime field of the source, destination and the next hop on the
204  // path to the destination is updated to be no less than the current
205  // time plus ACTIVE_ROUTE_TIMEOUT.
206 
207  updateValidRouteLifeTime(destAddr, simTime() + activeRouteTimeout);
208  updateValidRouteLifeTime(route->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
209 
210  return ACCEPT;
211  }
212  else {
213  bool isInactive = routeData && !routeData->isActive();
214  // A node disseminates a RREQ when it determines that it needs a route
215  // to a destination and does not have one available. This can happen if
216  // the destination is previously unknown to the node, or if a previously
217  // valid route to the destination expires or is marked as invalid.
218 
219  EV_INFO << (isInactive ? "Inactive" : "Missing") << " route for destination " << destAddr << endl;
220 
221  delayDatagram(datagram);
222 
223  if (!hasOngoingRouteDiscovery(destAddr)) {
224  // When a new route to the same destination is required at a later time
225  // (e.g., upon route loss), the TTL in the RREQ IP header is initially
226  // set to the Hop Count plus TTL_INCREMENT.
227  if (isInactive)
228  startRouteDiscovery(destAddr, route->getMetric() + ttlIncrement);
229  else
230  startRouteDiscovery(destAddr);
231  }
232  else
233  EV_DETAIL << "Route discovery is in progress, originator " << getSelfIPAddress() << " target " << destAddr << endl;
234 
235  return QUEUE;
236  }
237  }
238 }

◆ expungeRoutes()

void inet::aodv::Aodv::expungeRoutes ( )
protected
1439 {
1440  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1441  IRoute *route = routingTable->getRoute(i);
1442  if (route->getSource() == this) {
1443  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(route->getProtocolData());
1444  ASSERT(routeData != nullptr);
1445  if (routeData->getLifeTime() <= simTime()) {
1446  if (routeData->isActive()) {
1447  EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and set to inactive. It will be deleted after DELETE_PERIOD time" << endl;
1448  // An expired routing table entry SHOULD NOT be expunged before
1449  // (current_time + DELETE_PERIOD) (see section 6.11). Otherwise, the
1450  // soft state corresponding to the route (e.g., last known hop count)
1451  // will be lost.
1452  routeData->setIsActive(false);
1453  routeData->setLifeTime(simTime() + deletePeriod);
1454  }
1455  else {
1456  // Any routing table entry waiting for a RREP SHOULD NOT be expunged
1457  // before (current_time + 2 * NET_TRAVERSAL_TIME).
1458  if (hasOngoingRouteDiscovery(route->getDestinationAsGeneric())) {
1459  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;
1460  routeData->setLifeTime(simTime() + 2 * netTraversalTime);
1461  }
1462  else {
1463  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;
1464  routingTable->deleteRoute(route);
1465  }
1466  }
1467  }
1468  }
1469  }
1471 }

Referenced by handleMessageWhenUp().

◆ forwardRREP()

void inet::aodv::Aodv::forwardRREP ( const Ptr< Rrep > &  rrep,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected
1291 {
1292  EV_INFO << "Forwarding the Route Reply to the node " << rrep->getOriginatorAddr() << " which originated the Route Request" << endl;
1293 
1294  // RFC 5148:
1295  // When a node forwards a message, it SHOULD be jittered by delaying it
1296  // by a random duration. This delay SHOULD be generated uniformly in an
1297  // interval between zero and MAXJITTER.
1298  sendAODVPacket(rrep, destAddr, 100, *jitterPar);
1299 }

Referenced by handleRREP().

◆ forwardRREQ()

void inet::aodv::Aodv::forwardRREQ ( const Ptr< Rreq > &  rreq,
unsigned int  timeToLive 
)
protected
1302 {
1303  EV_INFO << "Forwarding the Route Request message with TTL= " << timeToLive << endl;
1304  sendAODVPacket(rreq, addressType->getBroadcastAddress(), timeToLive, *jitterPar);
1305 }

Referenced by handleRREQ().

◆ getSelfIPAddress()

L3Address inet::aodv::Aodv::getSelfIPAddress ( ) const
protected

◆ handleBlackListTimer()

void inet::aodv::Aodv::handleBlackListTimer ( )
protected
1679 {
1680  simtime_t nextTime = SimTime::getMaxTime();
1681 
1682  for (auto it = blacklist.begin(); it != blacklist.end();) {
1683  auto current = it++;
1684 
1685  // Nodes are removed from the blacklist set after a BLACKLIST_TIMEOUT period
1686  if (current->second <= simTime()) {
1687  EV_DETAIL << "Blacklist lifetime has expired for " << current->first << " removing it from the blacklisted addresses" << endl;
1688  blacklist.erase(current);
1689  }
1690  else if (nextTime > current->second)
1691  nextTime = current->second;
1692  }
1693 
1694  if (nextTime != SimTime::getMaxTime())
1695  scheduleAt(nextTime, blacklistTimer);
1696 }

Referenced by handleMessageWhenUp().

◆ handleCrashOperation()

void inet::aodv::Aodv::handleCrashOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

1235 {
1236  socket.destroy();
1237  clearState();
1238 }

◆ handleHelloMessage()

void inet::aodv::Aodv::handleHelloMessage ( const Ptr< Rrep > &  helloMessage)
protected
1401 {
1402  const L3Address& helloOriginatorAddr = helloMessage->getDestAddr();
1403  IRoute *routeHelloOriginator = routingTable->findBestMatchingRoute(helloOriginatorAddr);
1404 
1405  // Whenever a node receives a Hello message from a neighbor, the node
1406  // SHOULD make sure that it has an active route to the neighbor, and
1407  // create one if necessary. If a route already exists, then the
1408  // Lifetime for the route should be increased, if necessary, to be at
1409  // least ALLOWED_HELLO_LOSS * HELLO_INTERVAL. The route to the
1410  // neighbor, if it exists, MUST subsequently contain the latest
1411  // Destination Sequence Number from the Hello message. The current node
1412  // can now begin using this route to forward data packets. Routes that
1413  // are created by hello messages and not used by any other active routes
1414  // will have empty precursor lists and would not trigger a RERR message
1415  // if the neighbor moves away and a neighbor timeout occurs.
1416 
1417  unsigned int latestDestSeqNum = helloMessage->getDestSeqNum();
1418  simtime_t newLifeTime = simTime() + allowedHelloLoss * helloInterval;
1419 
1420  if (!routeHelloOriginator || routeHelloOriginator->getSource() != this)
1421  createRoute(helloOriginatorAddr, helloOriginatorAddr, 1, true, latestDestSeqNum, true, newLifeTime);
1422  else {
1423  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(routeHelloOriginator->getProtocolData());
1424  simtime_t lifeTime = routeData->getLifeTime();
1425  updateRoutingTable(routeHelloOriginator, helloOriginatorAddr, 1, true, latestDestSeqNum, true, std::max(lifeTime, newLifeTime));
1426  }
1427 
1428  // TODO This feature has not implemented yet.
1429  // A node MAY determine connectivity by listening for packets from its
1430  // set of neighbors. If, within the past DELETE_PERIOD, it has received
1431  // a Hello message from a neighbor, and then for that neighbor does not
1432  // receive any packets (Hello messages or otherwise) for more than
1433  // ALLOWED_HELLO_LOSS * HELLO_INTERVAL milliseconds, the node SHOULD
1434  // assume that the link to this neighbor is currently lost. When this
1435  // happens, the node SHOULD proceed as in Section 6.11.
1436 }

Referenced by handleRREP().

◆ handleLinkBreakSendRERR()

void inet::aodv::Aodv::handleLinkBreakSendRERR ( const L3Address unreachableAddr)
protected
1042 {
1043  // For case (i), the node first makes a list of unreachable destinations
1044  // consisting of the unreachable neighbor and any additional
1045  // destinations (or subnets, see section 7) in the local routing table
1046  // that use the unreachable neighbor as the next hop.
1047 
1048  // Just before transmitting the RERR, certain updates are made on the
1049  // routing table that may affect the destination sequence numbers for
1050  // the unreachable destinations. For each one of these destinations,
1051  // the corresponding routing table entry is updated as follows:
1052  //
1053  // 1. The destination sequence number of this routing entry, if it
1054  // exists and is valid, is incremented for cases (i) and (ii) above,
1055  // and copied from the incoming RERR in case (iii) above.
1056  //
1057  // 2. The entry is invalidated by marking the route entry as invalid
1058  //
1059  // 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
1060  // Before this time, the entry SHOULD NOT be deleted.
1061 
1062  IRoute *unreachableRoute = routingTable->findBestMatchingRoute(unreachableAddr);
1063 
1064  if (!unreachableRoute || unreachableRoute->getSource() != this)
1065  return;
1066 
1067  std::vector<UnreachableNode> unreachableNodes;
1068  AodvRouteData *unreachableRouteData = check_and_cast<AodvRouteData *>(unreachableRoute->getProtocolData());
1069 
1070  if (unreachableRouteData->isActive()) {
1071  UnreachableNode node;
1072  node.addr = unreachableAddr;
1073  node.seqNum = unreachableRouteData->getDestSeqNum();
1074  unreachableNodes.push_back(node);
1075  }
1076 
1077  // For case (i), the node first makes a list of unreachable destinations
1078  // consisting of the unreachable neighbor and any additional destinations
1079  // (or subnets, see section 7) in the local routing table that use the
1080  // unreachable neighbor as the next hop.
1081 
1082  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1083  IRoute *route = routingTable->getRoute(i);
1084 
1085  AodvRouteData *routeData = dynamic_cast<AodvRouteData *>(route->getProtocolData());
1086  if (routeData && routeData->isActive() && route->getNextHopAsGeneric() == unreachableAddr) {
1087  if (routeData->hasValidDestNum())
1088  routeData->setDestSeqNum(routeData->getDestSeqNum() + 1);
1089 
1090  EV_DETAIL << "Marking route to " << route->getDestinationAsGeneric() << " as inactive" << endl;
1091 
1092  routeData->setIsActive(false);
1093  routeData->setLifeTime(simTime() + deletePeriod);
1095 
1096  UnreachableNode node;
1097  node.addr = route->getDestinationAsGeneric();
1098  node.seqNum = routeData->getDestSeqNum();
1099  unreachableNodes.push_back(node);
1100  }
1101  }
1102 
1103  // The neighboring node(s) that should receive the RERR are all those
1104  // that belong to a precursor list of at least one of the unreachable
1105  // destination(s) in the newly created RERR. In case there is only one
1106  // unique neighbor that needs to receive the RERR, the RERR SHOULD be
1107  // unicast toward that neighbor. Otherwise the RERR is typically sent
1108  // to the local broadcast address (Destination IP == 255.255.255.255,
1109  // TTL == 1) with the unreachable destinations, and their corresponding
1110  // destination sequence numbers, included in the packet.
1111 
1112  if (rerrCount >= rerrRatelimit) {
1113  EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1114  return;
1115  }
1116 
1117  if (unreachableNodes.empty())
1118  return;
1119 
1120  auto rerr = createRERR(unreachableNodes);
1121  rerrCount++;
1122 
1123  // broadcast
1124  EV_INFO << "Broadcasting Route Error message with TTL=1" << endl;
1126 }

Referenced by receiveSignal().

◆ handleMessageWhenUp()

void inet::aodv::Aodv::handleMessageWhenUp ( cMessage *  msg)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

91 {
92  if (msg->isSelfMessage()) {
93  if (auto waitForRrep = dynamic_cast<WaitForRrep *>(msg))
94  handleWaitForRREP(waitForRrep);
95  else if (msg == helloMsgTimer)
97  else if (msg == expungeTimer)
98  expungeRoutes();
99  else if (msg == counterTimer) {
100  rreqCount = rerrCount = 0;
101  scheduleAfter(1, counterTimer);
102  }
103  else if (msg == rrepAckTimer)
105  else if (msg == blacklistTimer)
107  else if (msg->getKind() == KIND_DELAYEDSEND) {
108  auto timer = check_and_cast<PacketHolderMessage *>(msg);
109  socket.send(timer->removeOwnedPacket());
110  delete timer;
111  }
112  else
113  throw cRuntimeError("Unknown self message");
114  }
115  else
116  socket.processMessage(msg);
117 }

◆ handleRERR()

void inet::aodv::Aodv::handleRERR ( const Ptr< const Rerr > &  rerr,
const L3Address sourceAddr 
)
protected
1149 {
1150  EV_INFO << "AODV Route Error arrived with source addr: " << sourceAddr << endl;
1151 
1152  // A node initiates processing for a RERR message in three situations:
1153  // (iii) if it receives a RERR from a neighbor for one or more
1154  // active routes.
1155  unsigned int unreachableArraySize = rerr->getUnreachableNodesArraySize();
1156  std::vector<UnreachableNode> unreachableNeighbors;
1157 
1158  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1159  IRoute *route = routingTable->getRoute(i);
1160  AodvRouteData *routeData = route ? dynamic_cast<AodvRouteData *>(route->getProtocolData()) : nullptr;
1161 
1162  if (!routeData)
1163  continue;
1164 
1165  // For case (iii), the list should consist of those destinations in the RERR
1166  // for which there exists a corresponding entry in the local routing
1167  // table that has the transmitter of the received RERR as the next hop.
1168 
1169  if (routeData->isActive() && route->getNextHopAsGeneric() == sourceAddr) {
1170  for (unsigned int j = 0; j < unreachableArraySize; j++) {
1171  if (route->getDestinationAsGeneric() == rerr->getUnreachableNodes(j).addr) {
1172  // 1. The destination sequence number of this routing entry, if it
1173  // exists and is valid, is incremented for cases (i) and (ii) above,
1174  // ! and copied from the incoming RERR in case (iii) above.
1175 
1176  routeData->setDestSeqNum(rerr->getUnreachableNodes(j).seqNum);
1177  routeData->setIsActive(false); // it means invalid, see 3. AODV Terminology p.3. in RFC 3561
1178  routeData->setLifeTime(simTime() + deletePeriod);
1179 
1180  // The RERR should contain those destinations that are part of
1181  // the created list of unreachable destinations and have a non-empty
1182  // precursor list.
1183 
1184  if (routeData->getPrecursorList().size() > 0) {
1185  UnreachableNode node;
1186  node.addr = route->getDestinationAsGeneric();
1187  node.seqNum = routeData->getDestSeqNum();
1188  unreachableNeighbors.push_back(node);
1189  }
1191  }
1192  }
1193  }
1194  }
1195 
1196  if (rerrCount >= rerrRatelimit) {
1197  EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1198  return;
1199  }
1200 
1201  if (unreachableNeighbors.size() > 0 && (simTime() > rebootTime + deletePeriod || rebootTime == 0)) {
1202  EV_INFO << "Sending RERR to inform our neighbors about link breaks." << endl;
1203  auto newRERR = createRERR(unreachableNeighbors);
1204  sendAODVPacket(newRERR, addressType->getBroadcastAddress(), 1, 0);
1205  rerrCount++;
1206  }
1207 }

Referenced by processPacket().

◆ handleRREP()

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

Referenced by processPacket().

◆ handleRREPACK()

void inet::aodv::Aodv::handleRREPACK ( const Ptr< const RrepAck > &  rrepACK,
const L3Address neighborAddr 
)
protected
1647 {
1648  // Note that the RREP-ACK packet does not contain any information about
1649  // which RREP it is acknowledging. The time at which the RREP-ACK is
1650  // received will likely come just after the time when the RREP was sent
1651  // with the 'A' bit.
1652  if (rrepAckTimer->isScheduled()) {
1653  EV_INFO << "RREP-ACK arrived from " << neighborAddr << endl;
1654 
1655  IRoute *route = routingTable->findBestMatchingRoute(neighborAddr);
1656  if (route && route->getSource() == this) {
1657  EV_DETAIL << "Marking route " << route << " as active" << endl;
1658  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(route->getProtocolData());
1659  routeData->setIsActive(true);
1660  cancelEvent(rrepAckTimer);
1661  }
1662  }
1663 }

Referenced by processPacket().

◆ handleRREPACKTimer()

void inet::aodv::Aodv::handleRREPACKTimer ( )
protected
1666 {
1667  // when a node detects that its transmission of a RREP message has failed,
1668  // it remembers the next-hop of the failed RREP in a "blacklist" set.
1669 
1670  EV_INFO << "RREP-ACK didn't arrived within timeout. Adding " << failedNextHop << " to the blacklist" << endl;
1671 
1672  blacklist[failedNextHop] = simTime() + blacklistTimeout; // lifetime
1673 
1674  if (!blacklistTimer->isScheduled())
1675  scheduleAfter(blacklistTimeout, blacklistTimer);
1676 }

Referenced by handleMessageWhenUp().

◆ handleRREQ()

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

Referenced by processPacket().

◆ handleStartOperation()

void inet::aodv::Aodv::handleStartOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

1210 {
1211  rebootTime = simTime();
1212 
1213  socket.setOutputGate(gate("socketOut"));
1214  socket.setCallback(this);
1215  socket.bind(L3Address(), aodvUDPPort);
1216  socket.setBroadcast(true);
1217 
1218  // RFC 5148:
1219  // Jitter SHOULD be applied by reducing this delay by a random amount, so that
1220  // the delay between consecutive transmissions of messages of the same type is
1221  // equal to (MESSAGE_INTERVAL - jitter), where jitter is the random value.
1222  if (useHelloMessages)
1223  scheduleAfter(helloInterval - *periodicJitter, helloMsgTimer);
1224 
1225  scheduleAfter(1, counterTimer);
1226 }

◆ handleStopOperation()

void inet::aodv::Aodv::handleStopOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

1229 {
1230  socket.close();
1231  clearState();
1232 }

◆ handleWaitForRREP()

void inet::aodv::Aodv::handleWaitForRREP ( WaitForRrep rrepTimer)
protected
1269 {
1270  EV_INFO << "We didn't get any Route Reply within RREP timeout" << endl;
1271  L3Address destAddr = rrepTimer->getDestAddr();
1272 
1273  ASSERT(containsKey(addressToRreqRetries, destAddr));
1274  if (addressToRreqRetries[destAddr] == rreqRetries) {
1275  cancelRouteDiscovery(destAddr);
1276  EV_WARN << "Re-discovery attempts for node " << destAddr << " reached RREQ_RETRIES= " << rreqRetries << " limit. Stop sending RREQ." << endl;
1277  return;
1278  }
1279 
1280  auto rreq = createRREQ(destAddr);
1281 
1282  // the node MAY try again to discover a route by broadcasting another
1283  // RREQ, up to a maximum of RREQ_RETRIES times at the maximum TTL value.
1284  if (rrepTimer->getLastTTL() == netDiameter) // netDiameter is the maximum TTL value
1285  addressToRreqRetries[destAddr]++;
1286 
1288 }

Referenced by handleMessageWhenUp().

◆ hasOngoingRouteDiscovery()

bool inet::aodv::Aodv::hasOngoingRouteDiscovery ( const L3Address destAddr)
protected

◆ initialize()

void inet::aodv::Aodv::initialize ( int  stage)
overrideprotectedvirtual

Reimplemented from inet::OperationalMixin< cSimpleModule >.

34 {
35  if (stage == INITSTAGE_ROUTING_PROTOCOLS)
36  addressType = getSelfIPAddress().getAddressType(); // needed for handleStartOperation()
37 
39 
40  if (stage == INITSTAGE_LOCAL) {
41  lastBroadcastTime = SIMTIME_ZERO;
42  rebootTime = SIMTIME_ZERO;
43  rreqId = sequenceNum = 0;
44  rreqCount = rerrCount = 0;
45  host = getContainingNode(this);
46  routingTable.reference(this, "routingTableModule", true);
47  interfaceTable.reference(this, "interfaceTableModule", true);
48  networkProtocol.reference(this, "networkProtocolModule", true);
49 
50  aodvUDPPort = par("udpPort");
51  askGratuitousRREP = par("askGratuitousRREP");
52  useHelloMessages = par("useHelloMessages");
53  destinationOnlyFlag = par("destinationOnlyFlag");
54  activeRouteTimeout = par("activeRouteTimeout");
55  helloInterval = par("helloInterval");
56  allowedHelloLoss = par("allowedHelloLoss");
57  netDiameter = par("netDiameter");
58  nodeTraversalTime = par("nodeTraversalTime");
59  rerrRatelimit = par("rerrRatelimit");
60  rreqRetries = par("rreqRetries");
61  rreqRatelimit = par("rreqRatelimit");
62  timeoutBuffer = par("timeoutBuffer");
63  ttlStart = par("ttlStart");
64  ttlIncrement = par("ttlIncrement");
65  ttlThreshold = par("ttlThreshold");
66  localAddTTL = par("localAddTTL");
67  jitterPar = &par("jitter");
68  periodicJitter = &par("periodicJitter");
69 
70  myRouteTimeout = par("myRouteTimeout");
71  deletePeriod = par("deletePeriod");
72  blacklistTimeout = par("blacklistTimeout");
73  netTraversalTime = par("netTraversalTime");
74  nextHopWait = par("nextHopWait");
75  pathDiscoveryTime = par("pathDiscoveryTime");
76  expungeTimer = new cMessage("ExpungeTimer");
77  counterTimer = new cMessage("CounterTimer");
78  rrepAckTimer = new cMessage("RrepAckTimer");
79  blacklistTimer = new cMessage("BlackListTimer");
80  if (useHelloMessages)
81  helloMsgTimer = new cMessage("HelloMsgTimer");
82  }
83  else if (stage == INITSTAGE_ROUTING_PROTOCOLS) {
84  networkProtocol->registerHook(0, this);
85  host->subscribe(linkBrokenSignal, this);
86  usingIpv6 = (routingTable->getRouterIdAsGeneric().getType() == L3Address::IPv6);
87  }
88 }

◆ numInitStages()

virtual int inet::aodv::Aodv::numInitStages ( ) const
inlineoverrideprotectedvirtual
133 { return NUM_INIT_STAGES; }

◆ processPacket()

void inet::aodv::Aodv::processPacket ( Packet pk)
protected
144 {
145  L3Address sourceAddr = packet->getTag<L3AddressInd>()->getSrcAddress();
146  // KLUDGE I added this -1 after TTL decrement has been moved in Ipv4
147  unsigned int arrivalPacketTTL = packet->getTag<HopLimitInd>()->getHopLimit() - 1;
148  const auto& aodvPacket = packet->popAtFront<AodvControlPacket>();
149  // TODO aodvPacket->copyTags(*udpPacket);
150 
151  auto packetType = aodvPacket->getPacketType();
152  switch (packetType) {
153  case RREQ:
154  case RREQ_IPv6:
156  handleRREQ(CHK(dynamicPtrCast<Rreq>(aodvPacket->dupShared())), sourceAddr, arrivalPacketTTL);
157  delete packet;
158  return;
159 
160  case RREP:
161  case RREP_IPv6:
163  handleRREP(CHK(dynamicPtrCast<Rrep>(aodvPacket->dupShared())), sourceAddr);
164  delete packet;
165  return;
166 
167  case RERR:
168  case RERR_IPv6:
170  handleRERR(CHK(dynamicPtrCast<const Rerr>(aodvPacket)), sourceAddr);
171  delete packet;
172  return;
173 
174  case RREPACK:
175  case RREPACK_IPv6:
177  handleRREPACK(CHK(dynamicPtrCast<const RrepAck>(aodvPacket)), sourceAddr);
178  delete packet;
179  return;
180 
181  default:
182  throw cRuntimeError("AODV Control Packet arrived with undefined packet type: %d", packetType);
183  }
184 }

Referenced by socketDataArrived().

◆ receiveSignal()

void inet::aodv::Aodv::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprotectedvirtual
1014 {
1015  Enter_Method("%s", cComponent::getSignalName(signalID));
1016 
1017  if (signalID == linkBrokenSignal) {
1018  EV_DETAIL << "Received link break signal" << endl;
1019  Packet *datagram = check_and_cast<Packet *>(obj);
1020  const auto& networkHeader = findNetworkProtocolHeader(datagram);
1021  if (networkHeader != nullptr) {
1022  L3Address unreachableAddr = networkHeader->getDestinationAddress();
1023  if (unreachableAddr.getAddressType() == addressType) {
1024  // A node initiates processing for a RERR message in three situations:
1025  //
1026  // (i) if it detects a link break for the next hop of an active
1027  // route in its routing table while transmitting data (and
1028  // route repair, if attempted, was unsuccessful), or
1029 
1030  // TODO Implement: local repair
1031 
1032  IRoute *route = routingTable->findBestMatchingRoute(unreachableAddr);
1033 
1034  if (route && route->getSource() == this)
1035  handleLinkBreakSendRERR(route->getNextHopAsGeneric());
1036  }
1037  }
1038  }
1039 }

◆ scheduleExpungeRoutes()

void inet::aodv::Aodv::scheduleExpungeRoutes ( )
protected
1474 {
1475  simtime_t nextExpungeTime = SimTime::getMaxTime();
1476  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1477  IRoute *route = routingTable->getRoute(i);
1478 
1479  if (route->getSource() == this) {
1480  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(route->getProtocolData());
1481  ASSERT(routeData != nullptr);
1482 
1483  if (routeData->getLifeTime() < nextExpungeTime)
1484  nextExpungeTime = routeData->getLifeTime();
1485  }
1486  }
1487  if (nextExpungeTime == SimTime::getMaxTime()) {
1488  if (expungeTimer->isScheduled())
1489  cancelEvent(expungeTimer);
1490  }
1491  else {
1492  if (!expungeTimer->isScheduled())
1493  scheduleAt(nextExpungeTime, expungeTimer);
1494  else {
1495  if (expungeTimer->getArrivalTime() != nextExpungeTime) {
1496  rescheduleAt(nextExpungeTime, expungeTimer);
1497  }
1498  }
1499  }
1500 }

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

◆ sendAODVPacket()

void inet::aodv::Aodv::sendAODVPacket ( const Ptr< AodvControlPacket > &  packet,
const L3Address destAddr,
unsigned int  timeToLive,
double  delay 
)
protected
730 {
731  ASSERT(timeToLive != 0);
732 
733  const char *className = aodvPacket->getClassName();
734  Packet *packet = new Packet(!strncmp("inet::", className, 6) ? className + 6 : className);
735  packet->insertAtBack(aodvPacket);
736 
737  int interfaceId = CHK(interfaceTable->findInterfaceByName(par("interface")))->getInterfaceId(); // TODO Implement: support for multiple interfaces
738  packet->addTag<InterfaceReq>()->setInterfaceId(interfaceId);
739  packet->addTag<HopLimitReq>()->setHopLimit(timeToLive);
740  packet->addTag<L3AddressReq>()->setDestAddress(destAddr);
741  packet->addTag<L4PortReq>()->setDestPort(aodvUDPPort);
742 
743  if (destAddr.isBroadcast())
744  lastBroadcastTime = simTime();
745 
746  if (delay == 0)
747  socket.send(packet);
748  else {
749  auto *timer = new PacketHolderMessage("aodv-send-jitter", KIND_DELAYEDSEND);
750  timer->setOwnedPacket(packet);
751  scheduleAfter(delay, timer);
752  }
753 }

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

◆ sendGRREP()

void inet::aodv::Aodv::sendGRREP ( const Ptr< Rrep > &  grrep,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected
1334 {
1335  EV_INFO << "Sending gratuitous Route Reply to " << destAddr << endl;
1336 
1337  IRoute *destRoute = routingTable->findBestMatchingRoute(destAddr);
1338  const L3Address& nextHop = destRoute->getNextHopAsGeneric();
1339 
1340  sendAODVPacket(grrep, nextHop, timeToLive, 0);
1341 }

Referenced by handleRREQ().

◆ sendHelloMessagesIfNeeded()

void inet::aodv::Aodv::sendHelloMessagesIfNeeded ( )
protected
1369 {
1370  ASSERT(useHelloMessages);
1371  // Every HELLO_INTERVAL milliseconds, the node checks whether it has
1372  // sent a broadcast (e.g., a RREQ or an appropriate layer 2 message)
1373  // within the last HELLO_INTERVAL. If it has not, it MAY broadcast
1374  // a RREP with TTL = 1
1375 
1376  // A node SHOULD only use hello messages if it is part of an
1377  // active route.
1378  bool hasActiveRoute = false;
1379 
1380  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1381  IRoute *route = routingTable->getRoute(i);
1382  if (route->getSource() == this) {
1383  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(route->getProtocolData());
1384  if (routeData->isActive()) {
1385  hasActiveRoute = true;
1386  break;
1387  }
1388  }
1389  }
1390 
1391  if (hasActiveRoute && (lastBroadcastTime == 0 || simTime() - lastBroadcastTime > helloInterval)) {
1392  EV_INFO << "It is hello time, broadcasting Hello Messages with TTL=1" << endl;
1393  auto helloMessage = createHelloMessage();
1394  sendAODVPacket(helloMessage, addressType->getBroadcastAddress(), 1, 0);
1395  }
1396 
1397  scheduleAfter(helloInterval - *periodicJitter, helloMsgTimer);
1398 }

Referenced by handleMessageWhenUp().

◆ sendRERRWhenNoRouteToForward()

void inet::aodv::Aodv::sendRERRWhenNoRouteToForward ( const L3Address unreachableAddr)
protected
1577 {
1578  if (rerrCount >= rerrRatelimit) {
1579  EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1580  return;
1581  }
1582  std::vector<UnreachableNode> unreachableNodes;
1583  UnreachableNode node;
1584  node.addr = unreachableAddr;
1585 
1586  IRoute *unreachableRoute = routingTable->findBestMatchingRoute(unreachableAddr);
1587  AodvRouteData *unreachableRouteData = unreachableRoute ? dynamic_cast<AodvRouteData *>(unreachableRoute->getProtocolData()) : nullptr;
1588 
1589  if (unreachableRouteData && unreachableRouteData->hasValidDestNum())
1590  node.seqNum = unreachableRouteData->getDestSeqNum();
1591  else
1592  node.seqNum = 0;
1593 
1594  unreachableNodes.push_back(node);
1595  auto rerr = createRERR(unreachableNodes);
1596 
1597  rerrCount++;
1598  EV_INFO << "Broadcasting Route Error message with TTL=1" << endl;
1599  sendAODVPacket(rerr, addressType->getBroadcastAddress(), 1, *jitterPar); // TODO unicast if there exists a route to the source
1600 }

Referenced by datagramForwardHook().

◆ sendRREP()

void inet::aodv::Aodv::sendRREP ( const Ptr< Rrep > &  rrep,
const L3Address destAddr,
unsigned int  timeToLive 
)
protected
343 {
344  EV_INFO << "Sending Route Reply to " << destAddr << endl;
345 
346  // When any node transmits a RREP, the precursor list for the
347  // corresponding destination node is updated by adding to it
348  // the next hop node to which the RREP is forwarded.
349 
350  IRoute *destRoute = routingTable->findBestMatchingRoute(destAddr);
351  const L3Address& nextHop = destRoute->getNextHopAsGeneric();
352  AodvRouteData *destRouteData = check_and_cast<AodvRouteData *>(destRoute->getProtocolData());
353  destRouteData->addPrecursor(nextHop);
354 
355  // The node we received the Route Request for is our neighbor,
356  // it is probably an unidirectional link
357  if (destRoute->getMetric() == 1) {
358  // It is possible that a RREP transmission may fail, especially if the
359  // RREQ transmission triggering the RREP occurs over a unidirectional
360  // link.
361 
362  rrep->setAckRequiredFlag(true);
363 
364  // when a node detects that its transmission of a RREP message has failed,
365  // it remembers the next-hop of the failed RREP in a "blacklist" set.
366 
367  failedNextHop = nextHop;
368 
369  rescheduleAfter(nextHopWait, rrepAckTimer);
370  }
371  sendAODVPacket(rrep, nextHop, timeToLive, 0);
372 }

Referenced by handleRREQ().

◆ sendRREPACK()

void inet::aodv::Aodv::sendRREPACK ( const Ptr< RrepAck > &  rrepACK,
const L3Address destAddr 
)
protected
1641 {
1642  EV_INFO << "Sending Route Reply ACK to " << destAddr << endl;
1643  sendAODVPacket(rrepACK, destAddr, 100, 0);
1644 }

Referenced by handleRREP().

◆ sendRREQ()

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

Referenced by handleWaitForRREP(), and startRouteDiscovery().

◆ socketClosed()

void inet::aodv::Aodv::socketClosed ( UdpSocket socket)
overrideprotectedvirtual

Notifies about socket closed, indication ownership is transferred to the callee.

Implements inet::UdpSocket::ICallback.

768 {
769  if (operationalState == State::STOPPING_OPERATION)
770  startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
771 }

◆ socketDataArrived()

void inet::aodv::Aodv::socketDataArrived ( UdpSocket socket,
Packet packet 
)
overrideprotectedvirtual

Notifies about data arrival, packet ownership is transferred to the callee.

Implements inet::UdpSocket::ICallback.

756 {
757  // process incoming packet
758  processPacket(packet);
759 }

◆ socketErrorArrived()

void inet::aodv::Aodv::socketErrorArrived ( UdpSocket socket,
Indication indication 
)
overrideprotectedvirtual

Notifies about error indication arrival, indication ownership is transferred to the callee.

Implements inet::UdpSocket::ICallback.

762 {
763  EV_WARN << "Ignoring UDP error report " << indication->getName() << endl;
764  delete indication;
765 }

◆ startRouteDiscovery()

void inet::aodv::Aodv::startRouteDiscovery ( const L3Address target,
unsigned int  timeToLive = 0 
)
protected
250 {
251  EV_INFO << "Starting route discovery with originator " << getSelfIPAddress() << " and destination " << target << endl;
252  ASSERT(!hasOngoingRouteDiscovery(target));
253  auto rreq = createRREQ(target);
254  addressToRreqRetries[target] = 0;
255  sendRREQ(rreq, addressType->getBroadcastAddress(), timeToLive);
256 }

Referenced by ensureRouteForDatagram().

◆ updateRoutingTable()

void inet::aodv::Aodv::updateRoutingTable ( IRoute route,
const L3Address nextHop,
unsigned int  hopCount,
bool  hasValidDestNum,
unsigned int  destSeqNum,
bool  isActive,
simtime_t  lifeTime 
)
protected
710 {
711  EV_DETAIL << "Updating existing route: " << route << endl;
712 
713  route->setNextHop(nextHop);
714  route->setMetric(hopCount);
715 
716  AodvRouteData *routingData = check_and_cast<AodvRouteData *>(route->getProtocolData());
717  ASSERT(routingData != nullptr);
718 
719  routingData->setLifeTime(lifeTime);
720  routingData->setDestSeqNum(destSeqNum);
721  routingData->setIsActive(isActive);
722  routingData->setHasValidDestNum(hasValidDestNum);
723 
724  EV_DETAIL << "Route updated: " << route << endl;
725 
727 }

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

◆ updateValidRouteLifeTime()

bool inet::aodv::Aodv::updateValidRouteLifeTime ( const L3Address destAddr,
simtime_t  lifetime 
)
protected
1619 {
1620  IRoute *route = routingTable->findBestMatchingRoute(destAddr);
1621  if (route && route->getSource() == this) {
1622  AodvRouteData *routeData = check_and_cast<AodvRouteData *>(route->getProtocolData());
1623  if (routeData->isActive()) {
1624  simtime_t newLifeTime = std::max(routeData->getLifeTime(), lifetime);
1625  EV_DETAIL << "Updating " << route << " lifetime to " << newLifeTime << endl;
1626  routeData->setLifeTime(newLifeTime);
1627  return true;
1628  }
1629  }
1630  return false;
1631 }

Referenced by datagramForwardHook(), and ensureRouteForDatagram().

Member Data Documentation

◆ activeRouteTimeout

simtime_t inet::aodv::Aodv::activeRouteTimeout
protected

◆ addressToRreqRetries

std::map<L3Address, unsigned int> inet::aodv::Aodv::addressToRreqRetries
protected

◆ addressType

◆ allowedHelloLoss

unsigned int inet::aodv::Aodv::allowedHelloLoss = 0
protected

◆ aodvUDPPort

unsigned int inet::aodv::Aodv::aodvUDPPort = 0
protected

◆ askGratuitousRREP

bool inet::aodv::Aodv::askGratuitousRREP = false
protected

Referenced by createRREQ(), and initialize().

◆ blacklist

std::map<L3Address, simtime_t> inet::aodv::Aodv::blacklist
protected

◆ blacklistTimeout

simtime_t inet::aodv::Aodv::blacklistTimeout
protected

Referenced by handleRREPACKTimer(), and initialize().

◆ blacklistTimer

cMessage* inet::aodv::Aodv::blacklistTimer = nullptr
protected

◆ counterTimer

cMessage* inet::aodv::Aodv::counterTimer = nullptr
protected

◆ deletePeriod

simtime_t inet::aodv::Aodv::deletePeriod
protected

◆ destinationOnlyFlag

bool inet::aodv::Aodv::destinationOnlyFlag = false
protected

Referenced by createRREQ(), and initialize().

◆ expungeTimer

cMessage* inet::aodv::Aodv::expungeTimer = nullptr
protected

◆ failedNextHop

L3Address inet::aodv::Aodv::failedNextHop
protected

Referenced by handleRREPACKTimer(), and sendRREP().

◆ helloInterval

simtime_t inet::aodv::Aodv::helloInterval
protected

◆ helloMsgTimer

cMessage* inet::aodv::Aodv::helloMsgTimer = nullptr
protected

◆ host

cModule* inet::aodv::Aodv::host = nullptr
protected

Referenced by initialize().

◆ interfaceTable

ModuleRefByPar<IInterfaceTable> inet::aodv::Aodv::interfaceTable
protected

◆ jitterPar

cPar* inet::aodv::Aodv::jitterPar = nullptr
protected

◆ lastBroadcastTime

simtime_t inet::aodv::Aodv::lastBroadcastTime
protected

◆ localAddTTL

unsigned int inet::aodv::Aodv::localAddTTL = 0
protected

Referenced by initialize().

◆ maxJitter

simtime_t inet::aodv::Aodv::maxJitter
protected

◆ myRouteTimeout

simtime_t inet::aodv::Aodv::myRouteTimeout
protected

Referenced by createRREP(), and initialize().

◆ netDiameter

unsigned int inet::aodv::Aodv::netDiameter = 0
protected

◆ netTraversalTime

simtime_t inet::aodv::Aodv::netTraversalTime
protected

◆ networkProtocol

ModuleRefByPar<INetfilter> inet::aodv::Aodv::networkProtocol
protected

◆ nextHopWait

simtime_t inet::aodv::Aodv::nextHopWait
protected

Referenced by initialize(), and sendRREP().

◆ nodeTraversalTime

simtime_t inet::aodv::Aodv::nodeTraversalTime
protected

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

◆ pathDiscoveryTime

simtime_t inet::aodv::Aodv::pathDiscoveryTime
protected

Referenced by handleRREQ(), and initialize().

◆ periodicJitter

cPar* inet::aodv::Aodv::periodicJitter = nullptr
protected

◆ rebootTime

simtime_t inet::aodv::Aodv::rebootTime
protected

◆ rerrCount

unsigned int inet::aodv::Aodv::rerrCount = 0
protected

◆ rerrRatelimit

unsigned int inet::aodv::Aodv::rerrRatelimit = 0
protected

◆ routingTable

◆ rrepAckTimer

cMessage* inet::aodv::Aodv::rrepAckTimer = nullptr
protected

◆ rreqCount

unsigned int inet::aodv::Aodv::rreqCount = 0
protected

◆ rreqId

unsigned int inet::aodv::Aodv::rreqId = 0
protected

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

◆ rreqRatelimit

unsigned int inet::aodv::Aodv::rreqRatelimit = 0
protected

Referenced by initialize(), and sendRREQ().

◆ rreqRetries

unsigned int inet::aodv::Aodv::rreqRetries = 0
protected

Referenced by handleWaitForRREP(), and initialize().

◆ rreqsArrivalTime

std::map<RreqIdentifier, simtime_t, RreqIdentifierCompare> inet::aodv::Aodv::rreqsArrivalTime
protected

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

◆ sequenceNum

unsigned int inet::aodv::Aodv::sequenceNum = 0
protected

◆ socket

◆ targetAddressToDelayedPackets

std::multimap<L3Address, Packet *> inet::aodv::Aodv::targetAddressToDelayedPackets
protected

◆ timeoutBuffer

unsigned int inet::aodv::Aodv::timeoutBuffer = 0
protected

Referenced by initialize(), and sendRREQ().

◆ ttlIncrement

unsigned int inet::aodv::Aodv::ttlIncrement = 0
protected

◆ ttlStart

unsigned int inet::aodv::Aodv::ttlStart = 0
protected

Referenced by initialize(), and sendRREQ().

◆ ttlThreshold

unsigned int inet::aodv::Aodv::ttlThreshold = 0
protected

Referenced by initialize(), and sendRREQ().

◆ useHelloMessages

bool inet::aodv::Aodv::useHelloMessages = false
protected

◆ usingIpv6

◆ waitForRREPTimers

std::map<L3Address, WaitForRrep *> inet::aodv::Aodv::waitForRREPTimers
protected

The documentation for this class was generated from the following files:
inet::UdpSocket::setOutputGate
void setOutputGate(cGate *toUdp)
Sets the gate on which to send to UDP.
Definition: UdpSocket.h:117
CHK
#define CHK(x)
Definition: INETDefs.h:87
inet::aodv::Aodv::createHelloMessage
const Ptr< Rrep > createHelloMessage()
Definition: Aodv.cc:1343
inet::aodv::Aodv::expungeTimer
cMessage * expungeTimer
Definition: Aodv.h:119
inet::IRoute::AODV
@ AODV
managed by AODV routing
Definition: IRoute.h:41
inet::aodv::Aodv::createRERR
const Ptr< Rerr > createRERR(const std::vector< UnreachableNode > &unreachableNodes)
Definition: Aodv.cc:1128
inet::aodv::Aodv::usingIpv6
bool usingIpv6
Definition: Aodv.h:72
inet::aodv::Aodv::helloInterval
simtime_t helloInterval
Definition: Aodv.h:82
inet::OperationalMixin< cSimpleModule >::operationalState
State operationalState
Definition: OperationalMixin.h:23
inet::aodv::Aodv::handleLinkBreakSendRERR
void handleLinkBreakSendRERR(const L3Address &unreachableAddr)
Definition: Aodv.cc:1041
inet::UdpSocket::bind
void bind(int localPort)
Bind the socket to a local port number.
Definition: UdpSocket.cc:34
inet::aodv::RERR
@ RERR
Definition: AodvControlPackets_m.h:77
inet::aodv::Aodv::sendHelloMessagesIfNeeded
void sendHelloMessagesIfNeeded()
Definition: Aodv.cc:1368
inet::IL3AddressType::getMaxPrefixLength
virtual int getMaxPrefixLength() const =0
inet::aodv::Aodv::handleRERR
void handleRERR(const Ptr< const Rerr > &rerr, const L3Address &sourceAddr)
Definition: Aodv.cc:1148
inet::aodv::Aodv::nodeTraversalTime
simtime_t nodeTraversalTime
Definition: Aodv.h:92
inet::aodv::Aodv::completeRouteDiscovery
void completeRouteDiscovery(const L3Address &target)
Definition: Aodv.cc:1307
inet::aodv::Aodv::createRoute
IRoute * createRoute(const L3Address &destAddr, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: Aodv.cc:976
inet::linkBrokenSignal
simsignal_t linkBrokenSignal
Definition: Simsignals.cc:22
inet::aodv::Aodv::forwardRREP
void forwardRREP(const Ptr< Rrep > &rrep, const L3Address &destAddr, unsigned int timeToLive)
Definition: Aodv.cc:1290
inet::aodv::Aodv::interfaceTable
ModuleRefByPar< IInterfaceTable > interfaceTable
Definition: Aodv.h:69
inet::aodv::Aodv::sendRREP
void sendRREP(const Ptr< Rrep > &rrep, const L3Address &destAddr, unsigned int timeToLive)
Definition: Aodv.cc:342
inet::aodv::KIND_DELAYEDSEND
const int KIND_DELAYEDSEND
Definition: Aodv.cc:31
inet::aodv::Aodv::waitForRREPTimers
std::map< L3Address, WaitForRrep * > waitForRREPTimers
Definition: Aodv.h:108
inet::aodv::Aodv::addressToRreqRetries
std::map< L3Address, unsigned int > addressToRreqRetries
Definition: Aodv.h:115
L4PortReq
removed L4PortReq
Definition: IUdp-gates.txt:11
inet::aodv::Aodv::handleHelloMessage
void handleHelloMessage(const Ptr< Rrep > &helloMessage)
Definition: Aodv.cc:1400
inet::aodv::Aodv::myRouteTimeout
simtime_t myRouteTimeout
Definition: Aodv.h:99
inet::aodv::Aodv::nextHopWait
simtime_t nextHopWait
Definition: Aodv.h:102
inet::aodv::Aodv::host
cModule * host
Definition: Aodv.h:67
inet::aodv::Aodv::clearState
void clearState()
Definition: Aodv.cc:1240
inet::getContainingNode
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
inet::OperationalMixin< cSimpleModule >::initialize
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
inet::aodv::Aodv::netTraversalTime
simtime_t netTraversalTime
Definition: Aodv.h:101
inet::aodv::Aodv::periodicJitter
cPar * periodicJitter
Definition: Aodv.h:94
InterfaceReq
removed InterfaceReq
Definition: IUdp-gates.txt:11
inet::UdpSocket::destroy
virtual void destroy() override
Notify the protocol that the owner of ISocket has destroyed the socket.
Definition: UdpSocket.cc:98
inet::aodv::Aodv::sendRREQ
void sendRREQ(const Ptr< Rreq > &rreq, const L3Address &destAddr, unsigned int timeToLive)
Definition: Aodv.cc:271
inet::aodv::Aodv::rerrRatelimit
unsigned int rerrRatelimit
Definition: Aodv.h:75
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::aodv::Aodv::aodvUDPPort
unsigned int aodvUDPPort
Definition: Aodv.h:76
inet::aodv::Aodv::updateRoutingTable
void updateRoutingTable(IRoute *route, const L3Address &nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
Definition: Aodv.cc:709
inet::aodv::Aodv::forwardRREQ
void forwardRREQ(const Ptr< Rreq > &rreq, unsigned int timeToLive)
Definition: Aodv.cc:1301
inet::aodv::RREQ
@ RREQ
Definition: AodvControlPackets_m.h:75
inet::IL3AddressType::getBroadcastAddress
virtual L3Address getBroadcastAddress() const =0
inet::aodv::Aodv::ttlStart
unsigned int ttlStart
Definition: Aodv.h:87
inet::aodv::Aodv::createRREPACK
const Ptr< RrepAck > createRREPACK()
Definition: Aodv.cc:1633
inet::aodv::Aodv::sendAODVPacket
void sendAODVPacket(const Ptr< AodvControlPacket > &packet, const L3Address &destAddr, unsigned int timeToLive, double delay)
Definition: Aodv.cc:729
inet::aodv::Aodv::processPacket
void processPacket(Packet *pk)
Definition: Aodv.cc:143
inet::aodv::Aodv::blacklist
std::map< L3Address, simtime_t > blacklist
Definition: Aodv.h:111
inet::aodv::RREP_IPv6
@ RREP_IPv6
Definition: AodvControlPackets_m.h:80
inet::UdpSocket::setCallback
void setCallback(ICallback *cb)
Sets a callback object, to be used with processMessage().
Definition: UdpSocket.cc:338
inet::aodv::Aodv::createRREP
const Ptr< Rrep > createRREP(const Ptr< Rreq > &rreq, IRoute *destRoute, IRoute *originatorRoute, const L3Address &sourceAddr)
Definition: Aodv.cc:432
inet::aodv::Aodv::ensureRouteForDatagram
Result ensureRouteForDatagram(Packet *datagram)
Definition: Aodv.cc:186
inet::aodv::Aodv::handleWaitForRREP
void handleWaitForRREP(WaitForRrep *rrepTimer)
Definition: Aodv.cc:1268
inet::aodv::Aodv::counterTimer
cMessage * counterTimer
Definition: Aodv.h:120
inet::aodv::Aodv::activeRouteTimeout
simtime_t activeRouteTimeout
Definition: Aodv.h:81
inet::aodv::Aodv::handleRREPACKTimer
void handleRREPACKTimer()
Definition: Aodv.cc:1665
inet::aodv::Aodv::expungeRoutes
void expungeRoutes()
Definition: Aodv.cc:1438
inet::aodv::Aodv::useHelloMessages
bool useHelloMessages
Definition: Aodv.h:78
inet::aodv::RREQ_IPv6
@ RREQ_IPv6
Definition: AodvControlPackets_m.h:79
inet::findNetworkProtocolHeader
const Ptr< const NetworkHeaderBase > findNetworkProtocolHeader(Packet *packet)
Definition: L3Tools.cc:37
inet::aodv::Aodv::cancelRouteDiscovery
void cancelRouteDiscovery(const L3Address &destAddr)
Definition: Aodv.cc:1602
inet::UdpSocket::send
virtual void send(Packet *msg) override
Sends a data packet to the address and port specified previously in a connect() call.
Definition: UdpSocket.cc:80
inet::aodv::Aodv::hasOngoingRouteDiscovery
bool hasOngoingRouteDiscovery(const L3Address &destAddr)
Definition: Aodv.cc:244
inet::aodv::Aodv::netDiameter
unsigned int netDiameter
Definition: Aodv.h:83
inet::aodv::Aodv::sendGRREP
void sendGRREP(const Ptr< Rrep > &grrep, const L3Address &destAddr, unsigned int timeToLive)
Definition: Aodv.cc:1333
inet::aodv::Aodv::scheduleExpungeRoutes
void scheduleExpungeRoutes()
Definition: Aodv.cc:1473
inet::aodv::Aodv::lastBroadcastTime
simtime_t lastBroadcastTime
Definition: Aodv.h:114
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::getNetworkProtocolHeader
const Ptr< const NetworkHeaderBase > getNetworkProtocolHeader(Packet *packet)
Definition: L3Tools.cc:43
inet::aodv::Aodv::localAddTTL
unsigned int localAddTTL
Definition: Aodv.h:90
inet::aodv::Aodv::pathDiscoveryTime
simtime_t pathDiscoveryTime
Definition: Aodv.h:103
inet::aodv::Aodv::failedNextHop
L3Address failedNextHop
Definition: Aodv.h:110
inet::aodv::Aodv::targetAddressToDelayedPackets
std::multimap< L3Address, Packet * > targetAddressToDelayedPackets
Definition: Aodv.h:128
inet::aodv::Aodv::rrepAckTimer
cMessage * rrepAckTimer
Definition: Aodv.h:121
inet::INetfilter::IHook::QUEUE
@ QUEUE
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:42
inet::aodv::Aodv::socket
UdpSocket socket
Definition: Aodv.h:71
inet::aodv::RREP
@ RREP
Definition: AodvControlPackets_m.h:76
inet::aodv::Aodv::jitterPar
cPar * jitterPar
Definition: Aodv.h:93
inet::UdpSocket::processMessage
virtual void processMessage(cMessage *msg) override
Examines the message, takes ownership, and updates socket state.
Definition: UdpSocket.cc:343
HopLimitReq
removed HopLimitReq
Definition: IUdp-gates.txt:11
inet::aodv::Aodv::deletePeriod
simtime_t deletePeriod
Definition: Aodv.h:98
inet::aodv::Aodv::createGratuitousRREP
const Ptr< Rrep > createGratuitousRREP(const Ptr< Rreq > &rreq, IRoute *originatorRoute)
Definition: Aodv.cc:515
inet::aodv::Aodv::rebootTime
simtime_t rebootTime
Definition: Aodv.h:125
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::aodv::Aodv::sequenceNum
unsigned int sequenceNum
Definition: Aodv.h:107
inet::aodv::Aodv::timeoutBuffer
unsigned int timeoutBuffer
Definition: Aodv.h:86
inet::UdpSocket::close
virtual void close() override
Unbinds the socket.
Definition: UdpSocket.cc:87
inet::aodv::Aodv::ttlIncrement
unsigned int ttlIncrement
Definition: Aodv.h:88
inet::aodv::RERR_IPv6
@ RERR_IPv6
Definition: AodvControlPackets_m.h:81
inet::aodv::Aodv::rreqRetries
unsigned int rreqRetries
Definition: Aodv.h:84
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::sctp::max
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SctpAssociation.h:266
inet::UdpSocket::setBroadcast
void setBroadcast(bool broadcast)
Set the Broadcast option on the UDP socket.
Definition: UdpSocket.cc:139
inet::aodv::RREPACK_IPv6
@ RREPACK_IPv6
Definition: AodvControlPackets_m.h:82
inet::aodv::Aodv::destinationOnlyFlag
bool destinationOnlyFlag
Definition: Aodv.h:79
inet::L3Address::IPv6
@ IPv6
Definition: L3Address.h:36
inet::aodv::Aodv::updateValidRouteLifeTime
bool updateValidRouteLifeTime(const L3Address &destAddr, simtime_t lifetime)
Definition: Aodv.cc:1618
inet::aodv::Aodv::rreqsArrivalTime
std::map< RreqIdentifier, simtime_t, RreqIdentifierCompare > rreqsArrivalTime
Definition: Aodv.h:109
inet::aodv::Aodv::handleRREQ
void handleRREQ(const Ptr< Rreq > &rreq, const L3Address &sourceAddr, unsigned int timeToLive)
Definition: Aodv.cc:773
inet::aodv::Aodv::blacklistTimeout
simtime_t blacklistTimeout
Definition: Aodv.h:100
inet::aodv::Aodv::createRREQ
const Ptr< Rreq > createRREQ(const L3Address &destAddr)
Definition: Aodv.cc:374
inet::OperationalMixin< cSimpleModule >::startActiveOperationExtraTimeOrFinish
virtual void startActiveOperationExtraTimeOrFinish(simtime_t extraTime)
Definition: OperationalMixinImpl.h:179
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::aodv::Aodv::rreqId
unsigned int rreqId
Definition: Aodv.h:106
inet::aodv::Aodv::addressType
IL3AddressType * addressType
Definition: Aodv.h:64
inet::aodv::Aodv::sendRREPACK
void sendRREPACK(const Ptr< RrepAck > &rrepACK, const L3Address &destAddr)
Definition: Aodv.cc:1640
inet::aodv::Aodv::handleRREP
void handleRREP(const Ptr< Rrep > &rrep, const L3Address &sourceAddr)
Definition: Aodv.cc:549
inet::aodv::Aodv::getSelfIPAddress
L3Address getSelfIPAddress() const
Definition: Aodv.cc:258
inet::INetfilter::IHook::ACCEPT
@ ACCEPT
allows the datagram to pass to the next hook
Definition: INetfilter.h:40
inet::aodv::Aodv::rerrCount
unsigned int rerrCount
Definition: Aodv.h:112
inet::L3Address::getAddressType
IL3AddressType * getAddressType() const
Definition: L3Address.cc:59
inet::aodv::Aodv::helloMsgTimer
cMessage * helloMsgTimer
Definition: Aodv.h:118
inet::aodv::Aodv::rreqCount
unsigned int rreqCount
Definition: Aodv.h:113
inet::aodv::Aodv::askGratuitousRREP
bool askGratuitousRREP
Definition: Aodv.h:77
inet::aodv::Aodv::handleBlackListTimer
void handleBlackListTimer()
Definition: Aodv.cc:1678
inet::aodv::Aodv::networkProtocol
ModuleRefByPar< INetfilter > networkProtocol
Definition: Aodv.h:70
inet::aodv::RREPACK
@ RREPACK
Definition: AodvControlPackets_m.h:78
inet::aodv::Aodv::routingTable
ModuleRefByPar< IRoutingTable > routingTable
Definition: Aodv.h:68
inet::aodv::Aodv::handleRREPACK
void handleRREPACK(const Ptr< const RrepAck > &rrepACK, const L3Address &neighborAddr)
Definition: Aodv.cc:1646
inet::aodv::Aodv::checkIpVersionAndPacketTypeCompatibility
void checkIpVersionAndPacketTypeCompatibility(AodvControlPacketType packetType)
Definition: Aodv.cc:119
inet::aodv::Aodv::allowedHelloLoss
unsigned int allowedHelloLoss
Definition: Aodv.h:91
inet::aodv::Aodv::delayDatagram
void delayDatagram(Packet *datagram)
Definition: Aodv.cc:263
inet::aodv::Aodv::rreqRatelimit
unsigned int rreqRatelimit
Definition: Aodv.h:85
inet::aodv::Aodv::blacklistTimer
cMessage * blacklistTimer
Definition: Aodv.h:122
inet::containsKey
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80
inet::INITSTAGE_ROUTING_PROTOCOLS
INET_API InitStage INITSTAGE_ROUTING_PROTOCOLS
Initialization of routing protocols.
inet::aodv::Aodv::ttlThreshold
unsigned int ttlThreshold
Definition: Aodv.h:89
inet::aodv::Aodv::startRouteDiscovery
void startRouteDiscovery(const L3Address &target, unsigned int timeToLive=0)
Definition: Aodv.cc:249
inet::aodv::Aodv::sendRERRWhenNoRouteToForward
void sendRERRWhenNoRouteToForward(const L3Address &unreachableAddr)
Definition: Aodv.cc:1576