INET Framework for OMNeT++/OMNEST
inet::dymo::DYMO Class Reference

This class provides Dynamic MANET On-demand (DYMO also known as AODVv2) Routing based on the IETF draft at http://tools.ietf.org/html/draft-ietf-manet-dymo-24. More...

#include <DYMO.h>

Inheritance diagram for inet::dymo::DYMO:
inet::ILifecycle inet::INetfilter::IHook

Public Member Functions

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

Protected Member Functions

virtual int numInitStages () const override
 
void initialize (int stage) override
 
void handleMessage (cMessage *message) override
 

Private Member Functions

void processSelfMessage (cMessage *message)
 
void processMessage (cMessage *message)
 
void startRouteDiscovery (const L3Address &target)
 
void retryRouteDiscovery (const L3Address &target, int retryCount)
 
void completeRouteDiscovery (const L3Address &target)
 
void cancelRouteDiscovery (const L3Address &target)
 
bool hasOngoingRouteDiscovery (const L3Address &target)
 
void delayDatagram (INetworkDatagram *datagram)
 
void reinjectDelayedDatagram (INetworkDatagram *datagram)
 
void dropDelayedDatagram (INetworkDatagram *datagram)
 
void eraseDelayedDatagrams (const L3Address &target)
 
bool hasDelayedDatagrams (const L3Address &target)
 
void cancelRREQTimer (const L3Address &target)
 
void deleteRREQTimer (const L3Address &target)
 
void eraseRREQTimer (const L3Address &target)
 
RREQWaitRREPTimercreateRREQWaitRREPTimer (const L3Address &target, int retryCount)
 
void scheduleRREQWaitRREPTimer (RREQWaitRREPTimer *message)
 
void processRREQWaitRREPTimer (RREQWaitRREPTimer *message)
 
RREQBackoffTimercreateRREQBackoffTimer (const L3Address &target, int retryCount)
 
void scheduleRREQBackoffTimer (RREQBackoffTimer *message)
 
void processRREQBackoffTimer (RREQBackoffTimer *message)
 
simtime_t computeRREQBackoffTime (int retryCount)
 
RREQHolddownTimercreateRREQHolddownTimer (const L3Address &target)
 
void scheduleRREQHolddownTimer (RREQHolddownTimer *message)
 
void processRREQHolddownTimer (RREQHolddownTimer *message)
 
void sendUDPPacket (UDPPacket *packet, double delay)
 
void processUDPPacket (UDPPacket *packet)
 
void sendDYMOPacket (DYMOPacket *packet, const InterfaceEntry *interfaceEntry, const L3Address &nextHop, double delay)
 
void processDYMOPacket (DYMOPacket *packet)
 
bool permissibleRteMsg (RteMsg *rteMsg)
 
void processRteMsg (RteMsg *rteMsg)
 
int computeRteMsgBitLength (RteMsg *rteMsg)
 
RREQcreateRREQ (const L3Address &target, int retryCount)
 
void sendRREQ (RREQ *rreq)
 
void processRREQ (RREQ *rreq)
 
int computeRREQBitLength (RREQ *rreq)
 
RREPcreateRREP (RteMsg *rteMsg)
 
RREPcreateRREP (RteMsg *rteMsg, IRoute *route)
 
void sendRREP (RREP *rrep)
 
void sendRREP (RREP *rrep, IRoute *route)
 
void processRREP (RREP *rrep)
 
int computeRREPBitLength (RREP *rrep)
 
RERRcreateRERR (std::vector< L3Address > &addresses)
 
void sendRERR (RERR *rerr)
 
void sendRERRForUndeliverablePacket (const L3Address &destination)
 
void sendRERRForBrokenLink (const InterfaceEntry *interfaceEntry, const L3Address &nextHop)
 
void processRERR (RERR *rerr)
 
int computeRERRBitLength (RERR *rerr)
 
IRoutecreateRoute (RteMsg *rteMsg, AddressBlock &addressBlock)
 
void updateRoutes (RteMsg *rteMsg, AddressBlock &addressBlock)
 
void updateRoute (RteMsg *rteMsg, AddressBlock &addressBlock, IRoute *route)
 
int getLinkCost (const InterfaceEntry *interfaceEntry, DYMOMetricType metricType)
 
bool isLoopFree (RteMsg *rteMsg, IRoute *route)
 
void processExpungeTimer ()
 
void scheduleExpungeTimer ()
 
void expungeRoutes ()
 
simtime_t getNextExpungeTime ()
 
DYMORouteState getRouteState (DYMORouteData *routeData)
 
bool isNodeUp ()
 
void configureInterfaces ()
 
L3Address getSelfAddress ()
 
bool isClientAddress (const L3Address &address)
 
void addSelfNode (RteMsg *rteMsg)
 
void addNode (RteMsg *rteMsg, AddressBlock &addressBlock)
 
void incrementSequenceNumber ()
 
Result ensureRouteForDatagram (INetworkDatagram *datagram)
 
virtual Result datagramPreRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the first hook called by the network protocol before it routes a datagram that was received from the lower layer. More...
 
virtual Result datagramForwardHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the second hook called by the network protocol before it sends a datagram to the lower layer. More...
 
virtual Result datagramPostRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the last hook called by the network protocol before it sends a datagram to the lower layer. More...
 
virtual Result datagramLocalInHook (INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry) override
 This is the last hook called by the network protocol before it sends a datagram to the upper layer. More...
 
virtual Result datagramLocalOutHook (INetworkDatagram *datagram, const InterfaceEntry *&outputInterfaceEntry, L3Address &nextHopAddress) override
 This is the first hook called by the network protocol before it routes a datagram that was received from the upper layer. More...
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 

Private Attributes

const char * clientAddresses
 
bool useMulticastRREP
 
const char * interfaces
 
double activeInterval
 
double maxIdleTime
 
double maxSequenceNumberLifetime
 
double routeRREQWaitTime
 
double rreqHolddownTime
 
int maxHopCount
 
int discoveryAttemptsMax
 
bool appendInformation
 
int bufferSizePackets
 
int bufferSizeBytes
 
simtime_t maxJitter
 
bool sendIntermediateRREP
 
int minHopLimit
 
int maxHopLimit
 
cModule * host
 
NodeStatusnodeStatus
 
IL3AddressTypeaddressType
 
IInterfaceTableinterfaceTable
 
IRoutingTableroutingTable
 
INetfilternetworkProtocol
 
cMessage * expungeTimer
 
DYMOSequenceNumber sequenceNumber
 
std::map< L3Address, DYMOSequenceNumbertargetAddressToSequenceNumber
 
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
 
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
 
std::vector< std::pair< L3Address, int > > clientAddressAndPrefixLengthPairs
 

Additional Inherited Members

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

Detailed Description

This class provides Dynamic MANET On-demand (DYMO also known as AODVv2) Routing based on the IETF draft at http://tools.ietf.org/html/draft-ietf-manet-dymo-24.

Optional features implemented:

  • 7.1. Route Discovery Retries and Buffering To reduce congestion in a network, repeated attempts at route discovery for a particular Target Node SHOULD utilize a binary exponential backoff.
  • 13.1. Expanding Rings Multicast Increase hop limit from min to max with each retry.
  • 13.2. Intermediate RREP Allow intermediate DYMO routers to reply with RREP.
  • 13.6. Message Aggregation RFC5148 add jitter to broadcasts

Constructor & Destructor Documentation

inet::dymo::DYMO::DYMO ( )
50  :
51  clientAddresses(nullptr),
52  useMulticastRREP(false),
53  interfaces(nullptr),
59  maxHopCount(-1),
61  appendInformation(false),
63  bufferSizeBytes(-1),
64  maxJitter(NaN),
65  sendIntermediateRREP(false),
66  minHopLimit(-1),
67  maxHopLimit(-1),
68  host(nullptr),
69  nodeStatus(nullptr),
70  addressType(nullptr),
71  interfaceTable(nullptr),
72  routingTable(nullptr),
73  networkProtocol(nullptr),
74  expungeTimer(nullptr),
76 {
77 }
cMessage * expungeTimer
Definition: DYMO.h:89
double routeRREQWaitTime
Definition: DYMO.h:66
int maxHopCount
Definition: DYMO.h:68
int bufferSizeBytes
Definition: DYMO.h:72
const char * clientAddresses
Definition: DYMO.h:60
IRoutingTable * routingTable
Definition: DYMO.h:85
double maxIdleTime
Definition: DYMO.h:64
INetfilter * networkProtocol
Definition: DYMO.h:86
double maxSequenceNumberLifetime
Definition: DYMO.h:65
IL3AddressType * addressType
Definition: DYMO.h:83
simtime_t maxJitter
Definition: DYMO.h:75
double rreqHolddownTime
Definition: DYMO.h:67
#define NaN
Definition: INETMath.h:103
int maxHopLimit
Definition: DYMO.h:78
bool appendInformation
Definition: DYMO.h:70
const char * interfaces
Definition: DYMO.h:62
bool useMulticastRREP
Definition: DYMO.h:61
cModule * host
Definition: DYMO.h:81
DYMOSequenceNumber sequenceNumber
Definition: DYMO.h:90
int bufferSizePackets
Definition: DYMO.h:71
int minHopLimit
Definition: DYMO.h:77
NodeStatus * nodeStatus
Definition: DYMO.h:82
IInterfaceTable * interfaceTable
Definition: DYMO.h:84
double activeInterval
Definition: DYMO.h:63
bool sendIntermediateRREP
Definition: DYMO.h:76
int discoveryAttemptsMax
Definition: DYMO.h:69
inet::dymo::DYMO::~DYMO ( )
virtual
80 {
81  for (auto & elem : targetAddressToRREQTimer)
82  cancelAndDelete(elem.second);
83  cancelAndDelete(expungeTimer);
84 }
cMessage * expungeTimer
Definition: DYMO.h:89
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92

Member Function Documentation

void inet::dymo::DYMO::addNode ( RteMsg rteMsg,
AddressBlock addressBlock 
)
private

Referenced by addSelfNode().

1352 {
1353  int size = rteMsg->getAddedNodeArraySize();
1354  rteMsg->setAddedNodeArraySize(size + 1);
1355  rteMsg->setAddedNode(size, addressBlock);
1356 }
void inet::dymo::DYMO::addSelfNode ( RteMsg rteMsg)
private

Referenced by processRREP(), and processRREQ().

1335 {
1336  const L3Address& address = getSelfAddress();
1337  AddressBlock addressBlock;
1338  addressBlock.setAddress(address);
1339  addressBlock.setPrefixLength(addressType->getMaxPrefixLength());
1340  addressBlock.setHasValidityTime(false);
1341  addressBlock.setValidityTime(-1);
1342  addressBlock.setHasMetric(true);
1343  addressBlock.setMetric(0);
1344  addressBlock.setHasMetricType(true);
1345  addressBlock.setMetricType(HOP_COUNT);
1346  addressBlock.setHasSequenceNumber(true);
1347  addressBlock.setSequenceNumber(sequenceNumber);
1348  addNode(rteMsg, addressBlock);
1349 }
void addNode(RteMsg *rteMsg, AddressBlock &addressBlock)
Definition: DYMO.cc:1351
Definition: DYMOdefs.h:34
L3Address getSelfAddress()
Definition: DYMO.cc:1311
IL3AddressType * addressType
Definition: DYMO.h:83
DYMOSequenceNumber sequenceNumber
Definition: DYMO.h:90
virtual int getMaxPrefixLength() const =0
void inet::dymo::DYMO::cancelRouteDiscovery ( const L3Address target)
private

Referenced by handleOperationStage(), and processRREQWaitRREPTimer().

222 {
223  EV_INFO << "Canceling route discovery: originator = " << getSelfAddress() << ", target = " << target << endl;
224  ASSERT(hasOngoingRouteDiscovery(target));
225  auto lt = targetAddressToDelayedPackets.lower_bound(target);
226  auto ut = targetAddressToDelayedPackets.upper_bound(target);
227  for (auto it = lt; it != ut; it++)
228  dropDelayedDatagram(it->second);
229  eraseDelayedDatagrams(target);
230 }
bool hasOngoingRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:232
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void dropDelayedDatagram(INetworkDatagram *datagram)
Definition: DYMO.cc:254
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: DYMO.h:93
void eraseDelayedDatagrams(const L3Address &target)
Definition: DYMO.cc:260
void inet::dymo::DYMO::cancelRREQTimer ( const L3Address target)
private

Referenced by processRREP(), and processRREQWaitRREPTimer().

278 {
279  auto tt = targetAddressToRREQTimer.find(target);
280  cancelEvent(tt->second);
281 }
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::completeRouteDiscovery ( const L3Address target)
private

Referenced by processRREP().

211 {
212  EV_INFO << "Completing route discovery: originator = " << getSelfAddress() << ", target = " << target << endl;
213  ASSERT(hasOngoingRouteDiscovery(target));
214  auto lt = targetAddressToDelayedPackets.lower_bound(target);
215  auto ut = targetAddressToDelayedPackets.upper_bound(target);
216  for (auto it = lt; it != ut; it++)
217  reinjectDelayedDatagram(it->second);
218  eraseDelayedDatagrams(target);
219 }
bool hasOngoingRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:232
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void reinjectDelayedDatagram(INetworkDatagram *datagram)
Definition: DYMO.cc:248
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: DYMO.h:93
void eraseDelayedDatagrams(const L3Address &target)
Definition: DYMO.cc:260
int inet::dymo::DYMO::computeRERRBitLength ( RERR rerr)
private

Referenced by sendRERR().

1019 {
1020  // TODO: validityTime, metric, metricType, TLVs
1021  // 1. <address-block> := <num-addr> <addr-flags> (<head-length><head>?)? (<tail-length><tail>?)? <mid>* <prefix-length>*
1022  int addressBlock = 8 + 8;
1023  // head-length and head are not used
1024  // tail-length and tail are not used
1025  // mid contains the originator and target addresses
1026  addressBlock += rerr->getUnreachableNodeArraySize() * 4 * 8;
1027  // prefix-length is not used (assuming 8 * address-length bits)
1028  // 2. <tlv> := <tlv-type> <tlv-flags> <tlv-type-ext>? (<index-start><index-stop>?)? (<length><value>?)?
1029  int addressTLV = 8 + 8;
1030  // tlv-type-ext is not used
1031  // index-start and index-stop are not used
1032  // length is set to 2 + added node count
1033  addressTLV += 8;
1034  // sequence number values are included
1035  addressTLV += rerr->getUnreachableNodeArraySize() * 2 * 8;
1036  // 3. <tlv-block> := <tlvs-length> <tlv>*
1037  int addressTLVBlock = 16;
1038  // there's exactly one tlv in the block
1039  addressTLVBlock += addressTLV;
1040  // 4. <tlv-block> := <tlvs-length> <tlv>*
1041  int messageTLVBlock = 16;
1042  // there's no TLV in the message TLV block
1043  // 5. <msg-header> := <msg-type> <msg-flags> <msg-addr-length> <msg-size> <msg-orig-addr>? <msg-hop-limit>? <msg-hop-count>? <msg-seq-num>?
1044  int messageHeader = 8 + 4 + 4 + 16;
1045  // msg-orig-addr is not used
1046  // msg-hop-limit is always included in the message header
1047  messageHeader += 8 + 8;
1048  // msg-hop-count is not used
1049  // msg-seq-num is not used
1050  // 6. <message> := <msg-header> <tlv-block> (<addr-block><tlv-block>)*
1051  int message = messageHeader + messageTLVBlock;
1052  // there's exactly one address-block with one tlv-block in the message
1053  message += (addressBlock + addressTLVBlock);
1054  // 7. <pkt-header> := <version> <pkt-flags> <pkt-seq-num>? <tlv-block>?
1055  int packetHeader = 4 + 4;
1056  // pkt-seq-num is not used
1057  // tlv-block is not used
1058  // 8. <packet> := <pkt-header> <message>*
1059  int packet = packetHeader;
1060  // there's exactly one message in the packet
1061  packet += message;
1062  return packet;
1063 }
int inet::dymo::DYMO::computeRREPBitLength ( RREP rrep)
private

Referenced by sendRREP().

826 {
827  return computeRteMsgBitLength(rrep);
828 }
int computeRteMsgBitLength(RteMsg *rteMsg)
Definition: DYMO.cc:544
simtime_t inet::dymo::DYMO::computeRREQBackoffTime ( int  retryCount)
private

Referenced by scheduleRREQBackoffTimer().

356 {
357  return pow(routeRREQWaitTime, retryCount);
358 }
double routeRREQWaitTime
Definition: DYMO.h:66
int inet::dymo::DYMO::computeRREQBitLength ( RREQ rreq)
private

Referenced by sendRREQ().

707 {
708  return computeRteMsgBitLength(rreq);
709 }
int computeRteMsgBitLength(RteMsg *rteMsg)
Definition: DYMO.cc:544
int inet::dymo::DYMO::computeRteMsgBitLength ( RteMsg rteMsg)
private

Referenced by computeRREPBitLength(), and computeRREQBitLength().

545 {
546  // TODO: validityTime, metric, metricType, TLVs
547  // 1. <address-block> := <num-addr> <addr-flags> (<head-length><head>?)? (<tail-length><tail>?)? <mid>* <prefix-length>*
548  int addressBlock = 8 + 8;
549  // head-length and head are not used
550  // tail-length and tail are not used
551  // mid contains the originator and target addresses
552  addressBlock += (2 + rteMsg->getAddedNodeArraySize()) * 4 * 8;
553  // prefix-length is not used (assuming 8 * address-length bits)
554  // 2. <tlv> := <tlv-type> <tlv-flags> <tlv-type-ext>? (<index-start><index-stop>?)? (<length><value>?)?
555  int addressTLV = 8 + 8;
556  // tlv-type-ext is not used
557  // index-start and index-stop are not used
558  // length is set to 2 + added node count
559  addressTLV += 8;
560  // sequence number values are included
561  addressTLV += (2 + rteMsg->getAddedNodeArraySize()) * 2 * 8;
562  // 3. <tlv-block> := <tlvs-length> <tlv>*
563  int addressTLVBlock = 16;
564  // there's exactly one tlv in the block
565  addressTLVBlock += addressTLV;
566  // 4. <tlv-block> := <tlvs-length> <tlv>*
567  int messageTLVBlock = 16;
568  // there's no TLV in the message TLV block
569  // 5. <msg-header> := <msg-type> <msg-flags> <msg-addr-length> <msg-size> <msg-orig-addr>? <msg-hop-limit>? <msg-hop-count>? <msg-seq-num>?
570  int messageHeader = 8 + 4 + 4 + 16;
571  // msg-orig-addr is not used
572  // msg-hop-limit and msg-hop-count are always included in the message header
573  messageHeader += 8 + 8;
574  // msg-seq-num is not used
575  // 6. <message> := <msg-header> <tlv-block> (<addr-block><tlv-block>)*
576  int message = messageHeader + messageTLVBlock;
577  // there's exactly one address-block with one tlv-block in the message
578  message += (addressBlock + addressTLVBlock);
579  // 7. <pkt-header> := <version> <pkt-flags> <pkt-seq-num>? <tlv-block>?
580  int packetHeader = 4 + 4;
581  // pkt-seq-num is not used
582  // tlv-block is not used
583  // 8. <packet> := <pkt-header> <message>*
584  int packet = packetHeader;
585  // there's exactly one message in the packet
586  packet += message;
587  return packet;
588 }
void inet::dymo::DYMO::configureInterfaces ( )
private

Referenced by handleOperationStage(), and initialize().

1294 {
1295  // join multicast groups
1296  cPatternMatcher interfaceMatcher(interfaces, false, true, false);
1297  for (int i = 0; i < interfaceTable->getNumInterfaces(); i++) {
1298  InterfaceEntry *interfaceEntry = interfaceTable->getInterface(i);
1299  if (interfaceEntry->isMulticast() && interfaceMatcher.matches(interfaceEntry->getName()))
1300  // Most AODVv2 messages are sent with the IP destination address set to the link-local
1301  // multicast address LL-MANET-Routers [RFC5498] unless otherwise specified. Therefore,
1302  // all AODVv2 routers MUST subscribe to LL-MANET-Routers [RFC5498] to receiving AODVv2 messages.
1304  }
1305 }
virtual void joinMulticastGroup(const L3Address &address) const
Definition: InterfaceEntry.cc:330
IL3AddressType * addressType
Definition: DYMO.h:83
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
const char * interfaces
Definition: DYMO.h:62
IInterfaceTable * interfaceTable
Definition: DYMO.h:84
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
virtual L3Address getLinkLocalManetRoutersMulticastAddress() const =0
RERR * inet::dymo::DYMO::createRERR ( std::vector< L3Address > &  addresses)
private

Referenced by processRERR(), sendRERRForBrokenLink(), and sendRERRForUndeliverablePacket().

835 {
836  RERR *rerr = new RERR("RERR");
837  for (auto & unreachableAddresse : unreachableAddresses) {
838  const L3Address& unreachableAddress = unreachableAddresse;
839  AddressBlock *addressBlock = new AddressBlock();
840  addressBlock->setAddress(unreachableAddress);
841  addressBlock->setPrefixLength(addressType->getMaxPrefixLength());
842  addressBlock->setHasValidityTime(false);
843  addressBlock->setHasMetric(false);
844  addressBlock->setHasMetricType(false);
845  auto st = targetAddressToSequenceNumber.find(unreachableAddress);
846  if (st != targetAddressToSequenceNumber.end()) {
847  addressBlock->setHasSequenceNumber(true);
848  addressBlock->setSequenceNumber(st->second);
849  }
850  else
851  addressBlock->setHasSequenceNumber(false);
852  int size = rerr->getUnreachableNodeArraySize();
853  rerr->setUnreachableNodeArraySize(size + 1);
854  rerr->setUnreachableNode(size, *addressBlock);
855  }
856  rerr->setHopLimit(maxHopLimit);
857  return rerr;
858 }
std::map< L3Address, DYMOSequenceNumber > targetAddressToSequenceNumber
Definition: DYMO.h:91
IL3AddressType * addressType
Definition: DYMO.h:83
int maxHopLimit
Definition: DYMO.h:78
Definition: AODVControlPackets_m.h:70
virtual int getMaxPrefixLength() const =0
IRoute * inet::dymo::DYMO::createRoute ( RteMsg rteMsg,
AddressBlock addressBlock 
)
private

Referenced by updateRoutes().

1123 {
1124  IRoute *route = routingTable->createRoute();
1125  route->setSourceType(IRoute::DYMO);
1126  route->setSource(this);
1127  route->setProtocolData(new DYMORouteData());
1128  updateRoute(rteMsg, addressBlock, route);
1129  return route;
1130 }
virtual void setSourceType(SourceType type)=0
IRoutingTable * routingTable
Definition: DYMO.h:85
void updateRoute(RteMsg *rteMsg, AddressBlock &addressBlock, IRoute *route)
Definition: DYMO.cc:1132
virtual IRoute * createRoute()=0
managed by DYMO routing
Definition: IRoute.h:51
RREP * inet::dymo::DYMO::createRREP ( RteMsg rteMsg)
private

Referenced by processRREQ().

716 {
717  return createRREP(rteMsg, nullptr);
718 }
RREP * createRREP(RteMsg *rteMsg)
Definition: DYMO.cc:715
RREP * inet::dymo::DYMO::createRREP ( RteMsg rteMsg,
IRoute route 
)
private
721 {
722  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
723  RREP *rrep = new RREP("RREP");
724  AddressBlock& originatorNode = rrep->getOriginatorNode();
725  AddressBlock& targetNode = rrep->getTargetNode();
726  // 1. RREP_Gen first uses the routing information to update its route
727  // table entry for OrigNode if necessary as specified in Section 6.2.
728  // NOTE: this is already done
729  // 2. RREP_Gen MUST increment its OwnSeqNum by one (1) according to
730  // the rules specified in Section 5.5.
732  // 3. RREP.AddrBlk[OrigNode] := RREQ.AddrBlk[OrigNode]
733  originatorNode = AddressBlock(rteMsg->getOriginatorNode());
734  // 4. RREP.AddrBlk[TargNode] := RREQ.AddrBlk[TargNode]
735  targetNode = AddressBlock(rteMsg->getTargetNode());
736  // 5. RREP.SeqNumTLV[OrigNode] := RREQ.SeqNumTLV[OrigNode]
737  originatorNode.setHasSequenceNumber(true);
738  originatorNode.setSequenceNumber(rteMsg->getOriginatorNode().getSequenceNumber());
739  // 6. RREP.SeqNumTLV[TargNode] := OwnSeqNum
740  targetNode.setHasSequenceNumber(true);
741  targetNode.setSequenceNumber(sequenceNumber);
742  // 7. If Route[TargNode].PfxLen/8 is equal to the number of bytes in
743  // the addresses of the RREQ (4 for IPv4, 16 for IPv6), then no
744  // <prefix-length> is included with the iRREP. Otherwise,
745  // RREP.PfxLen[TargNode] := RREQ.PfxLen[TargNode] according to the
746  // rules of RFC 5444 AddrBlk encoding.
747  // TODO: implement
748  // 8. RREP.MetricType[TargNode] := Route[TargNode].MetricType
749  targetNode.setHasMetricType(true);
750  targetNode.setMetricType(routeData->getMetricType());
751  // 9. RREP.Metric[TargNode] := Route[TargNode].Metric
752  targetNode.setHasMetric(true);
753  targetNode.setMetric(route->getMetric());
754  // 10. <msg-hop-limit> SHOULD be set to RteMsg.<msg-hop-count>.
755  rrep->setHopLimit(rteMsg->getHopCount());
756  // 11. IP.DestinationAddr := Route[OrigNode].NextHop
757  // NOTE: can't be done here, it is done later
758  return rrep;
759 }
Definition: AODVControlPackets_m.h:69
DYMOSequenceNumber sequenceNumber
Definition: DYMO.h:90
void incrementSequenceNumber()
Definition: DYMO.cc:1362
RREQ * inet::dymo::DYMO::createRREQ ( const L3Address target,
int  retryCount 
)
private

Referenced by retryRouteDiscovery(), and startRouteDiscovery().

595 {
596  RREQ *rreq = new RREQ("RREQ");
597  AddressBlock& originatorNode = rreq->getOriginatorNode();
598  AddressBlock& targetNode = rreq->getTargetNode();
599  // 7.3. RREQ Generation
600  // 1. RREQ_Gen MUST increment its OwnSeqNum by one (1) according to the
601  // rules specified in Section 5.5.
603  // 2. OrigNode MUST be a unicast address. If RREQ_Gen is not OrigNode,
604  // then OwnSeqNum will be used as the value of OrigNode.SeqNum. will
605  // be used by AODVv2 routers to create a route toward the OrigNode,
606  // enabling a RREP from TargRtr, and eventually used for proper
607  // forwarding of data packets.
608  // 3. If RREQ_Gen requires that only TargRtr is allowed to generate a
609  // RREP, then RREQ_Gen includes the "Destination RREP Only" TLV as
610  // part of the RFC 5444 message header. This also assures that
611  // TargRtr increments its sequence number. Otherwise, intermediate
612  // AODVv2 routers MAY respond to the RREQ_Gen's RREQ if they have an
613  // valid route to TargNode (see Section 13.2).
614  // 4. msg-hopcount MUST be set to 0.
615  rreq->setHopCount(0);
616  // * This RFC 5444 constraint causes the typical RteMsg payload
617  // incur additional enlargement.
618  // 5. RREQ_Gen adds the TargNode.Addr to the RREQ.
619  targetNode.setAddress(target);
620  targetNode.setPrefixLength(addressType->getMaxPrefixLength());
621  // 6. If a previous value of the TargNode's SeqNum is known RREQ_Gen SHOULD
622  // include TargNode.SeqNum in all but the last RREQ attempt.
623  auto st = targetAddressToSequenceNumber.find(target);
624  if (st != targetAddressToSequenceNumber.end() && retryCount < discoveryAttemptsMax - 1) {
625  targetNode.setHasSequenceNumber(true);
626  targetNode.setSequenceNumber(st->second);
627  }
628  else
629  targetNode.setHasSequenceNumber(false);
630  // 7. RREQ_Gen adds OrigNode.Addr, its prefix, and the RREQ_Gen.SeqNum (OwnSeqNum) to the RREQ.
631  const L3Address& originator = getSelfAddress();
632  originatorNode.setAddress(originator);
633  originatorNode.setPrefixLength(addressType->getMaxPrefixLength());
634  originatorNode.setHasSequenceNumber(true);
635  originatorNode.setSequenceNumber(sequenceNumber);
636  // 8. If OrigNode.Metric is included it is set to the cost of the route
637  // between OrigNode and RREQ_Gen.
638  originatorNode.setHasMetric(true);
639  originatorNode.setMetric(0);
640  originatorNode.setHasMetricType(true);
641  originatorNode.setMetricType(HOP_COUNT);
642  targetNode.setHasMetricType(true);
643  targetNode.setMetricType(HOP_COUNT);
644  // 13.1. Expanding Rings Multicast
645  int hopLimit = minHopLimit + (maxHopLimit - minHopLimit) * retryCount / discoveryAttemptsMax;
646  rreq->setHopLimit(hopLimit);
647  return rreq;
648 }
Definition: DYMOdefs.h:34
std::map< L3Address, DYMOSequenceNumber > targetAddressToSequenceNumber
Definition: DYMO.h:91
L3Address getSelfAddress()
Definition: DYMO.cc:1311
IL3AddressType * addressType
Definition: DYMO.h:83
int maxHopLimit
Definition: DYMO.h:78
DYMOSequenceNumber sequenceNumber
Definition: DYMO.h:90
Definition: AODVControlPackets_m.h:68
int minHopLimit
Definition: DYMO.h:77
void incrementSequenceNumber()
Definition: DYMO.cc:1362
int discoveryAttemptsMax
Definition: DYMO.h:69
virtual int getMaxPrefixLength() const =0
RREQBackoffTimer * inet::dymo::DYMO::createRREQBackoffTimer ( const L3Address target,
int  retryCount 
)
private

Referenced by processRREQWaitRREPTimer().

334 {
335  RREQBackoffTimer *message = new RREQBackoffTimer("RREQBackoffTimer");
336  message->setRetryCount(retryCount);
337  message->setTarget(target);
338  return message;
339 }
RREQHolddownTimer * inet::dymo::DYMO::createRREQHolddownTimer ( const L3Address target)
private

Referenced by processRREQWaitRREPTimer().

365 {
366  RREQHolddownTimer *message = new RREQHolddownTimer("RREQHolddownTimer");
367  message->setTarget(target);
368  return message;
369 }
RREQWaitRREPTimer * inet::dymo::DYMO::createRREQWaitRREPTimer ( const L3Address target,
int  retryCount 
)
private

Referenced by retryRouteDiscovery(), and startRouteDiscovery().

300 {
301  RREQWaitRREPTimer *message = new RREQWaitRREPTimer("RREQWaitRREPTimer");
302  message->setRetryCount(retryCount);
303  message->setTarget(target);
304  return message;
305 }
virtual Result inet::dymo::DYMO::datagramForwardHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
inlineoverrideprivatevirtual

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.

215 { return ACCEPT; }
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
virtual Result inet::dymo::DYMO::datagramLocalInHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry 
)
inlineoverrideprivatevirtual

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.

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

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

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

Implements inet::INetfilter::IHook.

218 { Enter_Method("datagramLocalOutHook"); return ensureRouteForDatagram(datagram); }
Result ensureRouteForDatagram(INetworkDatagram *datagram)
Definition: DYMO.cc:1378
virtual Result inet::dymo::DYMO::datagramPostRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inputInterfaceEntry,
const InterfaceEntry *&  outputInterfaceEntry,
L3Address nextHopAddress 
)
inlineoverrideprivatevirtual

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

Implements inet::INetfilter::IHook.

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

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

The nextHopAddress is ignored when the outputInterfaceEntry is nullptr.

Implements inet::INetfilter::IHook.

214 { Enter_Method("datagramPreRoutingHook"); return ensureRouteForDatagram(datagram); }
Result ensureRouteForDatagram(INetworkDatagram *datagram)
Definition: DYMO.cc:1378
void inet::dymo::DYMO::delayDatagram ( INetworkDatagram datagram)
private

Referenced by ensureRouteForDatagram().

242 {
243  EV_INFO << "Queuing datagram: source = " << datagram->getSourceAddress() << ", destination = " << datagram->getDestinationAddress() << endl;
244  const L3Address& target = datagram->getDestinationAddress();
245  targetAddressToDelayedPackets.insert(std::pair<L3Address, INetworkDatagram *>(target, datagram));
246 }
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: DYMO.h:93
void inet::dymo::DYMO::deleteRREQTimer ( const L3Address target)
private

Referenced by processRREP().

284 {
285  auto tt = targetAddressToRREQTimer.find(target);
286  delete tt->second;
287 }
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::dropDelayedDatagram ( INetworkDatagram datagram)
private

Referenced by cancelRouteDiscovery().

255 {
256  EV_WARN << "Dropping queued datagram: source = " << datagram->getSourceAddress() << ", destination = " << datagram->getDestinationAddress() << endl;
257  networkProtocol->dropQueuedDatagram(const_cast<const INetworkDatagram *>(datagram));
258 }
INetfilter * networkProtocol
Definition: DYMO.h:86
virtual void dropQueuedDatagram(const INetworkDatagram *daragram)=0
Requests the network layer to drop the datagram, because it&#39;s no longer needed.
INetfilter::IHook::Result inet::dymo::DYMO::ensureRouteForDatagram ( INetworkDatagram datagram)
private
1379 {
1380  const L3Address& source = datagram->getSourceAddress();
1381  const L3Address& destination = datagram->getDestinationAddress();
1382  if (destination.isMulticast() || destination.isBroadcast() || routingTable->isLocalAddress(destination))
1383  return ACCEPT;
1384  else {
1385  EV_DETAIL << "Finding route: source = " << source << ", destination = " << destination << endl;
1386  IRoute *route = routingTable->findBestMatchingRoute(destination);
1387  DYMORouteData *routeData = route ? dynamic_cast<DYMORouteData *>(route->getProtocolData()) : nullptr;
1388  bool broken = routeData && routeData->getBroken();
1389  if (route && !route->getNextHopAsGeneric().isUnspecified() && !broken) {
1390  EV_DETAIL << "Route found: source = " << source << ", destination = " << destination << ", route: " << route << endl;
1391  if (routeData)
1392  // 8.1. Handling Route Lifetimes During Packet Forwarding
1393  // Route.LastUsed := Current_Time, and the packet is forwarded to the route's next hop.
1394  routeData->setLastUsed(simTime());
1395  return ACCEPT;
1396  }
1397  else if (source.isUnspecified() || isClientAddress(source)) {
1398  EV_DETAIL << (broken ? "Broken" : "Missing") << " route: source = " << source << ", destination = " << destination << endl;
1399  delayDatagram(datagram);
1400  if (!hasOngoingRouteDiscovery(destination))
1401  startRouteDiscovery(destination);
1402  else
1403  EV_INFO << "Route discovery is in progress: originator = " << getSelfAddress() << ", target = " << destination << endl;
1404  return QUEUE;
1405  }
1406  else
1407  // the actual routing decision will be repeated in the network protocol
1408  return ACCEPT;
1409  }
1410 }
bool isClientAddress(const L3Address &address)
Definition: DYMO.cc:1316
virtual bool isLocalAddress(const L3Address &dest) const =0
Checks if the address is a local one, i.e.
IRoutingTable * routingTable
Definition: DYMO.h:85
bool hasOngoingRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:232
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void startRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:194
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
void delayDatagram(INetworkDatagram *datagram)
Definition: DYMO.cc:241
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
void inet::dymo::DYMO::eraseDelayedDatagrams ( const L3Address target)
private

Referenced by cancelRouteDiscovery(), and completeRouteDiscovery().

261 {
262  EV_DEBUG << "Erasing the list of delayed datagrams: originator = " << getSelfAddress() << ", destination = " << target << endl;
263  auto lt = targetAddressToDelayedPackets.lower_bound(target);
264  auto ut = targetAddressToDelayedPackets.upper_bound(target);
265  targetAddressToDelayedPackets.erase(lt, ut);
266 }
L3Address getSelfAddress()
Definition: DYMO.cc:1311
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: DYMO.h:93
void inet::dymo::DYMO::eraseRREQTimer ( const L3Address target)
private

Referenced by processRREP(), processRREQHolddownTimer(), and processRREQWaitRREPTimer().

290 {
291  auto tt = targetAddressToRREQTimer.find(target);
292  targetAddressToRREQTimer.erase(tt);
293 }
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::expungeRoutes ( )
private

Referenced by processExpungeTimer().

1223 {
1224  EV_DETAIL << "Expunging routes from routing table: routeCount = " << routingTable->getNumRoutes() << endl;
1225  // 6.3. Route Table Entry Timeouts
1226  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1227  IRoute *route = routingTable->getRoute(i);
1228  if (route->getSource() == this) {
1229  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
1230  // An Active route MUST NOT be expunged
1231  // An Idle route SHOULD NOT be expunged
1232  // An Expired route MAY be expunged (least recently used first)
1233  // A route MUST be expunged if (Current_Time - Route.LastUsed) >= MAX_SEQNUM_LIFETIME.
1234  // A route MUST be expunged if Current_Time >= Route.ExpirationTime
1235  if ((getRouteState(routeData) == EXPIRED) ||
1236  (simTime() - routeData->getLastUsed() >= maxSequenceNumberLifetime) ||
1237  (simTime() >= routeData->getExpirationTime()))
1238  {
1239  EV_DETAIL << "Expunging route: " << route << endl;
1240  routingTable->deleteRoute(route);
1241  i--;
1242  }
1243  }
1244  }
1245 }
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
Definition: DYMOdefs.h:40
virtual bool deleteRoute(IRoute *entry)=0
Deletes the given route from the routing table.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IRoutingTable * routingTable
Definition: DYMO.h:85
double maxSequenceNumberLifetime
Definition: DYMO.h:65
DYMORouteState getRouteState(DYMORouteData *routeData)
Definition: DYMO.cc:1265
int inet::dymo::DYMO::getLinkCost ( const InterfaceEntry interfaceEntry,
DYMOMetricType  metricType 
)
private
1175 {
1176  switch (metricType) {
1177  case HOP_COUNT:
1178  return 1;
1179 
1180  default:
1181  throw cRuntimeError("Unknown metric type");
1182  }
1183 }
Definition: DYMOdefs.h:34
simtime_t inet::dymo::DYMO::getNextExpungeTime ( )
private

Referenced by scheduleExpungeTimer().

1248 {
1249  simtime_t nextExpirationTime = SimTime::getMaxTime();
1250  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1251  IRoute *route = routingTable->getRoute(i);
1252  if (route->getSource() == this) {
1253  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
1254  const simtime_t& expirationTime = routeData->getExpirationTime();
1255  if (expirationTime < nextExpirationTime)
1256  nextExpirationTime = expirationTime;
1257  const simtime_t& defaultExpirationTime = routeData->getLastUsed() + maxSequenceNumberLifetime;
1258  if (defaultExpirationTime < nextExpirationTime)
1259  nextExpirationTime = defaultExpirationTime;
1260  }
1261  }
1262  return nextExpirationTime;
1263 }
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IRoutingTable * routingTable
Definition: DYMO.h:85
double maxSequenceNumberLifetime
Definition: DYMO.h:65
DYMORouteState inet::dymo::DYMO::getRouteState ( DYMORouteData routeData)
private

Referenced by expungeRoutes(), and sendRERRForBrokenLink().

1266 {
1267  simtime_t lastUsed = routeData->getLastUsed();
1268  if (routeData->getBroken())
1269  return BROKEN;
1270  else if (lastUsed - simTime() <= activeInterval)
1271  return ACTIVE;
1272  else if (routeData->getExpirationTime() != SimTime::getMaxTime()) {
1273  if (simTime() >= routeData->getExpirationTime())
1274  return EXPIRED;
1275  else
1276  return TIMED;
1277  }
1278  else if (lastUsed - simTime() <= maxIdleTime)
1279  return IDLE;
1280  else
1281  return EXPIRED;
1282 }
Definition: DYMOdefs.h:40
Definition: DYMOdefs.h:39
double maxIdleTime
Definition: DYMO.h:64
Definition: DYMOdefs.h:41
Definition: DYMOdefs.h:42
Definition: DYMOdefs.h:38
double activeInterval
Definition: DYMO.h:63
L3Address inet::dymo::DYMO::getSelfAddress ( )
private
void inet::dymo::DYMO::handleMessage ( cMessage *  message)
overrideprotected
155 {
156  if (!isNodeUp())
157  throw cRuntimeError("Routing protocol is not running");
158  if (message->isSelfMessage())
159  processSelfMessage(message);
160  else
161  processMessage(message);
162 }
void processSelfMessage(cMessage *message)
Definition: DYMO.cc:168
void processMessage(cMessage *message)
Definition: DYMO.cc:182
bool isNodeUp()
Definition: DYMO.cc:1288
bool inet::dymo::DYMO::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprivatevirtual

Perform one stage of a lifecycle operation.

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

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

Implements inet::ILifecycle.

1417 {
1418  Enter_Method_Silent();
1419  if (dynamic_cast<NodeStartOperation *>(operation)) {
1422  }
1423  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
1425  // TODO: send a RERR to notify peers about broken routes
1426  for (auto & elem : targetAddressToRREQTimer)
1427  cancelRouteDiscovery(elem.first);
1428 
1429  }
1430  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
1433  targetAddressToRREQTimer.clear();
1435  }
1436  }
1437  else
1438  throw cRuntimeError("Unsupported lifecycle operation '%s'", operation->getClassName());
1439  return true;
1440 }
std::map< L3Address, DYMOSequenceNumber > targetAddressToSequenceNumber
Definition: DYMO.h:91
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void cancelRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:221
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: DYMO.h:93
Stage
Definition: NodeOperations.h:46
void configureInterfaces()
Definition: DYMO.cc:1293
Definition: NodeOperations.h:127
bool inet::dymo::DYMO::hasDelayedDatagrams ( const L3Address target)
private

Referenced by processRREQHolddownTimer().

269 {
271 }
std::multimap< L3Address, INetworkDatagram * > targetAddressToDelayedPackets
Definition: DYMO.h:93
bool inet::dymo::DYMO::hasOngoingRouteDiscovery ( const L3Address target)
private

Referenced by cancelRouteDiscovery(), completeRouteDiscovery(), ensureRouteForDatagram(), processRREP(), retryRouteDiscovery(), and startRouteDiscovery().

233 {
234  return targetAddressToRREQTimer.find(target) != targetAddressToRREQTimer.end();
235 }
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::incrementSequenceNumber ( )
private

Referenced by createRREP(), and createRREQ().

1363 {
1364  // 5.5. AODVv2 Sequence Numbers
1365  // Most of the time, OwnSeqNum is incremented by simply adding one (1).
1366  // But to increment OwnSeqNum when it has the value of the largest possible
1367  // number representable as a 16-bit unsigned integer (i.e., 65,535), it MUST
1368  // be set to one (1). In other words, the sequence number after 65,535 is 1.
1369  sequenceNumber++;
1370  if (sequenceNumber == 0)
1371  sequenceNumber = 1;
1372 }
DYMOSequenceNumber sequenceNumber
Definition: DYMO.h:90
void inet::dymo::DYMO::initialize ( int  stage)
overrideprotected
91 {
92  cSimpleModule::initialize(stage);
93 
94  if (stage == INITSTAGE_LOCAL) {
95  // DYMO parameters from RFC
96  clientAddresses = par("clientAddresses");
97  useMulticastRREP = par("useMulticastRREP");
98  interfaces = par("interfaces");
99  activeInterval = par("activeInterval");
100  maxIdleTime = par("maxIdleTime");
101  maxSequenceNumberLifetime = par("maxSequenceNumberLifetime");
102  routeRREQWaitTime = par("routeRREQWaitTime");
103  rreqHolddownTime = par("rreqHolddownTime");
104  maxHopCount = par("maxHopCount");
105  discoveryAttemptsMax = par("discoveryAttemptsMax");
106  appendInformation = par("appendInformation");
107  bufferSizePackets = par("bufferSizePackets");
108  bufferSizeBytes = par("bufferSizeBytes");
109  // DYMO extension parameters
110  maxJitter = par("maxJitter");
111  sendIntermediateRREP = par("sendIntermediateRREP");
112  minHopLimit = par("minHopLimit");
113  maxHopLimit = par("maxHopLimit");
114  // context
115  host = getContainingNode(this);
116  nodeStatus = dynamic_cast<NodeStatus *>(host->getSubmodule("status"));
117  interfaceTable = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
118  routingTable = getModuleFromPar<IRoutingTable>(par("routingTableModule"), this);
119  networkProtocol = getModuleFromPar<INetfilter>(par("networkProtocolModule"), this);
120  // internal
121  expungeTimer = new cMessage("ExpungeTimer");
122  }
123  else if (stage == INITSTAGE_NETWORK_LAYER_3) {
124  L3AddressResolver addressResolver;
125  cStringTokenizer tokenizer(clientAddresses);
126  while (tokenizer.hasMoreTokens()) {
127  const char *clientAddress = tokenizer.nextToken();
128  char *slash = const_cast<char *>(strchr(clientAddress, '/'));
129  if (slash)
130  *slash = 0;
131  const L3Address address = addressResolver.resolve(clientAddress);
132  int prefixLength = address.getAddressType()->getMaxPrefixLength();
133  if (slash) {
134  int pLength = atoi(slash + 1);
135  if (pLength < 0 || pLength > prefixLength)
136  throw cRuntimeError("invalid prefix length in 'clientAddresses' parameter: '%s/%s'", clientAddress, slash);
137  prefixLength = pLength;
138  }
139  clientAddressAndPrefixLengthPairs.push_back(std::pair<L3Address, int>(address, prefixLength));
140  }
141  }
142  else if (stage == INITSTAGE_ROUTING_PROTOCOLS) {
143  IPSocket socket(gate("ipOut"));
144  socket.registerProtocol(IP_PROT_MANET);
145 
146  host->subscribe(NF_LINK_BREAK, this);
148  networkProtocol->registerHook(0, this);
149  if (isNodeUp())
151  }
152 }
simsignal_t NF_LINK_BREAK
Definition: NotifierConsts.cc:43
cMessage * expungeTimer
Definition: DYMO.h:89
double routeRREQWaitTime
Definition: DYMO.h:66
int maxHopCount
Definition: DYMO.h:68
int bufferSizeBytes
Definition: DYMO.h:72
const char * clientAddresses
Definition: DYMO.h:60
Initialization of network-layer protocols, stage 3.
Definition: InitStages.h:84
IRoutingTable * routingTable
Definition: DYMO.h:85
double maxIdleTime
Definition: DYMO.h:64
INetfilter * networkProtocol
Definition: DYMO.h:86
Initialization of routing protocols.
Definition: InitStages.h:101
double maxSequenceNumberLifetime
Definition: DYMO.h:65
L3Address getSelfAddress()
Definition: DYMO.cc:1311
IL3AddressType * addressType
Definition: DYMO.h:83
Definition: IPProtocolId_m.h:93
std::vector< std::pair< L3Address, int > > clientAddressAndPrefixLengthPairs
Definition: DYMO.h:94
simtime_t maxJitter
Definition: DYMO.h:75
double rreqHolddownTime
Definition: DYMO.h:67
Local initializations.
Definition: InitStages.h:35
int maxHopLimit
Definition: DYMO.h:78
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:65
IL3AddressType * getAddressType() const
Definition: L3Address.cc:60
bool appendInformation
Definition: DYMO.h:70
const char * interfaces
Definition: DYMO.h:62
bool useMulticastRREP
Definition: DYMO.h:61
bool isNodeUp()
Definition: DYMO.cc:1288
cModule * host
Definition: DYMO.h:81
int bufferSizePackets
Definition: DYMO.h:71
int minHopLimit
Definition: DYMO.h:77
void configureInterfaces()
Definition: DYMO.cc:1293
NodeStatus * nodeStatus
Definition: DYMO.h:82
IInterfaceTable * interfaceTable
Definition: DYMO.h:84
virtual void registerHook(int priority, IHook *hook)=0
Adds the provided hook to the list of registered hooks that will be called by the network layer when ...
double activeInterval
Definition: DYMO.h:63
bool sendIntermediateRREP
Definition: DYMO.h:76
int discoveryAttemptsMax
Definition: DYMO.h:69
bool inet::dymo::DYMO::isClientAddress ( const L3Address address)
private

Referenced by ensureRouteForDatagram(), processRREP(), and processRREQ().

1317 {
1318  if (routingTable->isLocalAddress(address))
1319  return true;
1320  else {
1321  for (auto & elem : clientAddressAndPrefixLengthPairs)
1322  // TODO: check for prefix length too
1323  if (elem.first == address)
1324  return true;
1325 
1326  return false;
1327  }
1328 }
virtual bool isLocalAddress(const L3Address &dest) const =0
Checks if the address is a local one, i.e.
IRoutingTable * routingTable
Definition: DYMO.h:85
std::vector< std::pair< L3Address, int > > clientAddressAndPrefixLengthPairs
Definition: DYMO.h:94
bool inet::dymo::DYMO::isLoopFree ( RteMsg rteMsg,
IRoute route 
)
private

Referenced by updateRoutes().

1186 {
1187  // TODO: implement
1188  return true;
1189 }
bool inet::dymo::DYMO::isNodeUp ( )
private

Referenced by handleMessage(), and initialize().

1289 {
1290  return !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
1291 }
NodeStatus * nodeStatus
Definition: DYMO.h:82
virtual State getState() const
Definition: NodeStatus.h:48
Definition: NodeStatus.h:40
virtual int inet::dymo::DYMO::numInitStages ( ) const
inlineoverrideprotectedvirtual
102 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
bool inet::dymo::DYMO::permissibleRteMsg ( RteMsg rteMsg)
private

Referenced by processRREP(), and processRREQ().

454 {
455  // 7.5. Handling a Received RteMsg
456  AddressBlock& originatorNode = rteMsg->getOriginatorNode();
457  AddressBlock& targetNode = rteMsg->getTargetNode();
458  INetworkProtocolControlInfo *networkProtocolControlInfo = check_and_cast<INetworkProtocolControlInfo *>(rteMsg->getControlInfo());
459  // 1. HandlingRtr MUST handle AODVv2 messages only from adjacent
460  // routers as specified in Section 5.4. AODVv2 messages from other
461  // sources MUST be disregarded.
462  // 5.4. AODVv2 Packet Header Fields and Information Elements
463  // If a packet is received with a value other than 255, any AODVv2
464  // message contained in the packet MUST be disregarded by AODVv2.
465  // FIXME: we should rather compare with 255 but unfortunately IPv4 decrements
466  // FIXME: TTL too early in the sender, see http://en.wikipedia.org/wiki/Time_to_live
467  if (networkProtocolControlInfo->getHopLimit() != 254)
468  return false;
469  // 2. If the RteMsg.<msg-hop-limit> is equal to 0, then the message is disregarded.
470  if (rteMsg->getHopLimit() == 0)
471  return false;
472  // 3. If the RteMsg.<msg-hop-count> is present, and RteMsg.<msg-hop-
473  // count> >= MAX_HOPCOUNT, then the message is disregarded.
474  if (rteMsg->getHopCount() >= maxHopCount)
475  return false;
476  // 4. HandlingRtr examines the RteMsg to ascertain that it contains the
477  // required information: TargNode.Addr, OrigNode.Addr,
478  // RteMsg_Gen.Metric and RteMsg_Gen.SeqNum. If the required
479  // information does not exist, the message is disregarded.
480  if (dynamic_cast<RREQ *>(rteMsg) && (!originatorNode.getHasMetric() || !originatorNode.getHasSequenceNumber()))
481  return false;
482  else if (dynamic_cast<RREP *>(rteMsg) && (!targetNode.getHasMetric() || !targetNode.getHasSequenceNumber()))
483  return false;
484  // 5. HandlingRtr checks that OrigNode.Addr and TargNode.Addr are valid
485  // routable unicast addresses. If not, the message is disregarded.
486  const L3Address& originatorAddress = originatorNode.getAddress();
487  const L3Address& targetAddress = targetNode.getAddress();
488  if (originatorAddress.isUnspecified() || originatorAddress.isMulticast() || originatorAddress.isBroadcast() ||
489  targetAddress.isUnspecified() || targetAddress.isMulticast() || targetAddress.isBroadcast())
490  return false;
491  // 6. HandlingRtr checks that the Metric Type associated with
492  // OrigNode.Metric and TargNode.Metric is known, and that Cost(L)
493  // can be computed. If not, the message is disregarded.
494  // * DISCUSSION: alternatively, can change the AddrBlk metric to
495  // use HopCount, measured from<msg-hop-limit>.
496  if (originatorNode.getMetricType() != HOP_COUNT || targetNode.getMetricType() != HOP_COUNT)
497  return false;
498  // 7. If MAX_METRIC[RteMsg.MetricType] <= (RteMsg_Gen.Metric +
499  // Cost(L)), where 'L' is the incoming link, the RteMsg is
500  // disregarded.
501  // TODO: implement
502  return true;
503 }
int maxHopCount
Definition: DYMO.h:68
Definition: DYMOdefs.h:34
void inet::dymo::DYMO::processDYMOPacket ( DYMOPacket packet)
private

Referenced by processUDPPacket().

438 {
439  if (dynamic_cast<RREQ *>(packet))
440  processRREQ((RREQ *)packet);
441  else if (dynamic_cast<RREP *>(packet))
442  processRREP((RREP *)packet);
443  else if (dynamic_cast<RERR *>(packet))
444  processRERR((RERR *)packet);
445  else
446  throw cRuntimeError("Unknown DYMO packet");
447 }
Definition: AODVControlPackets_m.h:69
void processRREQ(RREQ *rreq)
Definition: DYMO.cc:659
void processRERR(RERR *rerr)
Definition: DYMO.cc:941
void processRREP(RREP *rrep)
Definition: DYMO.cc:780
Definition: AODVControlPackets_m.h:68
Definition: AODVControlPackets_m.h:70
void inet::dymo::DYMO::processExpungeTimer ( )
private

Referenced by processSelfMessage().

1196 {
1197  EV_DETAIL << "Processing expunge timer" << endl;
1198  expungeRoutes();
1200 }
void scheduleExpungeTimer()
Definition: DYMO.cc:1202
void expungeRoutes()
Definition: DYMO.cc:1222
void inet::dymo::DYMO::processMessage ( cMessage *  message)
private

Referenced by handleMessage().

183 {
184  if (dynamic_cast<UDPPacket *>(message))
185  processUDPPacket((UDPPacket *)message);
186  else
187  throw cRuntimeError("Unknown message");
188 }
void processUDPPacket(UDPPacket *packet)
Definition: DYMO.cc:400
void inet::dymo::DYMO::processRERR ( RERR rerr)
private

Referenced by processDYMOPacket().

942 {
943  EV_DETAIL << "Processing RERR" << endl;
944  // 8.4. Receiving and Handling RERR Messages
945  // HandlingRtr examines the incoming RERR to assure that it contains
946  // Msg.<msg-hop-limit> and at least one UnreachableNode.Address. If the
947  // required information does not exist, the incoming RERR message is
948  // disregarded and further processing stopped.
949  if (rerrIncoming->getHopLimit() == 0 || rerrIncoming->getUnreachableNodeArraySize() == 0)
950  return;
951  else {
952  INetworkProtocolControlInfo *networkProtocolControlInfo = check_and_cast<INetworkProtocolControlInfo *>(rerrIncoming->getControlInfo());
953  // Otherwise, for each UnreachableNode.Address, HandlingRtr searches its
954  // route table for a route using longest prefix matching. If no such
955  // Route is found, processing is complete for that UnreachableNode.Address.
956  std::vector<L3Address> unreachableAddresses;
957  for (int i = 0; i < (int)rerrIncoming->getUnreachableNodeArraySize(); i++) {
958  AddressBlock& addressBlock = rerrIncoming->getUnreachableNode(i);
959  for (int j = 0; j < routingTable->getNumRoutes(); j++) {
960  IRoute *route = routingTable->getRoute(j);
961  if (route->getSource() == this) {
962  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
963  const L3Address& unreachableAddress = addressBlock.getAddress();
964  // HandlingRtr verifies the following:
965  // 1. The UnreachableNode.Address is a routable unicast address.
966  // 2. Route.NextHopAddress is the same as RERR IP.SourceAddress.
967  // 3. Route.NextHopInterface is the same as the interface on which the
968  // RERR was received.
969  // 4. The UnreachableNode.SeqNum is unknown, OR Route.SeqNum <=
970  // UnreachableNode.SeqNum (using signed 16-bit arithmetic).
971  if (unreachableAddress.isUnicast() &&
972  unreachableAddress == route->getDestinationAsGeneric() &&
973  route->getNextHopAsGeneric() == networkProtocolControlInfo->getSourceAddress() &&
974  route->getInterface()->getInterfaceId() == networkProtocolControlInfo->getInterfaceId() &&
975  (!addressBlock.getHasSequenceNumber() || routeData->getSequenceNumber() <= addressBlock.getSequenceNumber()))
976  {
977  // If the route satisfies all of the above conditions, HandlingRtr sets
978  // the Route.Broken flag for that route.
979  EV_DETAIL << "Marking route as broken: " << route << endl;
980  // TODO delete route, but save its data for later update
981  // route->setEnabled(false);
982  routeData->setBroken(true);
983  unreachableAddresses.push_back(unreachableAddress);
984  }
985  }
986  }
987  }
988  if (unreachableAddresses.size() == 0)
989  EV_DETAIL << "No unreachable address found" << endl;
990  else {
991  // Furthermore, if Msg.<msg-hop-limit> is greater than 0, then HandlingRtr
992  // adds the UnreachableNode address and TLV information to an AddrBlk for
993  // delivery in the outgoing RERR message to one or more of HandlingRtr's
994  // upstream neighbors.
995  // If there are no UnreachableNode addresses to be transmitted in an
996  // RERR to upstream routers, HandlingRtr MUST discard the RERR, and no
997  // further action is taken.
998  // Otherwise, Msg.<msg-hop-limit> is decremented by one (1) and
999  RERR *rerrOutgoing = createRERR(unreachableAddresses);
1000  rerrOutgoing->setHopLimit(rerrIncoming->getHopLimit() - 1);
1001  // processing continues as follows:
1002  // o If precursor lists are (optionally) maintained, the outgoing RERR
1003  // SHOULD be sent to the active precursors of the broken route as
1004  // specified in Section 13.3.
1005  // o Otherwise, if the incoming RERR message was received at the LL-
1006  // MANET-Routers [RFC5498] multicast address, the outgoing RERR
1007  // SHOULD also be sent to LL-MANET-Routers.
1008  // o Otherwise, if the PktSource MsgTLV is present, and HandlingRtr has
1009  // a Route to PktSource.Addr, then HandlingRtr MUST send the outgoing
1010  // RERR to Route[PktSource.Addr].NextHop.
1011  // o Otherwise, the outgoing RERR MUST be sent to LL-MANET-Routers.
1012  sendRERR(rerrOutgoing);
1013  }
1014  }
1015  delete rerrIncoming;
1016 }
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IRoutingTable * routingTable
Definition: DYMO.h:85
RERR * createRERR(std::vector< L3Address > &addresses)
Definition: DYMO.cc:834
void sendRERR(RERR *rerr)
Definition: DYMO.cc:860
Definition: AODVControlPackets_m.h:70
void inet::dymo::DYMO::processRREP ( RREP rrep)
private

Referenced by processDYMOPacket().

781 {
782  const L3Address& target = rrepIncoming->getTargetNode().getAddress();
783  const L3Address& originator = rrepIncoming->getOriginatorNode().getAddress();
784  EV_DETAIL << "Processing RREP: originator = " << originator << ", target = " << target << endl;
785  if (permissibleRteMsg(rrepIncoming)) {
786  processRteMsg(rrepIncoming);
787  // 7.5.2. Additional Handling for Outgoing RREP
788  if (isClientAddress(originator)) {
789  EV_DETAIL << "Received RREP for client: originator = " << originator << ", target = " << target << endl;
790  if (hasOngoingRouteDiscovery(target)) {
791  completeRouteDiscovery(target);
792  cancelRREQTimer(target);
793  deleteRREQTimer(target);
794  eraseRREQTimer(target);
795  }
796  }
797  else {
798  // o If HandlingRtr is not OrigRtr then the outgoing RREP is sent to
799  // the Route.NextHopAddress for the RREP.AddrBlk[OrigNode]. If no
800  // forwarding route exists to OrigNode, then a RERR SHOULD be
801  // transmitted to RREP.AddrBlk[TargNode]. See Table 1 for notational
802  // conventions; OrigRtr, OrigNode, and TargNode are routers named in
803  // the context of OrigRtr, that is, the router originating the RREQ
804  // to which the RREP is responding.
805  EV_DETAIL << "Forwarding RREP: originator = " << originator << ", target = " << target << endl;
806  RREP *rrepOutgoing = rrepIncoming->dup();
807  if (appendInformation)
808  addSelfNode(rrepOutgoing);
809  if (useMulticastRREP)
810  sendRREP(rrepOutgoing);
811  else {
812  IRoute *route = routingTable->findBestMatchingRoute(originator);
813  if (route)
814  sendRREP(rrepOutgoing, route);
815  else
816  EV_WARN << "No route found toward originator, dropping RREP: originator = " << originator << ", target = " << target << endl;
817  }
818  }
819  }
820  else
821  EV_WARN << "Dropping non-permissible RREQ" << endl;
822  delete rrepIncoming;
823 }
Definition: AODVControlPackets_m.h:69
bool isClientAddress(const L3Address &address)
Definition: DYMO.cc:1316
void cancelRREQTimer(const L3Address &target)
Definition: DYMO.cc:277
void deleteRREQTimer(const L3Address &target)
Definition: DYMO.cc:283
void processRteMsg(RteMsg *rteMsg)
Definition: DYMO.cc:505
void addSelfNode(RteMsg *rteMsg)
Definition: DYMO.cc:1334
IRoutingTable * routingTable
Definition: DYMO.h:85
bool hasOngoingRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:232
bool permissibleRteMsg(RteMsg *rteMsg)
Definition: DYMO.cc:453
bool appendInformation
Definition: DYMO.h:70
bool useMulticastRREP
Definition: DYMO.h:61
void completeRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:210
void sendRREP(RREP *rrep)
Definition: DYMO.cc:761
void eraseRREQTimer(const L3Address &target)
Definition: DYMO.cc:289
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
void inet::dymo::DYMO::processRREQ ( RREQ rreq)
private

Referenced by processDYMOPacket().

660 {
661  const L3Address& target = rreqIncoming->getTargetNode().getAddress();
662  const L3Address& originator = rreqIncoming->getOriginatorNode().getAddress();
663  EV_DETAIL << "Processing RREQ: originator = " << originator << ", target = " << target << endl;
664  if (permissibleRteMsg(rreqIncoming)) {
665  processRteMsg(rreqIncoming);
666  // 7.5.1. Additional Handling for Outgoing RREQ
667  // o If the upstream router is in the Blacklist, and Current_Time <
668  // BlacklistRmTime, then HandlingRtr MUST NOT transmit any outgoing
669  // RREQ, and processing is complete.
670  // TODO: implement
671  // o Otherwise, if the upstream router is in the Blacklist, and
672  // Current_Time >= BlacklistRmTime, then the upstream router SHOULD
673  // be removed from the Blacklist, and message processing continued.
674  // TODO: implement
675  if (isClientAddress(target)) {
676  // o If TargNode is a client of HandlingRtr, then a RREP is generated
677  // by the HandlingRtr (i.e., TargRtr) and unicast to the upstream
678  // router towards the RREQ OrigNode, as specified in Section 7.4.
679  // Afterwards, TargRtr processing for the RREQ is complete.
680  EV_DETAIL << "Received RREQ for client: originator = " << originator << ", target = " << target << endl;
681  if (useMulticastRREP)
682  sendRREP(createRREP(rreqIncoming));
683  else {
684  IRoute *route = routingTable->findBestMatchingRoute(originator);
685  RREP *rrep = createRREP(rreqIncoming, route);
686  sendRREP(rrep, route);
687  }
688  }
689  else {
690  // o If HandlingRtr is not the TargetNode, then the outgoing RREQ (as
691  // altered by the procedure defined above) SHOULD be sent to the IP
692  // multicast address LL-MANET-Routers [RFC5498]. If the RREQ is
693  // unicast, the IP.DestinationAddress is set to the NextHopAddress.
694  EV_DETAIL << "Forwarding RREQ: originator = " << originator << ", target = " << target << endl;
695  RREQ *rreqOutgoing = rreqIncoming->dup();
696  if (appendInformation)
697  addSelfNode(rreqOutgoing);
698  sendRREQ(rreqOutgoing);
699  }
700  }
701  else
702  EV_WARN << "Dropping non-permissible RREQ" << endl;
703  delete rreqIncoming;
704 }
Definition: AODVControlPackets_m.h:69
bool isClientAddress(const L3Address &address)
Definition: DYMO.cc:1316
void processRteMsg(RteMsg *rteMsg)
Definition: DYMO.cc:505
RREP * createRREP(RteMsg *rteMsg)
Definition: DYMO.cc:715
void addSelfNode(RteMsg *rteMsg)
Definition: DYMO.cc:1334
IRoutingTable * routingTable
Definition: DYMO.h:85
void sendRREQ(RREQ *rreq)
Definition: DYMO.cc:650
bool permissibleRteMsg(RteMsg *rteMsg)
Definition: DYMO.cc:453
bool appendInformation
Definition: DYMO.h:70
bool useMulticastRREP
Definition: DYMO.h:61
void sendRREP(RREP *rrep)
Definition: DYMO.cc:761
Definition: AODVControlPackets_m.h:68
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
void inet::dymo::DYMO::processRREQBackoffTimer ( RREQBackoffTimer message)
private

Referenced by processSelfMessage().

349 {
350  EV_DETAIL << "Processing RREQ backoff timer" << endl;
351  retryRouteDiscovery(message->getTarget(), message->getRetryCount() + 1);
352  delete message;
353 }
void retryRouteDiscovery(const L3Address &target, int retryCount)
Definition: DYMO.cc:202
void inet::dymo::DYMO::processRREQHolddownTimer ( RREQHolddownTimer message)
private

Referenced by processSelfMessage().

379 {
380  EV_DETAIL << "Processing RREQ holddown timer" << endl;
381  const L3Address& target = message->getTarget();
382  eraseRREQTimer(target);
383  if (hasDelayedDatagrams(target))
384  startRouteDiscovery(target);
385  delete message;
386 }
bool hasDelayedDatagrams(const L3Address &target)
Definition: DYMO.cc:268
void startRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:194
void eraseRREQTimer(const L3Address &target)
Definition: DYMO.cc:289
void inet::dymo::DYMO::processRREQWaitRREPTimer ( RREQWaitRREPTimer message)
private

Referenced by processSelfMessage().

315 {
316  EV_DETAIL << "Processing RREQ wait RREP timer" << endl;
317  const L3Address& target = message->getTarget();
318  if (message->getRetryCount() == discoveryAttemptsMax - 1) {
319  cancelRouteDiscovery(target);
320  cancelRREQTimer(target);
321  eraseRREQTimer(target);
323  }
324  else
325  scheduleRREQBackoffTimer(createRREQBackoffTimer(target, message->getRetryCount()));
326  delete message;
327 }
RREQHolddownTimer * createRREQHolddownTimer(const L3Address &target)
Definition: DYMO.cc:364
void cancelRREQTimer(const L3Address &target)
Definition: DYMO.cc:277
RREQBackoffTimer * createRREQBackoffTimer(const L3Address &target, int retryCount)
Definition: DYMO.cc:333
void scheduleRREQBackoffTimer(RREQBackoffTimer *message)
Definition: DYMO.cc:341
void cancelRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:221
void eraseRREQTimer(const L3Address &target)
Definition: DYMO.cc:289
void scheduleRREQHolddownTimer(RREQHolddownTimer *message)
Definition: DYMO.cc:371
int discoveryAttemptsMax
Definition: DYMO.h:69
void inet::dymo::DYMO::processRteMsg ( RteMsg rteMsg)
private

Referenced by processRREP(), and processRREQ().

506 {
507  // 7.5. Handling a Received RteMsg
508  // 1. HandlingRtr MUST process the routing information contained in the
509  // RteMsg as speciied in Section 6.1.
510  if (dynamic_cast<RREQ *>(rteMsg))
511  updateRoutes(rteMsg, rteMsg->getOriginatorNode());
512  else if (dynamic_cast<RREP *>(rteMsg))
513  updateRoutes(rteMsg, rteMsg->getTargetNode());
514  // 2. HandlingRtr MAY process AddedNode routing information (if
515  // present) as specified in Section 13.7.1 Otherwise, if AddedNode
516  // information is not processed, it MUST be deleted.
517  int count = rteMsg->getAddedNodeArraySize();
518  for (int i = 0; i < count; i++)
519  updateRoutes(rteMsg, rteMsg->getAddedNode(i));
520  // 3. By sending the updated RteMsg, HandlingRtr advertises that it
521  // will route for addresses contained in the outgoing RteMsg based
522  // on the information enclosed. HandlingRtr MAY choose not to send
523  // the RteMsg, though not resending this RteMsg could decrease
524  // connectivity in the network or result in a nonoptimal path. The
525  // circumstances under which HandlingRtr might choose to not re-
526  // transmit a RteMsg are not specified in this document. Some
527  // examples might include the following:
528  // * HandlingRtr is already heavily loaded and does not want to
529  // advertise routing for the contained addresses
530  // * HandlingRtr recently transmitted identical routing information
531  // (e.g. in a RteMsg advertising the same metric)
532  // * HandlingRtr is low on energy and has to reduce energy expended
533  // for sending protocol messages or packet forwarding
534  // Unless HandlingRtr is prepared to send an updated RteMsg, it
535  // halts processing. Otherwise, processing continues as follows.
536  // TODO: why is this here and how could we halt here?
537  // 4. HandlingRtr MUST decrement RteMsg.<msg-hop-limit>. If
538  // RteMsg.<msg-hop-limit> is then zero (0), no further action is taken.
539  rteMsg->setHopLimit(rteMsg->getHopLimit() - 1);
540  // 5. HandlingRtr MUST increment RteMsg.<msg-hop-count>.
541  rteMsg->setHopCount(rteMsg->getHopCount() + 1);
542 }
int count(const std::vector< T > &v, const T &a)
Definition: stlutils.h:58
void updateRoutes(RteMsg *rteMsg, AddressBlock &addressBlock)
Definition: DYMO.cc:1069
void inet::dymo::DYMO::processSelfMessage ( cMessage *  message)
private

Referenced by handleMessage().

169 {
170  if (message == expungeTimer)
172  else if (dynamic_cast<RREQWaitRREPTimer *>(message))
173  processRREQWaitRREPTimer((RREQWaitRREPTimer *)message);
174  else if (dynamic_cast<RREQBackoffTimer *>(message))
175  processRREQBackoffTimer((RREQBackoffTimer *)message);
176  else if (dynamic_cast<RREQHolddownTimer *>(message))
177  processRREQHolddownTimer((RREQHolddownTimer *)message);
178  else
179  throw cRuntimeError("Unknown self message");
180 }
cMessage * expungeTimer
Definition: DYMO.h:89
void processRREQHolddownTimer(RREQHolddownTimer *message)
Definition: DYMO.cc:378
void processRREQBackoffTimer(RREQBackoffTimer *message)
Definition: DYMO.cc:348
void processExpungeTimer()
Definition: DYMO.cc:1195
void processRREQWaitRREPTimer(RREQWaitRREPTimer *message)
Definition: DYMO.cc:314
void inet::dymo::DYMO::processUDPPacket ( UDPPacket packet)
private

Referenced by processMessage().

401 {
402  cPacket *encapsulatedPacket = packet->decapsulate();
403  if (DYMOPacket *dymoPacket = dynamic_cast<DYMOPacket *>(encapsulatedPacket)) {
404  dymoPacket->setControlInfo(packet->removeControlInfo());
405  processDYMOPacket(dymoPacket);
406  }
407  else
408  throw cRuntimeError("Unknown UDP packet");
409  delete packet;
410 }
void processDYMOPacket(DYMOPacket *packet)
Definition: DYMO.cc:437
void inet::dymo::DYMO::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprivatevirtual
1447 {
1448  Enter_Method("receiveChangeNotification");
1449  if (signalID == NF_LINK_BREAK) {
1450  EV_WARN << "Received link break" << endl;
1451  cPacket *frame = check_and_cast<cPacket *>(obj);
1452 
1453  if (false
1454 #ifdef WITH_IEEE80211
1455  || dynamic_cast<ieee80211::Ieee80211Frame *>(frame)
1456 #endif // ifdef WITH_IEEE80211
1457 #ifdef WITH_IDEALWIRELESS
1458  || dynamic_cast<IdealMacFrame *>(frame)
1459 #endif // ifdef WITH_IDEALWIRELESS
1460  )
1461  {
1462  INetworkDatagram *datagram = dynamic_cast<INetworkDatagram *>(frame->getEncapsulatedPacket());
1463  if (datagram) {
1464  // TODO: get nexthop and interface from the packet
1465  // INetworkProtocolControlInfo * networkProtocolControlInfo = dynamic_cast<INetworkProtocolControlInfo *>(datagram->getControlInfo());
1466  const L3Address& destination = datagram->getDestinationAddress();
1467  if (destination.getAddressType() == addressType) {
1468  IRoute *route = routingTable->findBestMatchingRoute(destination);
1469  if (route) {
1470  const L3Address& nextHop = route->getNextHopAsGeneric();
1471  sendRERRForBrokenLink(route->getInterface(), nextHop);
1472  }
1473  }
1474  }
1475  }
1476  else
1477  throw cRuntimeError("Unknown packet type in NF_LINK_BREAK signal");
1478  }
1479 }
simsignal_t NF_LINK_BREAK
Definition: NotifierConsts.cc:43
IRoutingTable * routingTable
Definition: DYMO.h:85
void sendRERRForBrokenLink(const InterfaceEntry *interfaceEntry, const L3Address &nextHop)
Definition: DYMO.cc:890
IL3AddressType * addressType
Definition: DYMO.h:83
virtual L3Address getNextHopAsGeneric() const =0
Next hop address.
virtual IRoute * findBestMatchingRoute(const L3Address &dest) const =0
The routing function.
void inet::dymo::DYMO::reinjectDelayedDatagram ( INetworkDatagram datagram)
private

Referenced by completeRouteDiscovery().

249 {
250  EV_INFO << "Sending queued datagram: source = " << datagram->getSourceAddress() << ", destination = " << datagram->getDestinationAddress() << endl;
251  networkProtocol->reinjectQueuedDatagram(const_cast<const INetworkDatagram *>(datagram));
252 }
INetfilter * networkProtocol
Definition: DYMO.h:86
virtual void reinjectQueuedDatagram(const INetworkDatagram *datagram)=0
Requests the network layer to restart the processing of the datagram.
void inet::dymo::DYMO::retryRouteDiscovery ( const L3Address target,
int  retryCount 
)
private

Referenced by processRREQBackoffTimer().

203 {
204  EV_INFO << "Retrying route discovery: originator = " << getSelfAddress() << ", target = " << target << ", retry = " << retryCount << endl;
205  ASSERT(hasOngoingRouteDiscovery(target));
206  sendRREQ(createRREQ(target, retryCount));
208 }
bool hasOngoingRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:232
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void sendRREQ(RREQ *rreq)
Definition: DYMO.cc:650
void scheduleRREQWaitRREPTimer(RREQWaitRREPTimer *message)
Definition: DYMO.cc:307
RREQWaitRREPTimer * createRREQWaitRREPTimer(const L3Address &target, int retryCount)
Definition: DYMO.cc:299
RREQ * createRREQ(const L3Address &target, int retryCount)
Definition: DYMO.cc:594
void inet::dymo::DYMO::scheduleExpungeTimer ( )
private

Referenced by processExpungeTimer(), and updateRoute().

1203 {
1204  EV_DETAIL << "Scheduling expunge timer" << endl;
1205  simtime_t nextExpungeTime = getNextExpungeTime();
1206  if (nextExpungeTime == SimTime::getMaxTime()) {
1207  if (expungeTimer->isScheduled())
1208  cancelEvent(expungeTimer);
1209  }
1210  else {
1211  if (!expungeTimer->isScheduled())
1212  scheduleAt(nextExpungeTime, expungeTimer);
1213  else {
1214  if (expungeTimer->getArrivalTime() != nextExpungeTime) {
1215  cancelEvent(expungeTimer);
1216  scheduleAt(nextExpungeTime, expungeTimer);
1217  }
1218  }
1219  }
1220 }
simtime_t getNextExpungeTime()
Definition: DYMO.cc:1247
cMessage * expungeTimer
Definition: DYMO.h:89
void inet::dymo::DYMO::scheduleRREQBackoffTimer ( RREQBackoffTimer message)
private

Referenced by processRREQWaitRREPTimer().

342 {
343  EV_DETAIL << "Scheduling RREQ backoff timer" << endl;
344  targetAddressToRREQTimer[message->getTarget()] = message;
345  scheduleAt(simTime() + computeRREQBackoffTime(message->getRetryCount()), message);
346 }
simtime_t computeRREQBackoffTime(int retryCount)
Definition: DYMO.cc:355
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::scheduleRREQHolddownTimer ( RREQHolddownTimer message)
private

Referenced by processRREQWaitRREPTimer().

372 {
373  EV_DETAIL << "Scheduling RREQ holddown timer" << endl;
374  targetAddressToRREQTimer[message->getTarget()] = message;
375  scheduleAt(simTime() + rreqHolddownTime, message);
376 }
double rreqHolddownTime
Definition: DYMO.h:67
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::scheduleRREQWaitRREPTimer ( RREQWaitRREPTimer message)
private

Referenced by retryRouteDiscovery(), and startRouteDiscovery().

308 {
309  EV_DETAIL << "Scheduling RREQ wait RREP timer" << endl;
310  targetAddressToRREQTimer[message->getTarget()] = message;
311  scheduleAt(simTime() + routeRREQWaitTime, message);
312 }
double routeRREQWaitTime
Definition: DYMO.h:66
std::map< L3Address, RREQTimer * > targetAddressToRREQTimer
Definition: DYMO.h:92
void inet::dymo::DYMO::sendDYMOPacket ( DYMOPacket packet,
const InterfaceEntry interfaceEntry,
const L3Address nextHop,
double  delay 
)
private

Referenced by sendRERR(), sendRREP(), and sendRREQ().

417 {
418  INetworkProtocolControlInfo *networkProtocolControlInfo = addressType->createNetworkProtocolControlInfo();
419  // 5.4. AODVv2 Packet Header Fields and Information Elements
420  // In addition, IP Protocol Number 138 has been reserved for MANET protocols [RFC5498].
421  networkProtocolControlInfo->setTransportProtocol(IP_PROT_MANET);
422  // The IPv4 TTL (IPv6 Hop Limit) field for all packets containing AODVv2 messages is set to 255.
423  networkProtocolControlInfo->setHopLimit(255);
424  networkProtocolControlInfo->setDestinationAddress(nextHop);
425  networkProtocolControlInfo->setSourceAddress(getSelfAddress());
426  if (interfaceEntry)
427  networkProtocolControlInfo->setInterfaceId(interfaceEntry->getInterfaceId());
428  UDPPacket *udpPacket = new UDPPacket(packet->getName());
429  udpPacket->encapsulate(packet);
430  // In its default mode of operation, AODVv2 uses the UDP port 269 [RFC5498] to carry protocol packets.
431  udpPacket->setSourcePort(DYMO_UDP_PORT);
432  udpPacket->setDestinationPort(DYMO_UDP_PORT);
433  udpPacket->setControlInfo(dynamic_cast<cObject *>(networkProtocolControlInfo));
434  sendUDPPacket(udpPacket, delay);
435 }
virtual void setTransportProtocol(short Transportprotocol)=0
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void sendUDPPacket(UDPPacket *packet, double delay)
Definition: DYMO.cc:392
IL3AddressType * addressType
Definition: DYMO.h:83
Definition: IPProtocolId_m.h:93
virtual INetworkProtocolControlInfo * createNetworkProtocolControlInfo() const =0
#define DYMO_UDP_PORT
Definition: DYMOdefs.h:28
void inet::dymo::DYMO::sendRERR ( RERR rerr)
private

Referenced by processRERR(), sendRERRForBrokenLink(), and sendRERRForUndeliverablePacket().

861 {
862  rerr->setBitLength(computeRERRBitLength(rerr));
863  EV_DETAIL << "Sending RERR: unreachableNodeCount = " << rerr->getUnreachableNodeArraySize() << endl;
865 }
IL3AddressType * addressType
Definition: DYMO.h:83
int computeRERRBitLength(RERR *rerr)
Definition: DYMO.cc:1018
virtual L3Address getLinkLocalManetRoutersMulticastAddress() const =0
void sendDYMOPacket(DYMOPacket *packet, const InterfaceEntry *interfaceEntry, const L3Address &nextHop, double delay)
Definition: DYMO.cc:416
void inet::dymo::DYMO::sendRERRForBrokenLink ( const InterfaceEntry interfaceEntry,
const L3Address nextHop 
)
private

Referenced by receiveSignal().

891 {
892  EV_DETAIL << "Sending RERR for broken link: nextHop = " << nextHop << endl;
893  // 8.3.2. Case 2: Broken Link
894  // The second case happens when the link breaks to an active downstream
895  // neighbor (i.e., the next hop of an active route). In this case,
896  // RERR_dest MUST be the multicast address LL-MANET-Routers, except when
897  // the optional feature of maintaining precursor lists is used as
898  // specified in Section 13.3. All Active, Idle and Expired routes that
899  // use the broken link MUST be marked as Broken. The set of
900  // UnreachableNodes is initialized by identifying those Active routes
901  // which use the broken link. For each such Active Route, Route.Dest is
902  // added to the set of Unreachable Nodes. After the Active Routes using
903  // the broken link have all been included as UnreachableNodes, idle
904  // routes MAY also be included, as long as the packet size of the RERR
905  // does not exceed the MTU of the physical medium.
906  // If the set of UnreachableNodes is empty, no RERR is generated.
907  // Otherwise, RERR_Gen generates a new RERR, and the address of each
908  // UnreachableNode (IP.DestinationAddress from a data packet or
909  // RREP.TargNode.Address) is inserted into an AddrBlock. If a prefix is
910  // known for the UnreachableNode.Address, it SHOULD be included.
911  // Otherwise, the UnreachableNode.Address is assumed to be a host
912  // address with a full length prefix. The value for each
913  // UnreachableNode's SeqNum (UnreachableNode.SeqNum) MUST be placed in a
914  // SeqNum AddrTLV. If none of UnreachableNode.Addr entries are
915  // associated with known prefix lengths, then the AddrBLK SHOULD NOT
916  // include any prefix-length information. Otherwise, for each
917  // UnreachableNode.Addr that does not have any associated prefix-length
918  // information, the prefix-length for that address MUST be assigned to
919  // zero.
920  std::vector<L3Address> unreachableAddresses;
921  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
922  IRoute *route = routingTable->getRoute(i);
923  if (route->getSource() == this) {
924  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
925  DYMORouteState routeState = getRouteState(routeData);
926  if (routeState != BROKEN && route->getInterface() == interfaceEntry && route->getNextHopAsGeneric() == nextHop) {
927  EV_DETAIL << "Marking route as broken: " << route << endl;
928  // TODO delete route, but save its data for later update
929  // route->setEnabled(false);
930  routeData->setBroken(true);
931  unreachableAddresses.push_back(route->getDestinationAsGeneric());
932  }
933  }
934  }
935  if (unreachableAddresses.size() == 0)
936  EV_DETAIL << "No unreachable address found" << endl;
937  else
938  sendRERR(createRERR(unreachableAddresses));
939 }
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IRoutingTable * routingTable
Definition: DYMO.h:85
Definition: DYMOdefs.h:41
RERR * createRERR(std::vector< L3Address > &addresses)
Definition: DYMO.cc:834
void sendRERR(RERR *rerr)
Definition: DYMO.cc:860
DYMORouteState getRouteState(DYMORouteData *routeData)
Definition: DYMO.cc:1265
DYMORouteState
Definition: DYMOdefs.h:37
void inet::dymo::DYMO::sendRERRForUndeliverablePacket ( const L3Address destination)
private
868 {
869  EV_DETAIL << "Sending RERR for undeliverable packet: destination = " << destination << endl;
870  // 8.3.1. Case 1: Undeliverable Packet
871  // The first case happens when the router receives a packet but does not
872  // have a valid route for the destination of the packet. In this case,
873  // there is exactly one UnreachableNode to be included in the RERR's
874  // AddrBlk. RERR_dest SHOULD be the multicast address LL-MANET-Routers,
875  // but RERR_Gen MAY instead set RERR_dest to be the next hop towards the
876  // source IP address of the packet which was undeliverable. In the
877  // latter case, the PktSource MsgTLV MUST be included, containing the
878  // the source IP address of the undeliverable packet. If a value for
879  // the UnreachableNode's SeqNum (UnreachableNode.SeqNum) is known, it
880  // MUST be placed in the RERR. Otherwise, if no Seqnum AddrTLV is
881  // included, all nodes handling the RERR will assume their route through
882  // RERR_Gen towards the UnreachableNode is no longer valid and flag
883  // those routes as broken. RERR_Gen MUST discard the packet or message
884  // that triggered generation of the RERR.
885  std::vector<L3Address> unreachableAddresses;
886  unreachableAddresses.push_back(destination);
887  sendRERR(createRERR(unreachableAddresses));
888 }
RERR * createRERR(std::vector< L3Address > &addresses)
Definition: DYMO.cc:834
void sendRERR(RERR *rerr)
Definition: DYMO.cc:860
void inet::dymo::DYMO::sendRREP ( RREP rrep)
private

Referenced by processRREP(), and processRREQ().

762 {
763  const L3Address& target = rrep->getTargetNode().getAddress();
764  const L3Address& originator = rrep->getOriginatorNode().getAddress();
765  rrep->setBitLength(computeRREPBitLength(rrep));
766  EV_DETAIL << "Sending broadcast RREP: originator = " << originator << ", target = " << target << endl;
768 }
int computeRREPBitLength(RREP *rrep)
Definition: DYMO.cc:825
IL3AddressType * addressType
Definition: DYMO.h:83
virtual L3Address getLinkLocalManetRoutersMulticastAddress() const =0
void sendDYMOPacket(DYMOPacket *packet, const InterfaceEntry *interfaceEntry, const L3Address &nextHop, double delay)
Definition: DYMO.cc:416
void inet::dymo::DYMO::sendRREP ( RREP rrep,
IRoute route 
)
private
771 {
772  const L3Address& target = rrep->getTargetNode().getAddress();
773  const L3Address& originator = rrep->getOriginatorNode().getAddress();
774  const L3Address& nextHop = route->getNextHopAsGeneric();
775  rrep->setBitLength(computeRREPBitLength(rrep));
776  EV_DETAIL << "Sending unicast RREP: originator = " << originator << ", target = " << target << ", nextHop = " << nextHop << endl;
777  sendDYMOPacket(rrep, route->getInterface(), nextHop, 0);
778 }
int computeRREPBitLength(RREP *rrep)
Definition: DYMO.cc:825
void sendDYMOPacket(DYMOPacket *packet, const InterfaceEntry *interfaceEntry, const L3Address &nextHop, double delay)
Definition: DYMO.cc:416
void inet::dymo::DYMO::sendRREQ ( RREQ rreq)
private

Referenced by processRREQ(), retryRouteDiscovery(), and startRouteDiscovery().

651 {
652  const L3Address& target = rreq->getTargetNode().getAddress();
653  const L3Address& originator = rreq->getOriginatorNode().getAddress();
654  rreq->setBitLength(computeRREQBitLength(rreq));
655  EV_DETAIL << "Sending RREQ: originator = " << originator << ", target = " << target << endl;
657 }
int computeRREQBitLength(RREQ *rreq)
Definition: DYMO.cc:706
IL3AddressType * addressType
Definition: DYMO.h:83
simtime_t maxJitter
Definition: DYMO.h:75
virtual L3Address getLinkLocalManetRoutersMulticastAddress() const =0
void sendDYMOPacket(DYMOPacket *packet, const InterfaceEntry *interfaceEntry, const L3Address &nextHop, double delay)
Definition: DYMO.cc:416
void inet::dymo::DYMO::sendUDPPacket ( UDPPacket packet,
double  delay 
)
private

Referenced by sendDYMOPacket().

393 {
394  if (delay == 0)
395  send(packet, "ipOut");
396  else
397  sendDelayed(packet, delay, "ipOut");
398 }
void inet::dymo::DYMO::startRouteDiscovery ( const L3Address target)
private

Referenced by ensureRouteForDatagram(), and processRREQHolddownTimer().

195 {
196  EV_INFO << "Starting route discovery: originator = " << getSelfAddress() << ", target = " << target << endl;
197  ASSERT(!hasOngoingRouteDiscovery(target));
198  sendRREQ(createRREQ(target, 0));
200 }
bool hasOngoingRouteDiscovery(const L3Address &target)
Definition: DYMO.cc:232
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void sendRREQ(RREQ *rreq)
Definition: DYMO.cc:650
void scheduleRREQWaitRREPTimer(RREQWaitRREPTimer *message)
Definition: DYMO.cc:307
RREQWaitRREPTimer * createRREQWaitRREPTimer(const L3Address &target, int retryCount)
Definition: DYMO.cc:299
RREQ * createRREQ(const L3Address &target, int retryCount)
Definition: DYMO.cc:594
void inet::dymo::DYMO::updateRoute ( RteMsg rteMsg,
AddressBlock addressBlock,
IRoute route 
)
private

Referenced by createRoute(), and updateRoutes().

1133 {
1134  // 6.2. Applying Route Updates To Route Table Entries
1135  INetworkProtocolControlInfo *networkProtocolControlInfo = check_and_cast<INetworkProtocolControlInfo *>(rteMsg->getControlInfo());
1136  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
1137  // Route.Address := RteMsg.Addr
1138  const L3Address& address = addressBlock.getAddress();
1139  route->setDestination(address);
1140  // If (RteMsg.PfxLen != 0), then Route.PfxLen := RteMsg.PfxLen
1141  route->setPrefixLength(addressBlock.getPrefixLength());
1142  // Route.SeqNum := RteMsg.SeqNum
1143  DYMOSequenceNumber sequenceNumber = addressBlock.getSequenceNumber();
1144  routeData->setSequenceNumber(sequenceNumber);
1146  // Route.NextHopAddress := IP.SourceAddress (i.e., an address of the node from which the RteMsg was received)
1147  // note that DYMO packets are not routed on the IP level, so we can use the source address here
1148  route->setNextHop(networkProtocolControlInfo->getSourceAddress());
1149  // Route.NextHopInterface is set to the interface on which RteMsg was received
1150  InterfaceEntry *interfaceEntry = interfaceTable->getInterfaceById(networkProtocolControlInfo->getInterfaceId());
1151  if (interfaceEntry)
1152  route->setInterface(interfaceEntry);
1153  // Route.Broken flag := FALSE
1154  routeData->setBroken(false);
1155  // If RteMsg.MetricType is included, then Route.MetricType := RteMsg.MetricType. Otherwise, Route.MetricType := DEFAULT_METRIC_TYPE.
1156  // Route.MetricType := RteMsg.MetricType
1157  if (addressBlock.getHasMetricType())
1158  routeData->setMetricType(addressBlock.getMetricType());
1159  else
1160  routeData->setMetricType(HOP_COUNT);
1161  // Route.Metric := RteMsg.Metric
1162  route->setMetric(addressBlock.getMetric());
1163  // Route.LastUsed := Current_Time
1164  routeData->setLastUsed(simTime());
1165  // If RteMsg.VALIDITY_TIME is not included, then Route.ExpirationTime := MAXTIME, otherwise Route.ExpirationTime := Current_Time + RteMsg.VALIDITY_TIME
1166  if (addressBlock.getHasValidityTime())
1167  routeData->setExpirationTime(simTime() + addressBlock.getValidityTime());
1168  else
1169  routeData->setExpirationTime(SimTime::getMaxTime());
1171 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
void scheduleExpungeTimer()
Definition: DYMO.cc:1202
Definition: DYMOdefs.h:34
std::map< L3Address, DYMOSequenceNumber > targetAddressToSequenceNumber
Definition: DYMO.h:91
DYMOSequenceNumber sequenceNumber
Definition: DYMO.h:90
uint32_t DYMOSequenceNumber
Definition: DYMOdefs.h:30
IInterfaceTable * interfaceTable
Definition: DYMO.h:84
void inet::dymo::DYMO::updateRoutes ( RteMsg rteMsg,
AddressBlock addressBlock 
)
private

Referenced by processRteMsg().

1070 {
1071  const L3Address& address = addressBlock.getAddress();
1072  if (address == getSelfAddress())
1073  // we don't need to manage routes for our own address
1074  return;
1075  else {
1076  // 6.1. Evaluating Incoming Routing Information
1077  // HandRtr searches its route table to see if there is a route table
1078  // entry with the same MetricType of the RteMsg, matching RteMsg.Addr.
1079  IRoute *route = nullptr;
1080  for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1081  IRoute *routeCandidate = routingTable->getRoute(i);
1082  if (routeCandidate->getSource() == this) {
1083  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(routeCandidate->getProtocolData());
1084  if (routeCandidate->getDestinationAsGeneric() == address && routeData->getMetricType() == addressBlock.getMetricType()) {
1085  route = routeCandidate;
1086  break;
1087  }
1088  }
1089  }
1090  // If not, HandRtr creates a route table entry for RteMsg.Addr as described
1091  // in Section 6.2. Otherwise, HandRtr compares the incoming routing information
1092  // in RteMsg against the already stored routing information in the route table
1093  // entry (Route) for RteMsg.Addr, as described below.
1094  if (!route) {
1095  IRoute *route = createRoute(rteMsg, addressBlock);
1096  EV_DETAIL << "Adding new route: " << route << endl;
1097  routingTable->addRoute(route);
1098  }
1099  else {
1100  DYMORouteData *routeData = check_and_cast<DYMORouteData *>(route->getProtocolData());
1101  // Offers improvement if
1102  // (RteMsg.SeqNum > Route.SeqNum) OR
1103  // {(RteMsg.SeqNum == Route.SeqNum) AND
1104  // [(RteMsg.Metric < Route.Metric) OR
1105  // ((Route.Broken == TRUE) && LoopFree (RteMsg, Route))]} if
1106  if ((addressBlock.getSequenceNumber() > routeData->getSequenceNumber()) ||
1107  (addressBlock.getSequenceNumber() == routeData->getSequenceNumber() && addressBlock.getMetric() < route->getMetric()) ||
1108  (routeData->getBroken() && isLoopFree(rteMsg, route)))
1109  {
1110  // it's more recent, or it's not stale and is shorter, or it can safely repair a broken route
1111  // TODO: should we simply update the route instead? only if the route change notification is sent exactly once
1112  routingTable->removeRoute(route);
1113  EV_DETAIL << "Updating existing route: " << route << endl;
1114  updateRoute(rteMsg, addressBlock, route);
1115  EV_DETAIL << "Route updated: " << route << endl;
1116  routingTable->addRoute(route);
1117  }
1118  }
1119  }
1120 }
virtual IRoute * getRoute(int k) const =0
Returns the kth route.
virtual IRoute * removeRoute(IRoute *entry)=0
Removes the given route from the routing table, and returns it.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
bool isLoopFree(RteMsg *rteMsg, IRoute *route)
Definition: DYMO.cc:1185
virtual void addRoute(IRoute *entry)=0
Adds a route to the routing table.
IRoutingTable * routingTable
Definition: DYMO.h:85
L3Address getSelfAddress()
Definition: DYMO.cc:1311
void updateRoute(RteMsg *rteMsg, AddressBlock &addressBlock, IRoute *route)
Definition: DYMO.cc:1132
IRoute * createRoute(RteMsg *rteMsg, AddressBlock &addressBlock)
Definition: DYMO.cc:1122

Member Data Documentation

double inet::dymo::DYMO::activeInterval
private

Referenced by getRouteState(), and initialize().

bool inet::dymo::DYMO::appendInformation
private
int inet::dymo::DYMO::bufferSizeBytes
private

Referenced by initialize().

int inet::dymo::DYMO::bufferSizePackets
private

Referenced by initialize().

std::vector<std::pair<L3Address, int> > inet::dymo::DYMO::clientAddressAndPrefixLengthPairs
private

Referenced by initialize(), and isClientAddress().

const char* inet::dymo::DYMO::clientAddresses
private

Referenced by initialize().

int inet::dymo::DYMO::discoveryAttemptsMax
private
cMessage* inet::dymo::DYMO::expungeTimer
private
cModule* inet::dymo::DYMO::host
private

Referenced by initialize().

const char* inet::dymo::DYMO::interfaces
private

Referenced by configureInterfaces(), and initialize().

IInterfaceTable* inet::dymo::DYMO::interfaceTable
private
int inet::dymo::DYMO::maxHopCount
private

Referenced by initialize(), and permissibleRteMsg().

int inet::dymo::DYMO::maxHopLimit
private

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

double inet::dymo::DYMO::maxIdleTime
private

Referenced by getRouteState(), and initialize().

simtime_t inet::dymo::DYMO::maxJitter
private

Referenced by initialize(), and sendRREQ().

double inet::dymo::DYMO::maxSequenceNumberLifetime
private
int inet::dymo::DYMO::minHopLimit
private

Referenced by createRREQ(), and initialize().

INetfilter* inet::dymo::DYMO::networkProtocol
private
NodeStatus* inet::dymo::DYMO::nodeStatus
private

Referenced by initialize(), and isNodeUp().

double inet::dymo::DYMO::routeRREQWaitTime
private
double inet::dymo::DYMO::rreqHolddownTime
private
bool inet::dymo::DYMO::sendIntermediateRREP
private

Referenced by initialize().

DYMOSequenceNumber inet::dymo::DYMO::sequenceNumber
private
std::multimap<L3Address, INetworkDatagram *> inet::dymo::DYMO::targetAddressToDelayedPackets
private
std::map<L3Address, DYMOSequenceNumber> inet::dymo::DYMO::targetAddressToSequenceNumber
private
bool inet::dymo::DYMO::useMulticastRREP
private

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