· 8 years ago · Jan 31, 2018, 08:46 AM
1#include "inet/routing/aodv/AODVRouting.h"
2#include "inet/networklayer/ipv4/ICMPMessage.h"
3#include "inet/networklayer/ipv4/IPv4Route.h"
4
5#ifdef WITH_IDEALWIRELESS
6#include "inet/linklayer/ideal/IdealMacFrame_m.h"
7#endif // ifdef WITH_IDEALWIRELESS
8
9#ifdef WITH_IEEE80211
10#include "inet/linklayer/ieee80211/mac/Ieee80211Frame_m.h"
11#endif // ifdef WITH_IEEE80211
12
13#ifdef WITH_CSMA
14#include "inet/linklayer/csma/CSMAFrame_m.h"
15#endif // ifdef WITH_CSMA
16
17#ifdef WITH_CSMACA
18#include "inet/linklayer/csmaca/CsmaCaMacFrame_m.h"
19#endif // ifdef WITH_CSMA
20
21#ifdef WITH_LMAC
22#include "inet/linklayer/lmac/LMacFrame_m.h"
23#endif // ifdef WITH_LMAC
24
25#ifdef WITH_BMAC
26#include "inet/linklayer/bmac/BMacFrame_m.h"
27#endif // ifdef WITH_BMAC
28
29#include "inet/networklayer/common/IPSocket.h"
30#include "inet/transportlayer/contract/udp/UDPControlInfo.h"
31#include "inet/common/ModuleAccess.h"
32#include "inet/common/lifecycle/NodeOperations.h"
33
34namespace inet {
35
36Define_Module(AODVRouting);
37
38void AODVRouting::initialize(int stage)
39{
40 if (stage == INITSTAGE_LOCAL) {
41 lastBroadcastTime = SIMTIME_ZERO;
42 rebootTime = SIMTIME_ZERO;
43 rreqId = sequenceNum = 0;
44 rreqCount = rerrCount = 0;
45 host = getContainingNode(this);
46 routingTable = getModuleFromPar<IRoutingTable>(par("routingTableModule"), this);
47 interfaceTable = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
48 networkProtocol = getModuleFromPar<INetfilter>(par("networkProtocolModule"), this);
49
50 aodvUDPPort = par("udpPort");
51 askGratuitousRREP = par("askGratuitousRREP");
52 useHelloMessages = par("useHelloMessages");
53 activeRouteTimeout = par("activeRouteTimeout");
54 helloInterval = par("helloInterval");
55 allowedHelloLoss = par("allowedHelloLoss");
56 netDiameter = par("netDiameter");
57 nodeTraversalTime = par("nodeTraversalTime");
58 rerrRatelimit = par("rerrRatelimit");
59 rreqRetries = par("rreqRetries");
60 rreqRatelimit = par("rreqRatelimit");
61 timeoutBuffer = par("timeoutBuffer");
62 ttlStart = par("ttlStart");
63 ttlIncrement = par("ttlIncrement");
64 ttlThreshold = par("ttlThreshold");
65 localAddTTL = par("localAddTTL");
66 jitterPar = &par("jitter");
67 periodicJitter = &par("periodicJitter");
68
69 myRouteTimeout = par("myRouteTimeout");
70 deletePeriod = par("deletePeriod");
71 blacklistTimeout = par("blacklistTimeout");
72 netTraversalTime = par("netTraversalTime");
73 nextHopWait = par("nextHopWait");
74 pathDiscoveryTime = par("pathDiscoveryTime");
75 }
76 else if (stage == INITSTAGE_ROUTING_PROTOCOLS) {
77 NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(host->getSubmodule("status"));
78 isOperational = !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
79
80 addressType = getSelfIPAddress().getAddressType();
81 IPSocket socket(gate("ipOut"));
82 socket.registerProtocol(IP_PROT_MANET);
83 networkProtocol->registerHook(0, this);
84 host->subscribe(NF_LINK_BREAK, this);
85
86 if (useHelloMessages) {
87 helloMsgTimer = new cMessage("HelloMsgTimer");
88
89 // RFC 5148:
90 // Jitter SHOULD be applied by reducing this delay by a random amount, so that
91 // the delay between consecutive transmissions of messages of the same type is
92 // equal to (MESSAGE_INTERVAL - jitter), where jitter is the random value.
93 if (isOperational)
94 scheduleAt(simTime() + helloInterval - periodicJitter->doubleValue(), helloMsgTimer);
95 }
96
97 expungeTimer = new cMessage("ExpungeTimer");
98 counterTimer = new cMessage("CounterTimer");
99 rrepAckTimer = new cMessage("RREPACKTimer");
100 blacklistTimer = new cMessage("BlackListTimer");
101
102 if (isOperational)
103 scheduleAt(simTime() + 1, counterTimer);
104 }
105}
106
107void AODVRouting::handleMessage(cMessage *msg)
108{
109 if (!isOperational) {
110 if (msg->isSelfMessage())
111 throw cRuntimeError("Model error: self msg '%s' received when isOperational is false", msg->getName());
112
113 EV_ERROR << "Application is turned off, dropping '" << msg->getName() << "' message\n";
114 delete msg;
115 return;
116 }
117
118 if (msg->isSelfMessage()) {
119 if (dynamic_cast<WaitForRREP *>(msg))
120 handleWaitForRREP((WaitForRREP *)msg);
121 else if (msg == helloMsgTimer)
122 sendHelloMessagesIfNeeded();
123 else if (msg == expungeTimer)
124 expungeRoutes();
125 else if (msg == counterTimer) {
126 rreqCount = rerrCount = 0;
127 scheduleAt(simTime() + 1, counterTimer);
128 }
129 else if (msg == rrepAckTimer)
130 handleRREPACKTimer();
131 else if (msg == blacklistTimer)
132 handleBlackListTimer();
133 else
134 throw cRuntimeError("Unknown self message");
135 }
136 else if (ICMPMessage *icmpPacket = dynamic_cast<ICMPMessage *>(msg)) {
137 // ICMP packet arrived, dropped
138 delete icmpPacket;
139 }
140 else {
141 UDPPacket *udpPacket = check_and_cast<UDPPacket *>(msg);
142 AODVControlPacket *ctrlPacket = check_and_cast<AODVControlPacket *>(udpPacket->decapsulate());
143 INetworkProtocolControlInfo *udpProtocolCtrlInfo = check_and_cast<INetworkProtocolControlInfo *>(udpPacket->getControlInfo());
144 L3Address sourceAddr = udpProtocolCtrlInfo->getSourceAddress();
145 unsigned int arrivalPacketTTL = udpProtocolCtrlInfo->getHopLimit();
146
147 switch (ctrlPacket->getPacketType()) {
148 case RREQ:
149 handleRREQ(check_and_cast<AODVRREQ *>(ctrlPacket), sourceAddr, arrivalPacketTTL);
150 break;
151
152 case RREP:
153 handleRREP(check_and_cast<AODVRREP *>(ctrlPacket), sourceAddr);
154 break;
155
156 case RERR:
157 handleRERR(check_and_cast<AODVRERR *>(ctrlPacket), sourceAddr);
158 break;
159
160 case RREPACK:
161 handleRREPACK(check_and_cast<AODVRREPACK *>(ctrlPacket), sourceAddr);
162 break;
163
164 default:
165 throw cRuntimeError("AODV Control Packet arrived with undefined packet type: %d", ctrlPacket->getPacketType());
166 }
167 delete udpPacket;
168 }
169}
170
171INetfilter::IHook::Result AODVRouting::ensureRouteForDatagram(INetworkDatagram *datagram)
172{
173 Enter_Method("datagramPreRoutingHook");
174 const L3Address& destAddr = datagram->getDestinationAddress();
175 const L3Address& sourceAddr = datagram->getSourceAddress();
176
177 if (destAddr.isBroadcast() || routingTable->isLocalAddress(destAddr) || destAddr.isMulticast())
178 return ACCEPT;
179 else {
180 EV_INFO << "Finding route for source " << sourceAddr << " with destination " << destAddr << endl;
181 IRoute *route = routingTable->findBestMatchingRoute(destAddr);
182 AODVRouteData *routeData = route ? dynamic_cast<AODVRouteData *>(route->getProtocolData()) : nullptr;
183 bool isActive = routeData && routeData->isActive();
184 if (isActive && !route->getNextHopAsGeneric().isUnspecified()) {
185 EV_INFO << "Active route found: " << route << endl;
186
187 // Each time a route is used to forward a data packet, its Active Route
188 // Lifetime field of the source, destination and the next hop on the
189 // path to the destination is updated to be no less than the current
190 // time plus ACTIVE_ROUTE_TIMEOUT.
191
192 updateValidRouteLifeTime(destAddr, simTime() + activeRouteTimeout);
193 updateValidRouteLifeTime(route->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
194
195 return ACCEPT;
196 }
197 else if (sourceAddr.isUnspecified() || routingTable->isLocalAddress(sourceAddr)) {
198 bool isInactive = routeData && !routeData->isActive();
199 // A node disseminates a RREQ when it determines that it needs a route
200 // to a destination and does not have one available. This can happen if
201 // the destination is previously unknown to the node, or if a previously
202 // valid route to the destination expires or is marked as invalid.
203
204 EV_INFO << (isInactive ? "Inactive" : "Missing") << " route for destination " << destAddr << endl;
205
206 delayDatagram(datagram);
207
208 if (!hasOngoingRouteDiscovery(destAddr)) {
209 // When a new route to the same destination is required at a later time
210 // (e.g., upon route loss), the TTL in the RREQ IP header is initially
211 // set to the Hop Count plus TTL_INCREMENT.
212 if (isInactive)
213 startRouteDiscovery(destAddr, route->getMetric() + ttlIncrement);
214 else
215 startRouteDiscovery(destAddr);
216 }
217 else
218 EV_DETAIL << "Route discovery is in progress, originator " << getSelfIPAddress() << " target " << destAddr << endl;
219
220 return QUEUE;
221 }
222 else
223 return ACCEPT;
224 }
225}
226
227AODVRouting::AODVRouting()
228{
229}
230
231bool AODVRouting::hasOngoingRouteDiscovery(const L3Address& target)
232{
233 return waitForRREPTimers.find(target) != waitForRREPTimers.end();
234}
235
236void AODVRouting::startRouteDiscovery(const L3Address& target, unsigned timeToLive)
237{
238 EV_INFO << "Starting route discovery with originator " << getSelfIPAddress() << " and destination " << target << endl;
239 ASSERT(!hasOngoingRouteDiscovery(target));
240 AODVRREQ *rreq = createRREQ(target);
241 addressToRreqRetries[target] = 0;
242 sendRREQ(rreq, addressType->getBroadcastAddress(), timeToLive);
243}
244
245L3Address AODVRouting::getSelfIPAddress() const
246{
247 return routingTable->getRouterIdAsGeneric();
248}
249
250void AODVRouting::delayDatagram(INetworkDatagram *datagram)
251{
252 EV_DETAIL << "Queuing datagram, source " << datagram->getSourceAddress() << ", destination " << datagram->getDestinationAddress() << endl;
253 const L3Address& target = datagram->getDestinationAddress();
254 targetAddressToDelayedPackets.insert(std::pair<L3Address, INetworkDatagram *>(target, datagram));
255}
256
257void AODVRouting::sendRREQ(AODVRREQ *rreq, const L3Address& destAddr, unsigned int timeToLive)
258{
259 // In an expanding ring search, the originating node initially uses a TTL =
260 // TTL_START in the RREQ packet IP header and sets the timeout for
261 // receiving a RREP to RING_TRAVERSAL_TIME milliseconds.
262 // RING_TRAVERSAL_TIME is calculated as described in section 10. The
263 // TTL_VALUE used in calculating RING_TRAVERSAL_TIME is set equal to the
264 // value of the TTL field in the IP header. If the RREQ times out
265 // without a corresponding RREP, the originator broadcasts the RREQ
266 // again with the TTL incremented by TTL_INCREMENT. This continues
267 // until the TTL set in the RREQ reaches TTL_THRESHOLD, beyond which a
268 // TTL = NET_DIAMETER is used for each attempt.
269
270 if (rreqCount >= rreqRatelimit) {
271 EV_WARN << "A node should not originate more than RREQ_RATELIMIT RREQ messages per second. Canceling sending RREQ" << endl;
272 delete rreq;
273 return;
274 }
275
276 auto rrepTimer = waitForRREPTimers.find(rreq->getDestAddr());
277 WaitForRREP *rrepTimerMsg = nullptr;
278 if (rrepTimer != waitForRREPTimers.end()) {
279 rrepTimerMsg = rrepTimer->second;
280 unsigned int lastTTL = rrepTimerMsg->getLastTTL();
281 rrepTimerMsg->setDestAddr(rreq->getDestAddr());
282
283 // The Hop Count stored in an invalid routing table entry indicates the
284 // last known hop count to that destination in the routing table. When
285 // a new route to the same destination is required at a later time
286 // (e.g., upon route loss), the TTL in the RREQ IP header is initially
287 // set to the Hop Count plus TTL_INCREMENT. Thereafter, following each
288 // timeout the TTL is incremented by TTL_INCREMENT until TTL =
289 // TTL_THRESHOLD is reached. Beyond this TTL = NET_DIAMETER is used.
290 // Once TTL = NET_DIAMETER, the timeout for waiting for the RREP is set
291 // to NET_TRAVERSAL_TIME, as specified in section 6.3.
292
293 if (timeToLive != 0) {
294 rrepTimerMsg->setLastTTL(timeToLive);
295 rrepTimerMsg->setFromInvalidEntry(true);
296 cancelEvent(rrepTimerMsg);
297 }
298 else if (lastTTL + ttlIncrement < ttlThreshold) {
299 ASSERT(!rrepTimerMsg->isScheduled());
300 timeToLive = lastTTL + ttlIncrement;
301 rrepTimerMsg->setLastTTL(lastTTL + ttlIncrement);
302 }
303 else {
304 ASSERT(!rrepTimerMsg->isScheduled());
305 timeToLive = netDiameter;
306 rrepTimerMsg->setLastTTL(netDiameter);
307 }
308 }
309 else {
310 rrepTimerMsg = new WaitForRREP();
311 waitForRREPTimers[rreq->getDestAddr()] = rrepTimerMsg;
312 ASSERT(hasOngoingRouteDiscovery(rreq->getDestAddr()));
313
314 timeToLive = ttlStart;
315 rrepTimerMsg->setLastTTL(ttlStart);
316 rrepTimerMsg->setFromInvalidEntry(false);
317 rrepTimerMsg->setDestAddr(rreq->getDestAddr());
318 }
319
320 // Each time, the timeout for receiving a RREP is RING_TRAVERSAL_TIME.
321 simtime_t ringTraversalTime = 2.0 * nodeTraversalTime * (timeToLive + timeoutBuffer);
322 scheduleAt(simTime() + ringTraversalTime, rrepTimerMsg);
323
324 EV_INFO << "Sending a Route Request with target " << rreq->getDestAddr() << " and TTL= " << timeToLive << endl;
325 sendAODVPacket(rreq, destAddr, timeToLive, jitterPar->doubleValue());
326 rreqCount++;
327}
328
329void AODVRouting::sendRREP(AODVRREP *rrep, const L3Address& destAddr, unsigned int timeToLive)
330{
331 EV_INFO << "Sending Route Reply to " << destAddr << endl;
332
333 // When any node transmits a RREP, the precursor list for the
334 // corresponding destination node is updated by adding to it
335 // the next hop node to which the RREP is forwarded.
336
337 IRoute *destRoute = routingTable->findBestMatchingRoute(destAddr);
338 const L3Address& nextHop = destRoute->getNextHopAsGeneric();
339 AODVRouteData *destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
340 destRouteData->addPrecursor(nextHop);
341
342 // The node we received the Route Request for is our neighbor,
343 // it is probably an unidirectional link
344 if (destRoute->getMetric() == 1) {
345 // It is possible that a RREP transmission may fail, especially if the
346 // RREQ transmission triggering the RREP occurs over a unidirectional
347 // link.
348
349 rrep->setAckRequiredFlag(true);
350
351 // when a node detects that its transmission of a RREP message has failed,
352 // it remembers the next-hop of the failed RREP in a "blacklist" set.
353
354 failedNextHop = nextHop;
355
356 if (rrepAckTimer->isScheduled())
357 cancelEvent(rrepAckTimer);
358
359 scheduleAt(simTime() + nextHopWait, rrepAckTimer);
360 }
361 sendAODVPacket(rrep, nextHop, timeToLive, 0);
362}
363
364AODVRREQ *AODVRouting::createRREQ(const L3Address& destAddr)
365{
366 AODVRREQ *rreqPacket = new AODVRREQ("AODV-RREQ");
367
368 rreqPacket->setGratuitousRREPFlag(askGratuitousRREP);
369 IRoute *lastKnownRoute = routingTable->findBestMatchingRoute(destAddr);
370
371 rreqPacket->setPacketType(RREQ);
372
373 // The Originator Sequence Number in the RREQ message is the
374 // node's own sequence number, which is incremented prior to
375 // insertion in a RREQ.
376 sequenceNum++;
377
378 rreqPacket->setOriginatorSeqNum(sequenceNum);
379
380 if (lastKnownRoute && lastKnownRoute->getSource() == this) {
381 // The Destination Sequence Number field in the RREQ message is the last
382 // known destination sequence number for this destination and is copied
383 // from the Destination Sequence Number field in the routing table.
384
385 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(lastKnownRoute->getProtocolData());
386 if (routeData && routeData->hasValidDestNum()) {
387 rreqPacket->setDestSeqNum(routeData->getDestSeqNum());
388 rreqPacket->setUnknownSeqNumFlag(false);
389 }
390 else
391 rreqPacket->setUnknownSeqNumFlag(true);
392 }
393 else
394 rreqPacket->setUnknownSeqNumFlag(true); // If no sequence number is known, the unknown sequence number flag MUST be set.
395
396 rreqPacket->setOriginatorAddr(getSelfIPAddress());
397 rreqPacket->setDestAddr(destAddr);
398
399 // The RREQ ID field is incremented by one from the last RREQ ID used
400 // by the current node. Each node maintains only one RREQ ID.
401 rreqId++;
402 rreqPacket->setRreqId(rreqId);
403
404 // The Hop Count field is set to zero.
405 rreqPacket->setHopCount(0);
406
407 // Before broadcasting the RREQ, the originating node buffers the RREQ
408 // ID and the Originator IP address (its own address) of the RREQ for
409 // PATH_DISCOVERY_TIME.
410 // In this way, when the node receives the packet again from its neighbors,
411 // it will not reprocess and re-forward the packet.
412
413 RREQIdentifier rreqIdentifier(getSelfIPAddress(), rreqId);
414 rreqsArrivalTime[rreqIdentifier] = simTime();
415 rreqPacket->setByteLength(24);
416 return rreqPacket;
417}
418
419AODVRREP *AODVRouting::createRREP(AODVRREQ *rreq, IRoute *destRoute, IRoute *originatorRoute, const L3Address& lastHopAddr)
420{
421 AODVRREP *rrep = new AODVRREP("AODV-RREP");
422 rrep->setPacketType(RREP);
423
424 // When generating a RREP message, a node copies the Destination IP
425 // Address and the Originator Sequence Number from the RREQ message into
426 // the corresponding fields in the RREP message.
427
428 rrep->setDestAddr(rreq->getDestAddr());
429 rrep->setOriginatorSeqNum(rreq->getOriginatorSeqNum());
430
431 // OriginatorAddr = The IP address of the node which originated the RREQ
432 // for which the route is supplied.
433 rrep->setOriginatorAddr(rreq->getOriginatorAddr());
434
435 // Processing is slightly different, depending on whether the node is
436 // itself the requested destination (see section 6.6.1), or instead
437 // if it is an intermediate node with an fresh enough route to the destination
438 // (see section 6.6.2).
439
440 if (rreq->getDestAddr() == getSelfIPAddress()) { // node is itself the requested destination
441 // If the generating node is the destination itself, it MUST increment
442 // its own sequence number by one if the sequence number in the RREQ
443 // packet is equal to that incremented value.
444
445 if (!rreq->getUnknownSeqNumFlag() && sequenceNum + 1 == rreq->getDestSeqNum())
446 sequenceNum++;
447
448 // The destination node places its (perhaps newly incremented)
449 // sequence number into the Destination Sequence Number field of
450 // the RREP,
451 rrep->setDestSeqNum(sequenceNum);
452
453 // and enters the value zero in the Hop Count field
454 // of the RREP.
455 rrep->setHopCount(0);
456
457 // The destination node copies the value MY_ROUTE_TIMEOUT
458 // into the Lifetime field of the RREP.
459 rrep->setLifeTime(myRouteTimeout);
460 }
461 else { // intermediate node
462 // it copies its known sequence number for the destination into
463 // the Destination Sequence Number field in the RREP message.
464 AODVRouteData *destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
465 AODVRouteData *originatorRouteData = check_and_cast<AODVRouteData *>(originatorRoute->getProtocolData());
466 rrep->setDestSeqNum(destRouteData->getDestSeqNum());
467
468 // The intermediate node updates the forward route entry by placing the
469 // last hop node (from which it received the RREQ, as indicated by the
470 // source IP address field in the IP header) into the precursor list for
471 // the forward route entry -- i.e., the entry for the Destination IP
472 // Address.
473 destRouteData->addPrecursor(lastHopAddr);
474
475 // The intermediate node also updates its route table entry
476 // for the node originating the RREQ by placing the next hop towards the
477 // destination in the precursor list for the reverse route entry --
478 // i.e., the entry for the Originator IP Address field of the RREQ
479 // message data.
480
481 originatorRouteData->addPrecursor(destRoute->getNextHopAsGeneric());
482
483 // The intermediate node places its distance in hops from the
484 // destination (indicated by the hop count in the routing table)
485 // Hop Count field in the RREP.
486
487 rrep->setHopCount(destRoute->getMetric());
488
489 // The Lifetime field of the RREP is calculated by subtracting the
490 // current time from the expiration time in its route table entry.
491
492 rrep->setLifeTime(destRouteData->getLifeTime() - simTime());
493 }
494
495 rrep->setByteLength(20);
496 return rrep;
497}
498
499AODVRREP *AODVRouting::createGratuitousRREP(AODVRREQ *rreq, IRoute *originatorRoute)
500{
501 ASSERT(originatorRoute != nullptr);
502 AODVRREP *grrep = new AODVRREP("AODV-GRREP");
503 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(originatorRoute->getProtocolData());
504
505 // Hop Count The Hop Count as indicated in the
506 // node's route table entry for the
507 // originator
508 //
509 // Destination IP Address The IP address of the node that
510 // originated the RREQ
511 //
512 // Destination Sequence Number The Originator Sequence Number from
513 // the RREQ
514 //
515 // Originator IP Address The IP address of the Destination
516 // node in the RREQ
517 //
518 // Lifetime The remaining lifetime of the route
519 // towards the originator of the RREQ,
520 // as known by the intermediate node.
521
522 grrep->setPacketType(RREP);
523 grrep->setHopCount(originatorRoute->getMetric());
524 grrep->setDestAddr(rreq->getOriginatorAddr());
525 grrep->setDestSeqNum(rreq->getOriginatorSeqNum());
526 grrep->setOriginatorAddr(rreq->getDestAddr());
527 grrep->setLifeTime(routeData->getLifeTime());
528
529 grrep->setByteLength(20);
530 return grrep;
531}
532
533void AODVRouting::handleRREP(AODVRREP *rrep, const L3Address& sourceAddr)
534{
535 EV_INFO << "AODV Route Reply arrived with source addr: " << sourceAddr << " originator addr: " << rrep->getOriginatorAddr()
536 << " destination addr: " << rrep->getDestAddr() << endl;
537
538 if (rrep->getOriginatorAddr().isUnspecified()) {
539 EV_INFO << "This Route Reply is a Hello Message" << endl;
540 handleHelloMessage(rrep);
541 delete rrep;
542 return;
543 }
544 // When a node receives a RREP message, it searches (using longest-
545 // prefix matching) for a route to the previous hop.
546
547 // If needed, a route is created for the previous hop,
548 // but without a valid sequence number (see section 6.2)
549
550 IRoute *previousHopRoute = routingTable->findBestMatchingRoute(sourceAddr);
551
552 if (!previousHopRoute || previousHopRoute->getSource() != this) {
553 // create without valid sequence number
554 previousHopRoute = createRoute(sourceAddr, sourceAddr, 1, false, rrep->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
555 }
556 else
557 updateRoutingTable(previousHopRoute, sourceAddr, 1, false, rrep->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
558
559 // Next, the node then increments the hop count value in the RREP by one,
560 // to account for the new hop through the intermediate node
561 unsigned int newHopCount = rrep->getHopCount() + 1;
562 rrep->setHopCount(newHopCount);
563
564 // Then the forward route for this destination is created if it does not
565 // already exist.
566
567 IRoute *destRoute = routingTable->findBestMatchingRoute(rrep->getDestAddr());
568 AODVRouteData *destRouteData = nullptr;
569 simtime_t lifeTime = rrep->getLifeTime();
570 unsigned int destSeqNum = rrep->getDestSeqNum();
571
572 if (destRoute && destRoute->getSource() == this) { // already exists
573 destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
574 // Upon comparison, the existing entry is updated only in the following circumstances:
575
576 // (i) the sequence number in the routing table is marked as
577 // invalid in route table entry.
578
579 if (!destRouteData->hasValidDestNum()) {
580 updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
581
582 // If the route table entry to the destination is created or updated,
583 // then the following actions occur:
584 //
585 // - the route is marked as active,
586 //
587 // - the destination sequence number is marked as valid,
588 //
589 // - the next hop in the route entry is assigned to be the node from
590 // which the RREP is received, which is indicated by the source IP
591 // address field in the IP header,
592 //
593 // - the hop count is set to the value of the New Hop Count,
594 //
595 // - the expiry time is set to the current time plus the value of the
596 // Lifetime in the RREP message,
597 //
598 // - and the destination sequence number is the Destination Sequence
599 // Number in the RREP message.
600 }
601 // (ii) the Destination Sequence Number in the RREP is greater than
602 // the node's copy of the destination sequence number and the
603 // known value is valid, or
604 else if (destSeqNum > destRouteData->getDestSeqNum()) {
605 updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
606 }
607 else {
608 // (iii) the sequence numbers are the same, but the route is
609 // marked as inactive, or
610 if (destSeqNum == destRouteData->getDestSeqNum() && !destRouteData->isActive()) {
611 updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
612 }
613 // (iv) the sequence numbers are the same, and the New Hop Count is
614 // smaller than the hop count in route table entry.
615 else if (destSeqNum == destRouteData->getDestSeqNum() && newHopCount < (unsigned int)destRoute->getMetric()) {
616 updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
617 }
618 }
619 }
620 else { // create forward route for the destination: this path will be used by the originator to send data packets
621 destRoute = createRoute(rrep->getDestAddr(), sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
622 destRouteData = check_and_cast<AODVRouteData *>(destRoute->getProtocolData());
623 }
624
625 // If the current node is not the node indicated by the Originator IP
626 // Address in the RREP message AND a forward route has been created or
627 // updated as described above, the node consults its route table entry
628 // for the originating node to determine the next hop for the RREP
629 // packet, and then forwards the RREP towards the originator using the
630 // information in that route table entry.
631
632 IRoute *originatorRoute = routingTable->findBestMatchingRoute(rrep->getOriginatorAddr());
633 if (getSelfIPAddress() != rrep->getOriginatorAddr()) {
634 // If a node forwards a RREP over a link that is likely to have errors or
635 // be unidirectional, the node SHOULD set the 'A' flag to require that the
636 // recipient of the RREP acknowledge receipt of the RREP by sending a RREP-ACK
637 // message back (see section 6.8).
638
639 if (originatorRoute && originatorRoute->getSource() == this) {
640 AODVRouteData *originatorRouteData = check_and_cast<AODVRouteData *>(originatorRoute->getProtocolData());
641
642 // Also, at each node the (reverse) route used to forward a
643 // RREP has its lifetime changed to be the maximum of (existing-
644 // lifetime, (current time + ACTIVE_ROUTE_TIMEOUT).
645
646 simtime_t existingLifeTime = originatorRouteData->getLifeTime();
647 originatorRouteData->setLifeTime(std::max(simTime() + activeRouteTimeout, existingLifeTime));
648
649 if (simTime() > rebootTime + deletePeriod || rebootTime == 0) {
650 // If a node forwards a RREP over a link that is likely to have errors
651 // or be unidirectional, the node SHOULD set the 'A' flag to require that
652 // the recipient of the RREP acknowledge receipt of the RREP by sending a
653 // RREP-ACK message back (see section 6.8).
654
655 if (rrep->getAckRequiredFlag()) {
656 AODVRREPACK *rrepACK = createRREPACK();
657 sendRREPACK(rrepACK, sourceAddr);
658 rrep->setAckRequiredFlag(false);
659 }
660
661 // When any node transmits a RREP, the precursor list for the
662 // corresponding destination node is updated by adding to it
663 // the next hop node to which the RREP is forwarded.
664
665 destRouteData->addPrecursor(originatorRoute->getNextHopAsGeneric());
666
667 // Finally, the precursor list for the next hop towards the
668 // destination is updated to contain the next hop towards the
669 // source (originator).
670
671 IRoute *nextHopToDestRoute = routingTable->findBestMatchingRoute(destRoute->getNextHopAsGeneric());
672 if (nextHopToDestRoute && nextHopToDestRoute->getSource() == this) {
673 AODVRouteData *nextHopToDestRouteData = check_and_cast<AODVRouteData *>(nextHopToDestRoute->getProtocolData());
674 nextHopToDestRouteData->addPrecursor(originatorRoute->getNextHopAsGeneric());
675 }
676 AODVRREP *outgoingRREP = rrep->dup();
677 forwardRREP(outgoingRREP, originatorRoute->getNextHopAsGeneric(), 100);
678 }
679 }
680 else
681 EV_ERROR << "Reverse route doesn't exist. Dropping the RREP message" << endl;
682 }
683 else {
684 if (hasOngoingRouteDiscovery(rrep->getDestAddr())) {
685 EV_INFO << "The Route Reply has arrived for our Route Request to node " << rrep->getDestAddr() << endl;
686 updateRoutingTable(destRoute, sourceAddr, newHopCount, true, destSeqNum, true, simTime() + lifeTime);
687 completeRouteDiscovery(rrep->getDestAddr());
688 }
689 }
690
691 delete rrep;
692}
693
694void AODVRouting::updateRoutingTable(IRoute *route, const L3Address& nextHop, unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum, bool isActive, simtime_t lifeTime)
695{
696 EV_DETAIL << "Updating existing route: " << route << endl;
697
698 route->setNextHop(nextHop);
699 route->setMetric(hopCount);
700
701 AODVRouteData *routingData = check_and_cast<AODVRouteData *>(route->getProtocolData());
702 ASSERT(routingData != nullptr);
703
704 routingData->setLifeTime(lifeTime);
705 routingData->setDestSeqNum(destSeqNum);
706 routingData->setIsActive(isActive);
707 routingData->setHasValidDestNum(hasValidDestNum);
708
709 EV_DETAIL << "Route updated: " << route << endl;
710
711 scheduleExpungeRoutes();
712}
713
714void AODVRouting::sendAODVPacket(AODVControlPacket *packet, const L3Address& destAddr, unsigned int timeToLive, double delay)
715{
716 ASSERT(timeToLive != 0);
717
718 INetworkProtocolControlInfo *networkProtocolControlInfo = addressType->createNetworkProtocolControlInfo();
719
720 networkProtocolControlInfo->setHopLimit(timeToLive);
721
722 networkProtocolControlInfo->setTransportProtocol(IP_PROT_MANET);
723 networkProtocolControlInfo->setDestinationAddress(destAddr);
724 networkProtocolControlInfo->setSourceAddress(getSelfIPAddress());
725
726 // TODO: Implement: support for multiple interfaces
727 InterfaceEntry *ifEntry = interfaceTable->getInterfaceByName("wlan0");
728 networkProtocolControlInfo->setInterfaceId(ifEntry->getInterfaceId());
729
730 UDPPacket *udpPacket = new UDPPacket(packet->getName());
731 udpPacket->encapsulate(packet);
732 udpPacket->setSourcePort(aodvUDPPort);
733 udpPacket->setDestinationPort(aodvUDPPort);
734 udpPacket->setControlInfo(dynamic_cast<cObject *>(networkProtocolControlInfo));
735
736 if (destAddr.isBroadcast())
737 lastBroadcastTime = simTime();
738
739 if (delay == 0)
740 send(udpPacket, "ipOut");
741 else
742 sendDelayed(udpPacket, delay, "ipOut");
743}
744
745void AODVRouting::handleRREQ(AODVRREQ *rreq, const L3Address& sourceAddr, unsigned int timeToLive)
746{
747 EV_INFO << "AODV Route Request arrived with source addr: " << sourceAddr << " originator addr: " << rreq->getOriginatorAddr()
748 << " destination addr: " << rreq->getDestAddr() << endl;
749
750 // A node ignores all RREQs received from any node in its blacklist set.
751
752 auto blackListIt = blacklist.find(sourceAddr);
753 if (blackListIt != blacklist.end()) {
754 EV_INFO << "The sender node " << sourceAddr << " is in our blacklist. Ignoring the Route Request" << endl;
755 delete rreq;
756 return;
757 }
758
759 // When a node receives a RREQ, it first creates or updates a route to
760 // the previous hop without a valid sequence number (see section 6.2).
761
762 IRoute *previousHopRoute = routingTable->findBestMatchingRoute(sourceAddr);
763
764 if (!previousHopRoute || previousHopRoute->getSource() != this) {
765 // create without valid sequence number
766 previousHopRoute = createRoute(sourceAddr, sourceAddr, 1, false, rreq->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
767 }
768 else
769 updateRoutingTable(previousHopRoute, sourceAddr, 1, false, rreq->getOriginatorSeqNum(), true, simTime() + activeRouteTimeout);
770
771 // then checks to determine whether it has received a RREQ with the same
772 // Originator IP Address and RREQ ID within at least the last PATH_DISCOVERY_TIME.
773 // If such a RREQ has been received, the node silently discards the newly received RREQ.
774
775 RREQIdentifier rreqIdentifier(rreq->getOriginatorAddr(), rreq->getRreqId());
776 auto checkRREQArrivalTime = rreqsArrivalTime.find(rreqIdentifier);
777 if (checkRREQArrivalTime != rreqsArrivalTime.end() && simTime() - checkRREQArrivalTime->second <= pathDiscoveryTime) {
778 EV_WARN << "The same packet has arrived within PATH_DISCOVERY_TIME= " << pathDiscoveryTime << ". Discarding it" << endl;
779 delete rreq;
780 return;
781 }
782
783 // update or create
784 rreqsArrivalTime[rreqIdentifier] = simTime();
785
786 // First, it first increments the hop count value in the RREQ by one, to
787 // account for the new hop through the intermediate node.
788
789 rreq->setHopCount(rreq->getHopCount() + 1);
790
791 // Then the node searches for a reverse route to the Originator IP Address (see
792 // section 6.2), using longest-prefix matching.
793
794 IRoute *reverseRoute = routingTable->findBestMatchingRoute(rreq->getOriginatorAddr());
795
796 // If need be, the route is created, or updated using the Originator Sequence Number from the
797 // RREQ in its routing table.
798 //
799 // When the reverse route is created or updated, the following actions on
800 // the route are also carried out:
801 //
802 // 1. the Originator Sequence Number from the RREQ is compared to the
803 // corresponding destination sequence number in the route table entry
804 // and copied if greater than the existing value there
805 //
806 // 2. the valid sequence number field is set to true;
807 //
808 // 3. the next hop in the routing table becomes the node from which the
809 // RREQ was received (it is obtained from the source IP address in
810 // the IP header and is often not equal to the Originator IP Address
811 // field in the RREQ message);
812 //
813 // 4. the hop count is copied from the Hop Count in the RREQ message;
814 //
815 // Whenever a RREQ message is received, the Lifetime of the reverse
816 // route entry for the Originator IP address is set to be the maximum of
817 // (ExistingLifetime, MinimalLifetime), where
818 //
819 // MinimalLifetime = (current time + 2*NET_TRAVERSAL_TIME - 2*HopCount*NODE_TRAVERSAL_TIME).
820
821 unsigned int hopCount = rreq->getHopCount();
822 simtime_t minimalLifeTime = simTime() + 2 * netTraversalTime - 2 * hopCount * nodeTraversalTime;
823 simtime_t newLifeTime = std::max(simTime(), minimalLifeTime);
824 int rreqSeqNum = rreq->getOriginatorSeqNum();
825 if (!reverseRoute || reverseRoute->getSource() != this) { // create
826 // This reverse route will be needed if the node receives a RREP back to the
827 // node that originated the RREQ (identified by the Originator IP Address).
828 reverseRoute = createRoute(rreq->getOriginatorAddr(), sourceAddr, hopCount, true, rreqSeqNum, true, newLifeTime);
829 }
830 else {
831 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(reverseRoute->getProtocolData());
832 int routeSeqNum = routeData->getDestSeqNum();
833 int newSeqNum = std::max(routeSeqNum, rreqSeqNum);
834 int newHopCount = rreq->getHopCount(); // Note: already incremented by 1.
835 int routeHopCount = reverseRoute->getMetric();
836 // The route is only updated if the new sequence number is either
837 //
838 // (i) higher than the destination sequence number in the route
839 // table, or
840 //
841 // (ii) the sequence numbers are equal, but the hop count (of the
842 // new information) plus one, is smaller than the existing hop
843 // count in the routing table, or
844 //
845 // (iii) the sequence number is unknown.
846
847 if (rreqSeqNum > routeSeqNum ||
848 (rreqSeqNum == routeSeqNum && newHopCount < routeHopCount) ||
849 rreq->getUnknownSeqNumFlag())
850 {
851 updateRoutingTable(reverseRoute, sourceAddr, hopCount, true, newSeqNum, true, newLifeTime);
852 }
853 }
854
855 // A node generates a RREP if either:
856 //
857 // (i) it is itself the destination, or
858 //
859 // (ii) it has an active route to the destination, the destination
860 // sequence number in the node's existing route table entry
861 // for the destination is valid and greater than or equal to
862 // the Destination Sequence Number of the RREQ (comparison
863 // using signed 32-bit arithmetic), and the "destination only"
864 // ('D') flag is NOT set.
865
866 // After a node receives a RREQ and responds with a RREP, it discards
867 // the RREQ. If the RREQ has the 'G' flag set, and the intermediate
868 // node returns a RREP to the originating node, it MUST also unicast a
869 // gratuitous RREP to the destination node.
870
871 IRoute *destRoute = routingTable->findBestMatchingRoute(rreq->getDestAddr());
872 AODVRouteData *destRouteData = destRoute ? dynamic_cast<AODVRouteData *>(destRoute->getProtocolData()) : nullptr;
873
874 // check (i)
875 if (rreq->getDestAddr() == getSelfIPAddress()) {
876 EV_INFO << "I am the destination node for which the route was requested" << endl;
877
878 // create RREP
879 AODVRREP *rrep = createRREP(rreq, destRoute, reverseRoute, sourceAddr);
880
881 // send to the originator
882 sendRREP(rrep, rreq->getOriginatorAddr(), 255);
883
884 delete rreq;
885 return; // discard RREQ, in this case, we do not forward it.
886 }
887
888 // check (ii)
889 if (destRouteData && destRouteData->isActive() && destRouteData->hasValidDestNum() &&
890 destRouteData->getDestSeqNum() >= rreq->getDestSeqNum())
891 {
892 EV_INFO << "I am an intermediate node who has information about a route to " << rreq->getDestAddr() << endl;
893
894 if (destRoute->getNextHopAsGeneric() == sourceAddr) {
895 EV_WARN << "This RREP would make a loop. Dropping it" << endl;
896
897 delete rreq;
898 return;
899 }
900
901 // create RREP
902 AODVRREP *rrep = createRREP(rreq, destRoute, reverseRoute, sourceAddr);
903
904 // send to the originator
905 sendRREP(rrep, rreq->getOriginatorAddr(), 255);
906
907 if (rreq->getGratuitousRREPFlag()) {
908 // The gratuitous RREP is then sent to the next hop along the path to
909 // the destination node, just as if the destination node had already
910 // issued a RREQ for the originating node and this RREP was produced in
911 // response to that (fictitious) RREQ.
912
913 IRoute *originatorRoute = routingTable->findBestMatchingRoute(rreq->getOriginatorAddr());
914 AODVRREP *grrep = createGratuitousRREP(rreq, originatorRoute);
915 sendGRREP(grrep, rreq->getDestAddr(), 100);
916 }
917
918 delete rreq;
919 return; // discard RREQ, in this case, we also do not forward it.
920 }
921 // If a node does not generate a RREP (following the processing rules in
922 // section 6.6), and if the incoming IP header has TTL larger than 1,
923 // the node updates and broadcasts the RREQ to address 255.255.255.255
924 // on each of its configured interfaces (see section 6.14). To update
925 // the RREQ, the TTL or hop limit field in the outgoing IP header is
926 // decreased by one, and the Hop Count field in the RREQ message is
927 // incremented by one, to account for the new hop through the
928 // intermediate node. (!) Lastly, the Destination Sequence number for the
929 // requested destination is set to the maximum of the corresponding
930 // value received in the RREQ message, and the destination sequence
931 // value currently maintained by the node for the requested destination.
932 // However, the forwarding node MUST NOT modify its maintained value for
933 // the destination sequence number, even if the value received in the
934 // incoming RREQ is larger than the value currently maintained by the
935 // forwarding node.
936
937 if (timeToLive > 0 && (simTime() > rebootTime + deletePeriod || rebootTime == 0)) {
938 if (destRouteData)
939 rreq->setDestSeqNum(std::max(destRouteData->getDestSeqNum(), rreq->getDestSeqNum()));
940 rreq->setUnknownSeqNumFlag(false);
941
942 AODVRREQ *outgoingRREQ = rreq->dup();
943 forwardRREQ(outgoingRREQ, timeToLive);
944 }
945 else
946 EV_WARN << "Can't forward the RREQ because of its small (<= 1) TTL: " << timeToLive << " or the AODV reboot has not completed yet" << endl;
947
948 delete rreq;
949}
950
951IRoute *AODVRouting::createRoute(const L3Address& destAddr, const L3Address& nextHop,
952 unsigned int hopCount, bool hasValidDestNum, unsigned int destSeqNum,
953 bool isActive, simtime_t lifeTime)
954{
955 IRoute *newRoute = routingTable->createRoute();
956 AODVRouteData *newProtocolData = new AODVRouteData();
957
958 newProtocolData->setHasValidDestNum(hasValidDestNum);
959
960 // active route
961 newProtocolData->setIsActive(isActive);
962
963 // A route towards a destination that has a routing table entry
964 // that is marked as valid. Only active routes can be used to
965 // forward data packets.
966
967 newProtocolData->setLifeTime(lifeTime);
968 newProtocolData->setDestSeqNum(destSeqNum);
969
970 InterfaceEntry *ifEntry = interfaceTable->getInterfaceByName("wlan0"); // TODO: IMPLEMENT: multiple interfaces
971 if (ifEntry)
972 newRoute->setInterface(ifEntry);
973
974 newRoute->setDestination(destAddr);
975 newRoute->setSourceType(IRoute::AODV);
976 newRoute->setSource(this);
977 newRoute->setProtocolData(newProtocolData);
978 newRoute->setMetric(hopCount);
979 newRoute->setNextHop(nextHop);
980 newRoute->setPrefixLength(addressType->getMaxPrefixLength()); // TODO:
981
982 EV_DETAIL << "Adding new route " << newRoute << endl;
983 routingTable->addRoute(newRoute);
984 scheduleExpungeRoutes();
985 return newRoute;
986}
987
988void AODVRouting::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj, cObject *details)
989{
990 Enter_Method("receiveChangeNotification");
991 if (signalID == NF_LINK_BREAK) {
992 EV_DETAIL << "Received link break signal" << endl;
993 // XXX: This is a hack for supporting both IdealMac and Ieee80211Mac. etc
994 cPacket *frame = check_and_cast<cPacket *>(obj);
995 INetworkDatagram *datagram = nullptr;
996 if (false
997#ifdef WITH_IEEE80211
998 || dynamic_cast<ieee80211::Ieee80211Frame *>(frame)
999#endif // ifdef WITH_IEEE80211
1000#ifdef WITH_IDEALWIRELESS
1001 || dynamic_cast<IdealMacFrame *>(frame)
1002#endif // ifdef WITH_IDEALWIRELESS
1003#ifdef WITH_CSMA
1004 || dynamic_cast<CSMAFrame *>(frame)
1005#endif // ifdef WITH_CSMA
1006#ifdef WITH_CSMACA
1007 || dynamic_cast<CsmaCaMacFrame *>(frame)
1008#endif // ifdef WITH_CSMACA
1009#ifdef WITH_LMAC
1010 || dynamic_cast<LMacFrame *>(frame)
1011#endif // ifdef WITH_LMAC
1012#ifdef WITH_BMAC
1013 || dynamic_cast<BMacFrame *>(frame)
1014#endif // ifdef WITH_BMAC
1015 )
1016 datagram = dynamic_cast<INetworkDatagram *>(frame->getEncapsulatedPacket());
1017 else
1018 throw cRuntimeError("Unknown packet type in NF_LINK_BREAK signal");
1019 if (datagram) {
1020 L3Address unreachableAddr = datagram->getDestinationAddress();
1021 if (unreachableAddr.getAddressType() == addressType) {
1022 // A node initiates processing for a RERR message in three situations:
1023 //
1024 // (i) if it detects a link break for the next hop of an active
1025 // route in its routing table while transmitting data (and
1026 // route repair, if attempted, was unsuccessful), or
1027
1028 // TODO: Implement: local repair
1029
1030 IRoute *route = routingTable->findBestMatchingRoute(unreachableAddr);
1031
1032 if (route && route->getSource() == this)
1033 handleLinkBreakSendRERR(route->getNextHopAsGeneric());
1034 }
1035 }
1036 }
1037}
1038
1039void AODVRouting::handleLinkBreakSendRERR(const L3Address& unreachableAddr)
1040{
1041 // For case (i), the node first makes a list of unreachable destinations
1042 // consisting of the unreachable neighbor and any additional
1043 // destinations (or subnets, see section 7) in the local routing table
1044 // that use the unreachable neighbor as the next hop.
1045
1046 // Just before transmitting the RERR, certain updates are made on the
1047 // routing table that may affect the destination sequence numbers for
1048 // the unreachable destinations. For each one of these destinations,
1049 // the corresponding routing table entry is updated as follows:
1050 //
1051 // 1. The destination sequence number of this routing entry, if it
1052 // exists and is valid, is incremented for cases (i) and (ii) above,
1053 // and copied from the incoming RERR in case (iii) above.
1054 //
1055 // 2. The entry is invalidated by marking the route entry as invalid
1056 //
1057 // 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
1058 // Before this time, the entry SHOULD NOT be deleted.
1059
1060 IRoute *unreachableRoute = routingTable->findBestMatchingRoute(unreachableAddr);
1061
1062 if (!unreachableRoute || unreachableRoute->getSource() != this)
1063 return;
1064
1065 std::vector<UnreachableNode> unreachableNodes;
1066 AODVRouteData *unreachableRouteData = check_and_cast<AODVRouteData *>(unreachableRoute->getProtocolData());
1067
1068 if (unreachableRouteData->isActive()) {
1069 UnreachableNode node;
1070 node.addr = unreachableAddr;
1071 node.seqNum = unreachableRouteData->getDestSeqNum();
1072 unreachableNodes.push_back(node);
1073 }
1074
1075 // For case (i), the node first makes a list of unreachable destinations
1076 // consisting of the unreachable neighbor and any additional destinations
1077 // (or subnets, see section 7) in the local routing table that use the
1078 // unreachable neighbor as the next hop.
1079
1080 for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1081 IRoute *route = routingTable->getRoute(i);
1082
1083 AODVRouteData *routeData = dynamic_cast<AODVRouteData *>(route->getProtocolData());
1084 if (routeData && routeData->isActive() && route->getNextHopAsGeneric() == unreachableAddr) {
1085 if (routeData->hasValidDestNum())
1086 routeData->setDestSeqNum(routeData->getDestSeqNum() + 1);
1087
1088 EV_DETAIL << "Marking route to " << route->getDestinationAsGeneric() << " as inactive" << endl;
1089
1090 routeData->setIsActive(false);
1091 routeData->setLifeTime(simTime() + deletePeriod);
1092 scheduleExpungeRoutes();
1093
1094 UnreachableNode node;
1095 node.addr = route->getDestinationAsGeneric();
1096 node.seqNum = routeData->getDestSeqNum();
1097 unreachableNodes.push_back(node);
1098 }
1099 }
1100
1101 // The neighboring node(s) that should receive the RERR are all those
1102 // that belong to a precursor list of at least one of the unreachable
1103 // destination(s) in the newly created RERR. In case there is only one
1104 // unique neighbor that needs to receive the RERR, the RERR SHOULD be
1105 // unicast toward that neighbor. Otherwise the RERR is typically sent
1106 // to the local broadcast address (Destination IP == 255.255.255.255,
1107 // TTL == 1) with the unreachable destinations, and their corresponding
1108 // destination sequence numbers, included in the packet.
1109
1110 if (rerrCount >= rerrRatelimit) {
1111 EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1112 return;
1113 }
1114
1115 if (unreachableNodes.empty())
1116 return;
1117
1118 AODVRERR *rerr = createRERR(unreachableNodes);
1119 rerrCount++;
1120
1121 // broadcast
1122 EV_INFO << "Broadcasting Route Error message with TTL=1" << endl;
1123 sendAODVPacket(rerr, addressType->getBroadcastAddress(), 1, jitterPar->doubleValue());
1124}
1125
1126AODVRERR *AODVRouting::createRERR(const std::vector<UnreachableNode>& unreachableNodes)
1127{
1128 AODVRERR *rerr = new AODVRERR("AODV-RERR");
1129 unsigned int destCount = unreachableNodes.size();
1130
1131 rerr->setPacketType(RERR);
1132 rerr->setDestCount(destCount);
1133 rerr->setUnreachableNodesArraySize(destCount);
1134
1135 for (unsigned int i = 0; i < destCount; i++) {
1136 UnreachableNode node;
1137 node.addr = unreachableNodes[i].addr;
1138 node.seqNum = unreachableNodes[i].seqNum;
1139 rerr->setUnreachableNodes(i, node);
1140 }
1141
1142 rerr->setByteLength(4 + 4 * 2 * destCount);
1143 return rerr;
1144}
1145
1146void AODVRouting::handleRERR(AODVRERR *rerr, const L3Address& sourceAddr)
1147{
1148 EV_INFO << "AODV Route Error arrived with source addr: " << sourceAddr << endl;
1149
1150 // A node initiates processing for a RERR message in three situations:
1151 // (iii) if it receives a RERR from a neighbor for one or more
1152 // active routes.
1153 unsigned int unreachableArraySize = rerr->getUnreachableNodesArraySize();
1154 std::vector<UnreachableNode> unreachableNeighbors;
1155
1156 for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1157 IRoute *route = routingTable->getRoute(i);
1158 AODVRouteData *routeData = route ? dynamic_cast<AODVRouteData *>(route->getProtocolData()) : nullptr;
1159
1160 if (!routeData)
1161 continue;
1162
1163 // For case (iii), the list should consist of those destinations in the RERR
1164 // for which there exists a corresponding entry in the local routing
1165 // table that has the transmitter of the received RERR as the next hop.
1166
1167 if (routeData->isActive() && route->getNextHopAsGeneric() == sourceAddr) {
1168 for (unsigned int j = 0; j < unreachableArraySize; j++) {
1169 if (route->getDestinationAsGeneric() == rerr->getUnreachableNodes(j).addr) {
1170 // 1. The destination sequence number of this routing entry, if it
1171 // exists and is valid, is incremented for cases (i) and (ii) above,
1172 // ! and copied from the incoming RERR in case (iii) above.
1173
1174 routeData->setDestSeqNum(rerr->getUnreachableNodes(j).seqNum);
1175 routeData->setIsActive(false); // it means invalid, see 3. AODV Terminology p.3. in RFC 3561
1176 routeData->setLifeTime(simTime() + deletePeriod);
1177
1178 // The RERR should contain those destinations that are part of
1179 // the created list of unreachable destinations and have a non-empty
1180 // precursor list.
1181
1182 if (routeData->getPrecursorList().size() > 0) {
1183 UnreachableNode node;
1184 node.addr = route->getDestinationAsGeneric();
1185 node.seqNum = routeData->getDestSeqNum();
1186 unreachableNeighbors.push_back(node);
1187 }
1188 scheduleExpungeRoutes();
1189 }
1190 }
1191 }
1192 }
1193
1194 if (rerrCount >= rerrRatelimit) {
1195 EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1196 delete rerr;
1197 return;
1198 }
1199
1200 if (unreachableNeighbors.size() > 0 && (simTime() > rebootTime + deletePeriod || rebootTime == 0)) {
1201 EV_INFO << "Sending RERR to inform our neighbors about link breaks." << endl;
1202 AODVRERR *newRERR = createRERR(unreachableNeighbors);
1203 sendAODVPacket(newRERR, addressType->getBroadcastAddress(), 1, 0);
1204 rerrCount++;
1205 }
1206 delete rerr;
1207}
1208
1209bool AODVRouting::handleOperationStage(LifecycleOperation *operation, int stage, IDoneCallback *doneCallback)
1210{
1211 Enter_Method_Silent();
1212 if (dynamic_cast<NodeStartOperation *>(operation)) {
1213 if ((NodeStartOperation::Stage)stage == NodeStartOperation::STAGE_APPLICATION_LAYER) {
1214 isOperational = true;
1215 rebootTime = simTime();
1216
1217 if (useHelloMessages)
1218 scheduleAt(simTime() + helloInterval - periodicJitter->doubleValue(), helloMsgTimer);
1219
1220 scheduleAt(simTime() + 1, counterTimer);
1221 }
1222 }
1223 else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
1224 if ((NodeShutdownOperation::Stage)stage == NodeShutdownOperation::STAGE_APPLICATION_LAYER) {
1225 isOperational = false;
1226 clearState();
1227 }
1228 }
1229 else if (dynamic_cast<NodeCrashOperation *>(operation)) {
1230 if ((NodeCrashOperation::Stage)stage == NodeCrashOperation::STAGE_CRASH) {
1231 isOperational = false;
1232 clearState();
1233 }
1234 }
1235 else
1236 throw cRuntimeError("Unsupported lifecycle operation '%s'", operation->getClassName());
1237
1238 return true;
1239}
1240
1241void AODVRouting::clearState()
1242{
1243 rerrCount = rreqCount = rreqId = sequenceNum = 0;
1244 addressToRreqRetries.clear();
1245 for (auto & elem : waitForRREPTimers)
1246 cancelAndDelete(elem.second);
1247
1248 // FIXME: Drop the queued datagrams.
1249 //for (auto it = targetAddressToDelayedPackets.begin(); it != targetAddressToDelayedPackets.end(); it++)
1250 // networkProtocol->dropQueuedDatagram(const_cast<const INetworkDatagram *>(it->second));
1251
1252 targetAddressToDelayedPackets.clear();
1253
1254 waitForRREPTimers.clear();
1255 rreqsArrivalTime.clear();
1256
1257 if (useHelloMessages)
1258 cancelEvent(helloMsgTimer);
1259 if (expungeTimer)
1260 cancelEvent(expungeTimer);
1261 if (counterTimer)
1262 cancelEvent(counterTimer);
1263 if (blacklistTimer)
1264 cancelEvent(blacklistTimer);
1265 if (rrepAckTimer)
1266 cancelEvent(rrepAckTimer);
1267}
1268
1269void AODVRouting::handleWaitForRREP(WaitForRREP *rrepTimer)
1270{
1271 EV_INFO << "We didn't get any Route Reply within RREP timeout" << endl;
1272 L3Address destAddr = rrepTimer->getDestAddr();
1273
1274 ASSERT(addressToRreqRetries.find(destAddr) != addressToRreqRetries.end());
1275 if (addressToRreqRetries[destAddr] == rreqRetries) {
1276 cancelRouteDiscovery(destAddr);
1277 EV_WARN << "Re-discovery attempts for node " << destAddr << " reached RREQ_RETRIES= " << rreqRetries << " limit. Stop sending RREQ." << endl;
1278 return;
1279 }
1280
1281 AODVRREQ *rreq = createRREQ(destAddr);
1282
1283 // the node MAY try again to discover a route by broadcasting another
1284 // RREQ, up to a maximum of RREQ_RETRIES times at the maximum TTL value.
1285 if (rrepTimer->getLastTTL() == netDiameter) // netDiameter is the maximum TTL value
1286 addressToRreqRetries[destAddr]++;
1287
1288 sendRREQ(rreq, addressType->getBroadcastAddress(), 0);
1289}
1290
1291void AODVRouting::forwardRREP(AODVRREP *rrep, const L3Address& destAddr, unsigned int timeToLive)
1292{
1293 EV_INFO << "Forwarding the Route Reply to the node " << rrep->getOriginatorAddr() << " which originated the Route Request" << endl;
1294
1295 // RFC 5148:
1296 // When a node forwards a message, it SHOULD be jittered by delaying it
1297 // by a random duration. This delay SHOULD be generated uniformly in an
1298 // interval between zero and MAXJITTER.
1299 sendAODVPacket(rrep, destAddr, 100, jitterPar->doubleValue());
1300}
1301
1302void AODVRouting::forwardRREQ(AODVRREQ *rreq, unsigned int timeToLive)
1303{
1304 EV_INFO << "Forwarding the Route Request message with TTL= " << timeToLive << endl;
1305 sendAODVPacket(rreq, addressType->getBroadcastAddress(), timeToLive, jitterPar->doubleValue());
1306}
1307
1308void AODVRouting::completeRouteDiscovery(const L3Address& target)
1309{
1310 EV_DETAIL << "Completing route discovery, originator " << getSelfIPAddress() << ", target " << target << endl;
1311 ASSERT(hasOngoingRouteDiscovery(target));
1312
1313 auto lt = targetAddressToDelayedPackets.lower_bound(target);
1314 auto ut = targetAddressToDelayedPackets.upper_bound(target);
1315
1316 // reinject the delayed datagrams
1317 for (auto it = lt; it != ut; it++) {
1318 INetworkDatagram *datagram = it->second;
1319 EV_DETAIL << "Sending queued datagram: source " << datagram->getSourceAddress() << ", destination " << datagram->getDestinationAddress() << endl;
1320 networkProtocol->reinjectQueuedDatagram(const_cast<const INetworkDatagram *>(datagram));
1321 }
1322
1323 // clear the multimap
1324 targetAddressToDelayedPackets.erase(lt, ut);
1325
1326 // we have a route for the destination, thus we must cancel the WaitForRREPTimer events
1327 auto waitRREPIter = waitForRREPTimers.find(target);
1328 ASSERT(waitRREPIter != waitForRREPTimers.end());
1329 cancelAndDelete(waitRREPIter->second);
1330 waitForRREPTimers.erase(waitRREPIter);
1331}
1332
1333void AODVRouting::sendGRREP(AODVRREP *grrep, const L3Address& destAddr, unsigned int timeToLive)
1334{
1335 EV_INFO << "Sending gratuitous Route Reply to " << destAddr << endl;
1336
1337 IRoute *destRoute = routingTable->findBestMatchingRoute(destAddr);
1338 const L3Address& nextHop = destRoute->getNextHopAsGeneric();
1339
1340 sendAODVPacket(grrep, nextHop, timeToLive, 0);
1341}
1342
1343AODVRREP *AODVRouting::createHelloMessage()
1344{
1345 // called a Hello message, with the RREP
1346 // message fields set as follows:
1347 //
1348 // Destination IP Address The node's IP address.
1349 //
1350 // Destination Sequence Number The node's latest sequence number.
1351 //
1352 // Hop Count 0
1353 //
1354 // Lifetime ALLOWED_HELLO_LOSS *HELLO_INTERVAL
1355
1356 AODVRREP *helloMessage = new AODVRREP("AODV-HelloMsg");
1357 helloMessage->setPacketType(RREP);
1358 helloMessage->setDestAddr(getSelfIPAddress());
1359 helloMessage->setDestSeqNum(sequenceNum);
1360 helloMessage->setHopCount(0);
1361 helloMessage->setLifeTime(allowedHelloLoss * helloInterval);
1362 helloMessage->setByteLength(20);
1363
1364 return helloMessage;
1365}
1366
1367void AODVRouting::sendHelloMessagesIfNeeded()
1368{
1369 ASSERT(useHelloMessages);
1370 // Every HELLO_INTERVAL milliseconds, the node checks whether it has
1371 // sent a broadcast (e.g., a RREQ or an appropriate layer 2 message)
1372 // within the last HELLO_INTERVAL. If it has not, it MAY broadcast
1373 // a RREP with TTL = 1
1374
1375 // A node SHOULD only use hello messages if it is part of an
1376 // active route.
1377 bool hasActiveRoute = false;
1378
1379 for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1380 IRoute *route = routingTable->getRoute(i);
1381 if (route->getSource() == this) {
1382 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1383 if (routeData->isActive()) {
1384 hasActiveRoute = true;
1385 break;
1386 }
1387 }
1388 }
1389
1390 if (hasActiveRoute && (lastBroadcastTime == 0 || simTime() - lastBroadcastTime > helloInterval)) {
1391 EV_INFO << "It is hello time, broadcasting Hello Messages with TTL=1" << endl;
1392 AODVRREP *helloMessage = createHelloMessage();
1393 sendAODVPacket(helloMessage, addressType->getBroadcastAddress(), 1, 0);
1394 }
1395
1396 scheduleAt(simTime() + helloInterval - periodicJitter->doubleValue(), helloMsgTimer);
1397}
1398
1399void AODVRouting::handleHelloMessage(AODVRREP *helloMessage)
1400{
1401 const L3Address& helloOriginatorAddr = helloMessage->getDestAddr();
1402 IRoute *routeHelloOriginator = routingTable->findBestMatchingRoute(helloOriginatorAddr);
1403
1404 // Whenever a node receives a Hello message from a neighbor, the node
1405 // SHOULD make sure that it has an active route to the neighbor, and
1406 // create one if necessary. If a route already exists, then the
1407 // Lifetime for the route should be increased, if necessary, to be at
1408 // least ALLOWED_HELLO_LOSS * HELLO_INTERVAL. The route to the
1409 // neighbor, if it exists, MUST subsequently contain the latest
1410 // Destination Sequence Number from the Hello message. The current node
1411 // can now begin using this route to forward data packets. Routes that
1412 // are created by hello messages and not used by any other active routes
1413 // will have empty precursor lists and would not trigger a RERR message
1414 // if the neighbor moves away and a neighbor timeout occurs.
1415
1416 unsigned int latestDestSeqNum = helloMessage->getDestSeqNum();
1417 simtime_t newLifeTime = simTime() + allowedHelloLoss * helloInterval;
1418
1419 if (!routeHelloOriginator || routeHelloOriginator->getSource() != this)
1420 createRoute(helloOriginatorAddr, helloOriginatorAddr, 1, true, latestDestSeqNum, true, newLifeTime);
1421 else {
1422 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(routeHelloOriginator->getProtocolData());
1423 simtime_t lifeTime = routeData->getLifeTime();
1424 updateRoutingTable(routeHelloOriginator, helloOriginatorAddr, 1, true, latestDestSeqNum, true, std::max(lifeTime, newLifeTime));
1425 }
1426
1427 // TODO: This feature has not implemented yet.
1428 // A node MAY determine connectivity by listening for packets from its
1429 // set of neighbors. If, within the past DELETE_PERIOD, it has received
1430 // a Hello message from a neighbor, and then for that neighbor does not
1431 // receive any packets (Hello messages or otherwise) for more than
1432 // ALLOWED_HELLO_LOSS * HELLO_INTERVAL milliseconds, the node SHOULD
1433 // assume that the link to this neighbor is currently lost. When this
1434 // happens, the node SHOULD proceed as in Section 6.11.
1435}
1436
1437void AODVRouting::expungeRoutes()
1438{
1439 for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1440 IRoute *route = routingTable->getRoute(i);
1441 if (route->getSource() == this) {
1442 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1443 ASSERT(routeData != nullptr);
1444 if (routeData->getLifeTime() <= simTime()) {
1445 if (routeData->isActive()) {
1446 EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and set to inactive. It will be deleted after DELETE_PERIOD time" << endl;
1447 // An expired routing table entry SHOULD NOT be expunged before
1448 // (current_time + DELETE_PERIOD) (see section 6.11). Otherwise, the
1449 // soft state corresponding to the route (e.g., last known hop count)
1450 // will be lost.
1451 routeData->setIsActive(false);
1452 routeData->setLifeTime(simTime() + deletePeriod);
1453 }
1454 else {
1455 // Any routing table entry waiting for a RREP SHOULD NOT be expunged
1456 // before (current_time + 2 * NET_TRAVERSAL_TIME).
1457 if (hasOngoingRouteDiscovery(route->getDestinationAsGeneric())) {
1458 EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and is inactive, but we are waiting for a RREP to this destination, so we extend its lifetime with 2 * NET_TRAVERSAL_TIME" << endl;
1459 routeData->setLifeTime(simTime() + 2 * netTraversalTime);
1460 }
1461 else {
1462 EV_DETAIL << "Route to " << route->getDestinationAsGeneric() << " expired and is inactive and we are not expecting any RREP to this destination, so we delete this route" << endl;
1463 routingTable->deleteRoute(route);
1464 }
1465 }
1466 }
1467 }
1468 }
1469 scheduleExpungeRoutes();
1470}
1471
1472void AODVRouting::scheduleExpungeRoutes()
1473{
1474 simtime_t nextExpungeTime = SimTime::getMaxTime();
1475 for (int i = 0; i < routingTable->getNumRoutes(); i++) {
1476 IRoute *route = routingTable->getRoute(i);
1477
1478 if (route->getSource() == this) {
1479 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1480 ASSERT(routeData != nullptr);
1481
1482 if (routeData->getLifeTime() < nextExpungeTime)
1483 nextExpungeTime = routeData->getLifeTime();
1484 }
1485 }
1486 if (nextExpungeTime == SimTime::getMaxTime()) {
1487 if (expungeTimer->isScheduled())
1488 cancelEvent(expungeTimer);
1489 }
1490 else {
1491 if (!expungeTimer->isScheduled())
1492 scheduleAt(nextExpungeTime, expungeTimer);
1493 else {
1494 if (expungeTimer->getArrivalTime() != nextExpungeTime) {
1495 cancelEvent(expungeTimer);
1496 scheduleAt(nextExpungeTime, expungeTimer);
1497 }
1498 }
1499 }
1500}
1501
1502INetfilter::IHook::Result AODVRouting::datagramForwardHook(INetworkDatagram *datagram, const InterfaceEntry *inputInterfaceEntry, const InterfaceEntry *& outputInterfaceEntry, L3Address& nextHopAddress)
1503{
1504 // TODO: Implement: Actions After Reboot
1505 // If the node receives a data packet for some other destination, it SHOULD
1506 // broadcast a RERR as described in subsection 6.11 and MUST reset the waiting
1507 // timer to expire after current time plus DELETE_PERIOD.
1508
1509 Enter_Method("datagramForwardHook");
1510 const L3Address& destAddr = datagram->getDestinationAddress();
1511 const L3Address& sourceAddr = datagram->getSourceAddress();
1512 IRoute *ipSource = routingTable->findBestMatchingRoute(sourceAddr);
1513
1514 if (destAddr.isBroadcast() || routingTable->isLocalAddress(destAddr) || destAddr.isMulticast()) {
1515 if (routingTable->isLocalAddress(destAddr) && ipSource && ipSource->getSource() == this)
1516 updateValidRouteLifeTime(ipSource->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1517
1518 return ACCEPT;
1519 }
1520
1521 // TODO: IMPLEMENT: check if the datagram is a data packet or we take control packets as data packets
1522
1523 IRoute *routeDest = routingTable->findBestMatchingRoute(destAddr);
1524 AODVRouteData *routeDestData = routeDest ? dynamic_cast<AODVRouteData *>(routeDest->getProtocolData()) : nullptr;
1525
1526 // Each time a route is used to forward a data packet, its Active Route
1527 // Lifetime field of the source, destination and the next hop on the
1528 // path to the destination is updated to be no less than the current
1529 // time plus ACTIVE_ROUTE_TIMEOUT
1530
1531 updateValidRouteLifeTime(sourceAddr, simTime() + activeRouteTimeout);
1532 updateValidRouteLifeTime(destAddr, simTime() + activeRouteTimeout);
1533
1534 if (routeDest && routeDest->getSource() == this)
1535 updateValidRouteLifeTime(routeDest->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1536
1537 // Since the route between each originator and destination pair is expected
1538 // to be symmetric, the Active Route Lifetime for the previous hop, along the
1539 // reverse path back to the IP source, is also updated to be no less than the
1540 // current time plus ACTIVE_ROUTE_TIMEOUT.
1541
1542 if (ipSource && ipSource->getSource() == this)
1543 updateValidRouteLifeTime(ipSource->getNextHopAsGeneric(), simTime() + activeRouteTimeout);
1544
1545 EV_INFO << "We can't forward datagram because we have no active route for " << destAddr << endl;
1546 if (routeDest && routeDestData && !routeDestData->isActive()) { // exists but is not active
1547 // A node initiates processing for a RERR message in three situations:
1548 // (ii) if it gets a data packet destined to a node for which it
1549 // does not have an active route and is not repairing (if
1550 // using local repair)
1551
1552 // TODO: check if it is not repairing (if using local repair)
1553
1554 // 1. The destination sequence number of this routing entry, if it
1555 // exists and is valid, is incremented for cases (i) and (ii) above,
1556 // and copied from the incoming RERR in case (iii) above.
1557
1558 if (routeDestData->hasValidDestNum())
1559 routeDestData->setDestSeqNum(routeDestData->getDestSeqNum() + 1);
1560
1561 // 2. The entry is invalidated by marking the route entry as invalid <- it is invalid
1562
1563 // 3. The Lifetime field is updated to current time plus DELETE_PERIOD.
1564 // Before this time, the entry SHOULD NOT be deleted.
1565 routeDestData->setLifeTime(simTime() + deletePeriod);
1566
1567 sendRERRWhenNoRouteToForward(destAddr);
1568 }
1569 else if (!routeDest || routeDest->getSource() != this) // doesn't exist at all
1570 sendRERRWhenNoRouteToForward(destAddr);
1571
1572 return ACCEPT;
1573}
1574
1575void AODVRouting::sendRERRWhenNoRouteToForward(const L3Address& unreachableAddr)
1576{
1577 if (rerrCount >= rerrRatelimit) {
1578 EV_WARN << "A node should not generate more than RERR_RATELIMIT RERR messages per second. Canceling sending RERR" << endl;
1579 return;
1580 }
1581 std::vector<UnreachableNode> unreachableNodes;
1582 UnreachableNode node;
1583 node.addr = unreachableAddr;
1584
1585 IRoute *unreachableRoute = routingTable->findBestMatchingRoute(unreachableAddr);
1586 AODVRouteData *unreachableRouteData = unreachableRoute ? dynamic_cast<AODVRouteData *>(unreachableRoute->getProtocolData()) : nullptr;
1587
1588 if (unreachableRouteData && unreachableRouteData->hasValidDestNum())
1589 node.seqNum = unreachableRouteData->getDestSeqNum();
1590 else
1591 node.seqNum = 0;
1592
1593 unreachableNodes.push_back(node);
1594 AODVRERR *rerr = createRERR(unreachableNodes);
1595
1596 rerrCount++;
1597 EV_INFO << "Broadcasting Route Error message with TTL=1" << endl;
1598 sendAODVPacket(rerr, addressType->getBroadcastAddress(), 1, jitterPar->doubleValue()); // TODO: unicast if there exists a route to the source
1599}
1600
1601void AODVRouting::cancelRouteDiscovery(const L3Address& destAddr)
1602{
1603 ASSERT(hasOngoingRouteDiscovery(destAddr));
1604 auto lt = targetAddressToDelayedPackets.lower_bound(destAddr);
1605 auto ut = targetAddressToDelayedPackets.upper_bound(destAddr);
1606 for (auto it = lt; it != ut; it++)
1607 networkProtocol->dropQueuedDatagram(const_cast<const INetworkDatagram *>(it->second));
1608
1609 targetAddressToDelayedPackets.erase(lt, ut);
1610
1611 auto waitRREPIter = waitForRREPTimers.find(destAddr);
1612 ASSERT(waitRREPIter != waitForRREPTimers.end());
1613 cancelAndDelete(waitRREPIter->second);
1614 waitForRREPTimers.erase(waitRREPIter);
1615}
1616
1617bool AODVRouting::updateValidRouteLifeTime(const L3Address& destAddr, simtime_t lifetime)
1618{
1619 IRoute *route = routingTable->findBestMatchingRoute(destAddr);
1620 if (route && route->getSource() == this) {
1621 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1622 if (routeData->isActive()) {
1623 simtime_t newLifeTime = std::max(routeData->getLifeTime(), lifetime);
1624 EV_DETAIL << "Updating " << route << " lifetime to " << newLifeTime << endl;
1625 routeData->setLifeTime(newLifeTime);
1626 return true;
1627 }
1628 }
1629 return false;
1630}
1631
1632AODVRREPACK *AODVRouting::createRREPACK()
1633{
1634 AODVRREPACK *rrepACK = new AODVRREPACK("AODV-RREPACK");
1635 rrepACK->setPacketType(RREPACK);
1636 rrepACK->setByteLength(2);
1637 return rrepACK;
1638}
1639
1640void AODVRouting::sendRREPACK(AODVRREPACK *rrepACK, const L3Address& destAddr)
1641{
1642 EV_INFO << "Sending Route Reply ACK to " << destAddr << endl;
1643 sendAODVPacket(rrepACK, destAddr, 100, 0);
1644}
1645
1646void AODVRouting::handleRREPACK(AODVRREPACK *rrepACK, const L3Address& neighborAddr)
1647{
1648 // Note that the RREP-ACK packet does not contain any information about
1649 // which RREP it is acknowledging. The time at which the RREP-ACK is
1650 // received will likely come just after the time when the RREP was sent
1651 // with the 'A' bit.
1652 if (rrepAckTimer->isScheduled()) {
1653 EV_INFO << "RREP-ACK arrived from " << neighborAddr << endl;
1654
1655 IRoute *route = routingTable->findBestMatchingRoute(neighborAddr);
1656 if (route && route->getSource() == this) {
1657 EV_DETAIL << "Marking route " << route << " as active" << endl;
1658 AODVRouteData *routeData = check_and_cast<AODVRouteData *>(route->getProtocolData());
1659 routeData->setIsActive(true);
1660 cancelEvent(rrepAckTimer);
1661 }
1662 }
1663 delete rrepACK;
1664}
1665
1666void AODVRouting::handleRREPACKTimer()
1667{
1668 // when a node detects that its transmission of a RREP message has failed,
1669 // it remembers the next-hop of the failed RREP in a "blacklist" set.
1670
1671 EV_INFO << "RREP-ACK didn't arrived within timeout. Adding " << failedNextHop << " to the blacklist" << endl;
1672
1673 blacklist[failedNextHop] = simTime() + blacklistTimeout; // lifetime
1674
1675 if (!blacklistTimer->isScheduled())
1676 scheduleAt(simTime() + blacklistTimeout, blacklistTimer);
1677}
1678
1679void AODVRouting::handleBlackListTimer()
1680{
1681 simtime_t nextTime = SimTime::getMaxTime();
1682
1683 for (auto it = blacklist.begin(); it != blacklist.end(); ) {
1684 auto current = it++;
1685
1686 // Nodes are removed from the blacklist set after a BLACKLIST_TIMEOUT period
1687 if (current->second <= simTime()) {
1688 EV_DETAIL << "Blacklist lifetime has expired for " << current->first << " removing it from the blacklisted addresses" << endl;
1689 blacklist.erase(current);
1690 }
1691 else if (nextTime > current->second)
1692 nextTime = current->second;
1693 }
1694
1695 if (nextTime != SimTime::getMaxTime())
1696 scheduleAt(nextTime, blacklistTimer);
1697}
1698
1699AODVRouting::~AODVRouting()
1700{
1701 clearState();
1702 delete helloMsgTimer;
1703 delete expungeTimer;
1704 delete counterTimer;
1705 delete rrepAckTimer;
1706 delete blacklistTimer;
1707}
1708
1709} // namespace inet