A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
aodv-routing-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 IITP RAS
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Based on
18 * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
19 * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
20 *
21 * AODV-UU implementation by Erik Nordström of Uppsala University
22 * https://web.archive.org/web/20100527072022/http://core.it.uu.se/core/index.php/AODV-UU
23 *
24 * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
25 * Pavel Boyko <boyko@iitp.ru>
26 */
27#define NS_LOG_APPEND_CONTEXT \
28 if (m_ipv4) \
29 { \
30 std::clog << "[node " << m_ipv4->GetObject<Node>()->GetId() << "] "; \
31 }
32
34
35#include "ns3/adhoc-wifi-mac.h"
36#include "ns3/boolean.h"
37#include "ns3/inet-socket-address.h"
38#include "ns3/log.h"
39#include "ns3/pointer.h"
40#include "ns3/random-variable-stream.h"
41#include "ns3/string.h"
42#include "ns3/trace-source-accessor.h"
43#include "ns3/udp-header.h"
44#include "ns3/udp-l4-protocol.h"
45#include "ns3/udp-socket-factory.h"
46#include "ns3/wifi-mpdu.h"
47#include "ns3/wifi-net-device.h"
48
49#include <algorithm>
50#include <limits>
51
52namespace ns3
53{
54
55NS_LOG_COMPONENT_DEFINE("AodvRoutingProtocol");
56
57namespace aodv
58{
59NS_OBJECT_ENSURE_REGISTERED(RoutingProtocol);
60
61/// UDP Port for AODV control traffic
63
64/**
65 * \ingroup aodv
66 * \brief Tag used by AODV implementation
67 */
69{
70 public:
71 /**
72 * \brief Constructor
73 * \param o the output interface
74 */
76 : Tag(),
77 m_oif(o)
78 {
79 }
80
81 /**
82 * \brief Get the type ID.
83 * \return the object TypeId
84 */
86 {
87 static TypeId tid = TypeId("ns3::aodv::DeferredRouteOutputTag")
88 .SetParent<Tag>()
89 .SetGroupName("Aodv")
90 .AddConstructor<DeferredRouteOutputTag>();
91 return tid;
92 }
93
94 TypeId GetInstanceTypeId() const override
95 {
96 return GetTypeId();
97 }
98
99 /**
100 * \brief Get the output interface
101 * \return the output interface
102 */
104 {
105 return m_oif;
106 }
107
108 /**
109 * \brief Set the output interface
110 * \param oif the output interface
111 */
113 {
114 m_oif = oif;
115 }
116
118 {
119 return sizeof(int32_t);
120 }
121
122 void Serialize(TagBuffer i) const override
123 {
124 i.WriteU32(m_oif);
125 }
126
127 void Deserialize(TagBuffer i) override
128 {
129 m_oif = i.ReadU32();
130 }
131
132 void Print(std::ostream& os) const override
133 {
134 os << "DeferredRouteOutputTag: output interface = " << m_oif;
135 }
136
137 private:
138 /// Positive if output device is fixed in RouteOutput
140};
141
143
144//-----------------------------------------------------------------------------
146 : m_rreqRetries(2),
147 m_ttlStart(1),
148 m_ttlIncrement(2),
149 m_ttlThreshold(7),
150 m_timeoutBuffer(2),
151 m_rreqRateLimit(10),
152 m_rerrRateLimit(10),
153 m_activeRouteTimeout(Seconds(3)),
154 m_netDiameter(35),
155 m_nodeTraversalTime(MilliSeconds(40)),
156 m_netTraversalTime(Time((2 * m_netDiameter) * m_nodeTraversalTime)),
157 m_pathDiscoveryTime(Time(2 * m_netTraversalTime)),
158 m_myRouteTimeout(Time(2 * std::max(m_pathDiscoveryTime, m_activeRouteTimeout))),
159 m_helloInterval(Seconds(1)),
160 m_allowedHelloLoss(2),
161 m_deletePeriod(Time(5 * std::max(m_activeRouteTimeout, m_helloInterval))),
162 m_nextHopWait(m_nodeTraversalTime + MilliSeconds(10)),
163 m_blackListTimeout(Time(m_rreqRetries * m_netTraversalTime)),
164 m_maxQueueLen(64),
165 m_maxQueueTime(Seconds(30)),
166 m_destinationOnly(false),
167 m_gratuitousReply(true),
168 m_enableHello(false),
169 m_routingTable(m_deletePeriod),
170 m_queue(m_maxQueueLen, m_maxQueueTime),
171 m_requestId(0),
172 m_seqNo(0),
173 m_rreqIdCache(m_pathDiscoveryTime),
174 m_dpd(m_pathDiscoveryTime),
175 m_nb(m_helloInterval),
176 m_rreqCount(0),
177 m_rerrCount(0),
178 m_htimer(Timer::CANCEL_ON_DESTROY),
179 m_rreqRateLimitTimer(Timer::CANCEL_ON_DESTROY),
180 m_rerrRateLimitTimer(Timer::CANCEL_ON_DESTROY),
181 m_lastBcastTime(Seconds(0))
182{
184}
185
186TypeId
188{
189 static TypeId tid =
190 TypeId("ns3::aodv::RoutingProtocol")
192 .SetGroupName("Aodv")
193 .AddConstructor<RoutingProtocol>()
194 .AddAttribute("HelloInterval",
195 "HELLO messages emission interval.",
196 TimeValue(Seconds(1)),
199 .AddAttribute("TtlStart",
200 "Initial TTL value for RREQ.",
201 UintegerValue(1),
203 MakeUintegerChecker<uint16_t>())
204 .AddAttribute("TtlIncrement",
205 "TTL increment for each attempt using the expanding ring search for RREQ "
206 "dissemination.",
207 UintegerValue(2),
209 MakeUintegerChecker<uint16_t>())
210 .AddAttribute("TtlThreshold",
211 "Maximum TTL value for expanding ring search, TTL = NetDiameter is used "
212 "beyond this value.",
213 UintegerValue(7),
215 MakeUintegerChecker<uint16_t>())
216 .AddAttribute("TimeoutBuffer",
217 "Provide a buffer for the timeout.",
218 UintegerValue(2),
220 MakeUintegerChecker<uint16_t>())
221 .AddAttribute("RreqRetries",
222 "Maximum number of retransmissions of RREQ to discover a route",
223 UintegerValue(2),
225 MakeUintegerChecker<uint32_t>())
226 .AddAttribute("RreqRateLimit",
227 "Maximum number of RREQ per second.",
228 UintegerValue(10),
230 MakeUintegerChecker<uint32_t>())
231 .AddAttribute("RerrRateLimit",
232 "Maximum number of RERR per second.",
233 UintegerValue(10),
235 MakeUintegerChecker<uint32_t>())
236 .AddAttribute("NodeTraversalTime",
237 "Conservative estimate of the average one hop traversal time for packets "
238 "and should include "
239 "queuing delays, interrupt processing times and transfer times.",
243 .AddAttribute(
244 "NextHopWait",
245 "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
249 .AddAttribute("ActiveRouteTimeout",
250 "Period of time during which the route is considered to be valid",
251 TimeValue(Seconds(3)),
254 .AddAttribute("MyRouteTimeout",
255 "Value of lifetime field in RREP generating by this node = 2 * "
256 "max(ActiveRouteTimeout, PathDiscoveryTime)",
257 TimeValue(Seconds(11.2)),
260 .AddAttribute("BlackListTimeout",
261 "Time for which the node is put into the blacklist = RreqRetries * "
262 "NetTraversalTime",
263 TimeValue(Seconds(5.6)),
266 .AddAttribute("DeletePeriod",
267 "DeletePeriod is intended to provide an upper bound on the time for "
268 "which an upstream node A "
269 "can have a neighbor B as an active next hop for destination D, while B "
270 "has invalidated the route to D."
271 " = 5 * max (HelloInterval, ActiveRouteTimeout)",
272 TimeValue(Seconds(15)),
275 .AddAttribute("NetDiameter",
276 "Net diameter measures the maximum possible number of hops between two "
277 "nodes in the network",
278 UintegerValue(35),
280 MakeUintegerChecker<uint32_t>())
281 .AddAttribute(
282 "NetTraversalTime",
283 "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
284 TimeValue(Seconds(2.8)),
287 .AddAttribute(
288 "PathDiscoveryTime",
289 "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
290 TimeValue(Seconds(5.6)),
293 .AddAttribute("MaxQueueLen",
294 "Maximum number of packets that we allow a routing protocol to buffer.",
295 UintegerValue(64),
298 MakeUintegerChecker<uint32_t>())
299 .AddAttribute("MaxQueueTime",
300 "Maximum time packets can be queued (in seconds)",
301 TimeValue(Seconds(30)),
305 .AddAttribute("AllowedHelloLoss",
306 "Number of hello messages which may be loss for valid link.",
307 UintegerValue(2),
309 MakeUintegerChecker<uint16_t>())
310 .AddAttribute("GratuitousReply",
311 "Indicates whether a gratuitous RREP should be unicast to the node "
312 "originated route discovery.",
313 BooleanValue(true),
317 .AddAttribute("DestinationOnly",
318 "Indicates only the destination may respond to this RREQ.",
319 BooleanValue(false),
323 .AddAttribute("EnableHello",
324 "Indicates whether a hello messages enable.",
325 BooleanValue(true),
329 .AddAttribute("EnableBroadcast",
330 "Indicates whether a broadcast data packets forwarding enable.",
331 BooleanValue(true),
335 .AddAttribute("UniformRv",
336 "Access to the underlying UniformRandomVariable",
337 StringValue("ns3::UniformRandomVariable"),
339 MakePointerChecker<UniformRandomVariable>());
340 return tid;
341}
342
343void
345{
346 m_maxQueueLen = len;
348}
349
350void
352{
353 m_maxQueueTime = t;
355}
356
358{
359}
360
361void
363{
364 m_ipv4 = nullptr;
365 for (auto iter = m_socketAddresses.begin(); iter != m_socketAddresses.end(); iter++)
366 {
367 iter->first->Close();
368 }
369 m_socketAddresses.clear();
370 for (auto iter = m_socketSubnetBroadcastAddresses.begin();
372 iter++)
373 {
374 iter->first->Close();
375 }
378}
379
380void
382{
383 *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
384 << "; Time: " << Now().As(unit)
385 << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
386 << ", AODV Routing table" << std::endl;
387
388 m_routingTable.Print(stream, unit);
389 *stream->GetStream() << std::endl;
390}
391
392int64_t
394{
395 NS_LOG_FUNCTION(this << stream);
397 return 1;
398}
399
400void
402{
403 NS_LOG_FUNCTION(this);
404 if (m_enableHello)
405 {
407 }
410
413}
414
417 const Ipv4Header& header,
418 Ptr<NetDevice> oif,
419 Socket::SocketErrno& sockerr)
420{
421 NS_LOG_FUNCTION(this << header << (oif ? oif->GetIfIndex() : 0));
422 if (!p)
423 {
424 NS_LOG_DEBUG("Packet is == 0");
425 return LoopbackRoute(header, oif); // later
426 }
427 if (m_socketAddresses.empty())
428 {
430 NS_LOG_LOGIC("No aodv interfaces");
431 Ptr<Ipv4Route> route;
432 return route;
433 }
434 sockerr = Socket::ERROR_NOTERROR;
435 Ptr<Ipv4Route> route;
436 Ipv4Address dst = header.GetDestination();
438 if (m_routingTable.LookupValidRoute(dst, rt))
439 {
440 route = rt.GetRoute();
441 NS_ASSERT(route);
442 NS_LOG_DEBUG("Exist route to " << route->GetDestination() << " from interface "
443 << route->GetSource());
444 if (oif && route->GetOutputDevice() != oif)
445 {
446 NS_LOG_DEBUG("Output device doesn't match. Dropped.");
448 return Ptr<Ipv4Route>();
449 }
451 UpdateRouteLifeTime(route->GetGateway(), m_activeRouteTimeout);
452 return route;
453 }
454
455 // Valid route not found, in this case we return loopback.
456 // Actual route request will be deferred until packet will be fully formed,
457 // routed to loopback, received from loopback and passed to RouteInput (see below)
458 uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice(oif) : -1);
459 DeferredRouteOutputTag tag(iif);
460 NS_LOG_DEBUG("Valid Route not found");
461 if (!p->PeekPacketTag(tag))
462 {
463 p->AddPacketTag(tag);
464 }
465 return LoopbackRoute(header, oif);
466}
467
468void
470 const Ipv4Header& header,
472 ErrorCallback ecb)
473{
474 NS_LOG_FUNCTION(this << p << header);
475 NS_ASSERT(p && p != Ptr<Packet>());
476
477 QueueEntry newEntry(p, header, ucb, ecb);
478 bool result = m_queue.Enqueue(newEntry);
479 if (result)
480 {
481 NS_LOG_LOGIC("Add packet " << p->GetUid() << " to queue. Protocol "
482 << (uint16_t)header.GetProtocol());
484 bool result = m_routingTable.LookupRoute(header.GetDestination(), rt);
485 if (!result || ((rt.GetFlag() != IN_SEARCH) && result))
486 {
487 NS_LOG_LOGIC("Send new RREQ for outbound packet to " << header.GetDestination());
488 SendRequest(header.GetDestination());
489 }
490 }
491}
492
493bool
495 const Ipv4Header& header,
497 const UnicastForwardCallback& ucb,
498 const MulticastForwardCallback& mcb,
499 const LocalDeliverCallback& lcb,
500 const ErrorCallback& ecb)
501{
502 NS_LOG_FUNCTION(this << p->GetUid() << header.GetDestination() << idev->GetAddress());
503 if (m_socketAddresses.empty())
504 {
505 NS_LOG_LOGIC("No aodv interfaces");
506 return false;
507 }
509 NS_ASSERT(p);
510 // Check if input device supports IP
511 NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
512 int32_t iif = m_ipv4->GetInterfaceForDevice(idev);
513
514 Ipv4Address dst = header.GetDestination();
515 Ipv4Address origin = header.GetSource();
516
517 // Deferred route request
518 if (idev == m_lo)
519 {
521 if (p->PeekPacketTag(tag))
522 {
523 DeferredRouteOutput(p, header, ucb, ecb);
524 return true;
525 }
526 }
527
528 // Duplicate of own packet
529 if (IsMyOwnAddress(origin))
530 {
531 return true;
532 }
533
534 // AODV is not a multicast routing protocol
535 if (dst.IsMulticast())
536 {
537 return false;
538 }
539
540 // Broadcast local delivery/forwarding
541 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
542 {
543 Ipv4InterfaceAddress iface = j->second;
544 if (m_ipv4->GetInterfaceForAddress(iface.GetLocal()) == iif)
545 {
546 if (dst == iface.GetBroadcast() || dst.IsBroadcast())
547 {
548 if (m_dpd.IsDuplicate(p, header))
549 {
550 NS_LOG_DEBUG("Duplicated packet " << p->GetUid() << " from " << origin
551 << ". Drop.");
552 return true;
553 }
555 Ptr<Packet> packet = p->Copy();
556 if (!lcb.IsNull())
557 {
558 NS_LOG_LOGIC("Broadcast local delivery to " << iface.GetLocal());
559 lcb(p, header, iif);
560 // Fall through to additional processing
561 }
562 else
563 {
564 NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
565 << p->GetUid() << " from " << origin);
566 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
567 }
569 {
570 return true;
571 }
573 {
574 UdpHeader udpHeader;
575 p->PeekHeader(udpHeader);
576 if (udpHeader.GetDestinationPort() == AODV_PORT)
577 {
578 // AODV packets sent in broadcast are already managed
579 return true;
580 }
581 }
582 if (header.GetTtl() > 1)
583 {
584 NS_LOG_LOGIC("Forward broadcast. TTL " << (uint16_t)header.GetTtl());
585 RoutingTableEntry toBroadcast;
586 if (m_routingTable.LookupRoute(dst, toBroadcast))
587 {
588 Ptr<Ipv4Route> route = toBroadcast.GetRoute();
589 ucb(route, packet, header);
590 }
591 else
592 {
593 NS_LOG_DEBUG("No route to forward broadcast. Drop packet " << p->GetUid());
594 }
595 }
596 else
597 {
598 NS_LOG_DEBUG("TTL exceeded. Drop packet " << p->GetUid());
599 }
600 return true;
601 }
602 }
603 }
604
605 // Unicast local delivery
606 if (m_ipv4->IsDestinationAddress(dst, iif))
607 {
609 RoutingTableEntry toOrigin;
610 if (m_routingTable.LookupValidRoute(origin, toOrigin))
611 {
614 }
615 if (!lcb.IsNull())
616 {
617 NS_LOG_LOGIC("Unicast local delivery to " << dst);
618 lcb(p, header, iif);
619 }
620 else
621 {
622 NS_LOG_ERROR("Unable to deliver packet locally due to null callback "
623 << p->GetUid() << " from " << origin);
624 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
625 }
626 return true;
627 }
628
629 // Check if input device supports IP forwarding
630 if (!m_ipv4->IsForwarding(iif))
631 {
632 NS_LOG_LOGIC("Forwarding disabled for this interface");
633 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
634 return true;
635 }
636
637 // Forwarding
638 return Forwarding(p, header, ucb, ecb);
639}
640
641bool
643 const Ipv4Header& header,
645 ErrorCallback ecb)
646{
647 NS_LOG_FUNCTION(this);
648 Ipv4Address dst = header.GetDestination();
649 Ipv4Address origin = header.GetSource();
651 RoutingTableEntry toDst;
652 if (m_routingTable.LookupRoute(dst, toDst))
653 {
654 if (toDst.GetFlag() == VALID)
655 {
656 Ptr<Ipv4Route> route = toDst.GetRoute();
657 NS_LOG_LOGIC(route->GetSource() << " forwarding to " << dst << " from " << origin
658 << " packet " << p->GetUid());
659
660 /*
661 * Each time a route is used to forward a data packet, its Active Route
662 * Lifetime field of the source, destination and the next hop on the
663 * path to the destination is updated to be no less than the current
664 * time plus ActiveRouteTimeout.
665 */
668 UpdateRouteLifeTime(route->GetGateway(), m_activeRouteTimeout);
669 /*
670 * Since the route between each originator and destination pair is expected to be
671 * symmetric, the Active Route Lifetime for the previous hop, along the reverse path
672 * back to the IP source, is also updated to be no less than the current time plus
673 * ActiveRouteTimeout
674 */
675 RoutingTableEntry toOrigin;
676 m_routingTable.LookupRoute(origin, toOrigin);
678
679 m_nb.Update(route->GetGateway(), m_activeRouteTimeout);
681
682 ucb(route, p, header);
683 return true;
684 }
685 else
686 {
687 if (toDst.GetValidSeqNo())
688 {
689 SendRerrWhenNoRouteToForward(dst, toDst.GetSeqNo(), origin);
690 NS_LOG_DEBUG("Drop packet " << p->GetUid() << " because no route to forward it.");
691 return false;
692 }
693 }
694 }
695 NS_LOG_LOGIC("route not found to " << dst << ". Send RERR message.");
696 NS_LOG_DEBUG("Drop packet " << p->GetUid() << " because no route to forward it.");
697 SendRerrWhenNoRouteToForward(dst, 0, origin);
698 return false;
699}
700
701void
703{
704 NS_ASSERT(ipv4);
706
707 m_ipv4 = ipv4;
708
709 // Create lo route. It is asserted that the only one interface up for now is loopback
710 NS_ASSERT(m_ipv4->GetNInterfaces() == 1 &&
711 m_ipv4->GetAddress(0, 0).GetLocal() == Ipv4Address("127.0.0.1"));
712 m_lo = m_ipv4->GetNetDevice(0);
714 // Remember lo route
716 /*dev=*/m_lo,
717 /*dst=*/Ipv4Address::GetLoopback(),
718 /*vSeqNo=*/true,
719 /*seqNo=*/0,
720 /*iface=*/Ipv4InterfaceAddress(Ipv4Address::GetLoopback(), Ipv4Mask("255.0.0.0")),
721 /*hops=*/1,
722 /*nextHop=*/Ipv4Address::GetLoopback(),
725
727}
728
729void
731{
732 NS_LOG_FUNCTION(this << m_ipv4->GetAddress(i, 0).GetLocal());
733 Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
734 if (l3->GetNAddresses(i) > 1)
735 {
736 NS_LOG_WARN("AODV does not work with more then one address per each interface.");
737 }
738 Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
739 if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
740 {
741 return;
742 }
743
744 // Create a socket to listen only on this interface
745 Ptr<Socket> socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
746 NS_ASSERT(socket);
747 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
748 socket->BindToNetDevice(l3->GetNetDevice(i));
749 socket->Bind(InetSocketAddress(iface.GetLocal(), AODV_PORT));
750 socket->SetAllowBroadcast(true);
751 socket->SetIpRecvTtl(true);
752 m_socketAddresses.insert(std::make_pair(socket, iface));
753
754 // create also a subnet broadcast socket
755 socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
756 NS_ASSERT(socket);
757 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
758 socket->BindToNetDevice(l3->GetNetDevice(i));
759 socket->Bind(InetSocketAddress(iface.GetBroadcast(), AODV_PORT));
760 socket->SetAllowBroadcast(true);
761 socket->SetIpRecvTtl(true);
762 m_socketSubnetBroadcastAddresses.insert(std::make_pair(socket, iface));
763
764 // Add local broadcast record to the routing table
765 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
766 RoutingTableEntry rt(/*dev=*/dev,
767 /*dst=*/iface.GetBroadcast(),
768 /*vSeqNo=*/true,
769 /*seqNo=*/0,
770 /*iface=*/iface,
771 /*hops=*/1,
772 /*nextHop=*/iface.GetBroadcast(),
775
776 if (l3->GetInterface(i)->GetArpCache())
777 {
778 m_nb.AddArpCache(l3->GetInterface(i)->GetArpCache());
779 }
780
781 // Allow neighbor manager use this interface for layer 2 feedback if possible
782 Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
783 if (!wifi)
784 {
785 return;
786 }
787 Ptr<WifiMac> mac = wifi->GetMac();
788 if (!mac)
789 {
790 return;
791 }
792
793 mac->TraceConnectWithoutContext("DroppedMpdu",
795}
796
797void
799{
800 m_nb.GetTxErrorCallback()(mpdu->GetHeader());
801}
802
803void
805{
806 NS_LOG_FUNCTION(this << m_ipv4->GetAddress(i, 0).GetLocal());
807
808 // Disable layer 2 link state monitoring (if possible)
809 Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
810 Ptr<NetDevice> dev = l3->GetNetDevice(i);
811 Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
812 if (wifi)
813 {
814 Ptr<WifiMac> mac = wifi->GetMac()->GetObject<AdhocWifiMac>();
815 if (mac)
816 {
817 mac->TraceDisconnectWithoutContext("DroppedMpdu",
819 m_nb.DelArpCache(l3->GetInterface(i)->GetArpCache());
820 }
821 }
822
823 // Close socket
824 Ptr<Socket> socket = FindSocketWithInterfaceAddress(m_ipv4->GetAddress(i, 0));
825 NS_ASSERT(socket);
826 socket->Close();
827 m_socketAddresses.erase(socket);
828
829 // Close socket
830 socket = FindSubnetBroadcastSocketWithInterfaceAddress(m_ipv4->GetAddress(i, 0));
831 NS_ASSERT(socket);
832 socket->Close();
834
835 if (m_socketAddresses.empty())
836 {
837 NS_LOG_LOGIC("No aodv interfaces");
839 m_nb.Clear();
841 return;
842 }
844}
845
846void
848{
849 NS_LOG_FUNCTION(this << " interface " << i << " address " << address);
850 Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
851 if (!l3->IsUp(i))
852 {
853 return;
854 }
855 if (l3->GetNAddresses(i) == 1)
856 {
857 Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
859 if (!socket)
860 {
861 if (iface.GetLocal() == Ipv4Address("127.0.0.1"))
862 {
863 return;
864 }
865 // Create a socket to listen only on this interface
866 Ptr<Socket> socket =
868 NS_ASSERT(socket);
869 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
870 socket->BindToNetDevice(l3->GetNetDevice(i));
871 socket->Bind(InetSocketAddress(iface.GetLocal(), AODV_PORT));
872 socket->SetAllowBroadcast(true);
873 m_socketAddresses.insert(std::make_pair(socket, iface));
874
875 // create also a subnet directed broadcast socket
876 socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
877 NS_ASSERT(socket);
878 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
879 socket->BindToNetDevice(l3->GetNetDevice(i));
880 socket->Bind(InetSocketAddress(iface.GetBroadcast(), AODV_PORT));
881 socket->SetAllowBroadcast(true);
882 socket->SetIpRecvTtl(true);
883 m_socketSubnetBroadcastAddresses.insert(std::make_pair(socket, iface));
884
885 // Add local broadcast record to the routing table
886 Ptr<NetDevice> dev =
887 m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
888 RoutingTableEntry rt(/*dev=*/dev,
889 /*dst=*/iface.GetBroadcast(),
890 /*vSeqNo=*/true,
891 /*seqNo=*/0,
892 /*iface=*/iface,
893 /*hops=*/1,
894 /*nextHop=*/iface.GetBroadcast(),
897 }
898 }
899 else
900 {
901 NS_LOG_LOGIC("AODV does not work with more then one address per each interface. Ignore "
902 "added address");
903 }
904}
905
906void
908{
909 NS_LOG_FUNCTION(this);
911 if (socket)
912 {
914 socket->Close();
915 m_socketAddresses.erase(socket);
916
918 if (unicastSocket)
919 {
920 unicastSocket->Close();
921 m_socketAddresses.erase(unicastSocket);
922 }
923
924 Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol>();
925 if (l3->GetNAddresses(i))
926 {
927 Ipv4InterfaceAddress iface = l3->GetAddress(i, 0);
928 // Create a socket to listen only on this interface
929 Ptr<Socket> socket =
931 NS_ASSERT(socket);
932 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
933 // Bind to any IP address so that broadcasts can be received
934 socket->BindToNetDevice(l3->GetNetDevice(i));
935 socket->Bind(InetSocketAddress(iface.GetLocal(), AODV_PORT));
936 socket->SetAllowBroadcast(true);
937 socket->SetIpRecvTtl(true);
938 m_socketAddresses.insert(std::make_pair(socket, iface));
939
940 // create also a unicast socket
941 socket = Socket::CreateSocket(GetObject<Node>(), UdpSocketFactory::GetTypeId());
942 NS_ASSERT(socket);
943 socket->SetRecvCallback(MakeCallback(&RoutingProtocol::RecvAodv, this));
944 socket->BindToNetDevice(l3->GetNetDevice(i));
945 socket->Bind(InetSocketAddress(iface.GetBroadcast(), AODV_PORT));
946 socket->SetAllowBroadcast(true);
947 socket->SetIpRecvTtl(true);
948 m_socketSubnetBroadcastAddresses.insert(std::make_pair(socket, iface));
949
950 // Add local broadcast record to the routing table
951 Ptr<NetDevice> dev =
952 m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(iface.GetLocal()));
953 RoutingTableEntry rt(/*dev=*/dev,
954 /*dst=*/iface.GetBroadcast(),
955 /*vSeqNo=*/true,
956 /*seqNo=*/0,
957 /*iface=*/iface,
958 /*hops=*/1,
959 /*nextHop=*/iface.GetBroadcast(),
962 }
963 if (m_socketAddresses.empty())
964 {
965 NS_LOG_LOGIC("No aodv interfaces");
967 m_nb.Clear();
969 return;
970 }
971 }
972 else
973 {
974 NS_LOG_LOGIC("Remove address not participating in AODV operation");
975 }
976}
977
978bool
980{
981 NS_LOG_FUNCTION(this << src);
982 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
983 {
984 Ipv4InterfaceAddress iface = j->second;
985 if (src == iface.GetLocal())
986 {
987 return true;
988 }
989 }
990 return false;
991}
992
995{
996 NS_LOG_FUNCTION(this << hdr);
998 Ptr<Ipv4Route> rt = Create<Ipv4Route>();
999 rt->SetDestination(hdr.GetDestination());
1000 //
1001 // Source address selection here is tricky. The loopback route is
1002 // returned when AODV does not have a route; this causes the packet
1003 // to be looped back and handled (cached) in RouteInput() method
1004 // while a route is found. However, connection-oriented protocols
1005 // like TCP need to create an endpoint four-tuple (src, src port,
1006 // dst, dst port) and create a pseudo-header for checksumming. So,
1007 // AODV needs to guess correctly what the eventual source address
1008 // will be.
1009 //
1010 // For single interface, single address nodes, this is not a problem.
1011 // When there are possibly multiple outgoing interfaces, the policy
1012 // implemented here is to pick the first available AODV interface.
1013 // If RouteOutput() caller specified an outgoing interface, that
1014 // further constrains the selection of source address
1015 //
1016 auto j = m_socketAddresses.begin();
1017 if (oif)
1018 {
1019 // Iterate to find an address on the oif device
1020 for (j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
1021 {
1022 Ipv4Address addr = j->second.GetLocal();
1023 int32_t interface = m_ipv4->GetInterfaceForAddress(addr);
1024 if (oif == m_ipv4->GetNetDevice(static_cast<uint32_t>(interface)))
1025 {
1026 rt->SetSource(addr);
1027 break;
1028 }
1029 }
1030 }
1031 else
1032 {
1033 rt->SetSource(j->second.GetLocal());
1034 }
1035 NS_ASSERT_MSG(rt->GetSource() != Ipv4Address(), "Valid AODV source address not found");
1036 rt->SetGateway(Ipv4Address("127.0.0.1"));
1037 rt->SetOutputDevice(m_lo);
1038 return rt;
1039}
1040
1041void
1043{
1044 NS_LOG_FUNCTION(this << dst);
1045 // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
1047 {
1050 this,
1051 dst);
1052 return;
1053 }
1054 else
1055 {
1056 m_rreqCount++;
1057 }
1058 // Create RREQ header
1059 RreqHeader rreqHeader;
1060 rreqHeader.SetDst(dst);
1061
1063 // Using the Hop field in Routing Table to manage the expanding ring search
1064 uint16_t ttl = m_ttlStart;
1065 if (m_routingTable.LookupRoute(dst, rt))
1066 {
1067 if (rt.GetFlag() != IN_SEARCH)
1068 {
1069 ttl = std::min<uint16_t>(rt.GetHop() + m_ttlIncrement, m_netDiameter);
1070 }
1071 else
1072 {
1073 ttl = rt.GetHop() + m_ttlIncrement;
1074 if (ttl > m_ttlThreshold)
1075 {
1076 ttl = m_netDiameter;
1077 }
1078 }
1079 if (ttl == m_netDiameter)
1080 {
1081 rt.IncrementRreqCnt();
1082 }
1083 if (rt.GetValidSeqNo())
1084 {
1085 rreqHeader.SetDstSeqno(rt.GetSeqNo());
1086 }
1087 else
1088 {
1089 rreqHeader.SetUnknownSeqno(true);
1090 }
1091 rt.SetHop(ttl);
1092 rt.SetFlag(IN_SEARCH);
1095 }
1096 else
1097 {
1098 rreqHeader.SetUnknownSeqno(true);
1099 Ptr<NetDevice> dev = nullptr;
1100 RoutingTableEntry newEntry(/*dev=*/dev,
1101 /*dst=*/dst,
1102 /*vSeqNo=*/false,
1103 /*seqNo=*/0,
1104 /*iface=*/Ipv4InterfaceAddress(),
1105 /*hops=*/ttl,
1106 /*nextHop=*/Ipv4Address(),
1107 /*lifetime=*/m_pathDiscoveryTime);
1108 // Check if TtlStart == NetDiameter
1109 if (ttl == m_netDiameter)
1110 {
1111 newEntry.IncrementRreqCnt();
1112 }
1113 newEntry.SetFlag(IN_SEARCH);
1114 m_routingTable.AddRoute(newEntry);
1115 }
1116
1118 {
1119 rreqHeader.SetGratuitousRrep(true);
1120 }
1122 {
1123 rreqHeader.SetDestinationOnly(true);
1124 }
1125
1126 m_seqNo++;
1127 rreqHeader.SetOriginSeqno(m_seqNo);
1128 m_requestId++;
1129 rreqHeader.SetId(m_requestId);
1130
1131 // Send RREQ as subnet directed broadcast from each interface used by aodv
1132 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
1133 {
1134 Ptr<Socket> socket = j->first;
1135 Ipv4InterfaceAddress iface = j->second;
1136
1137 rreqHeader.SetOrigin(iface.GetLocal());
1139
1140 Ptr<Packet> packet = Create<Packet>();
1141 SocketIpTtlTag tag;
1142 tag.SetTtl(ttl);
1143 packet->AddPacketTag(tag);
1144 packet->AddHeader(rreqHeader);
1145 TypeHeader tHeader(AODVTYPE_RREQ);
1146 packet->AddHeader(tHeader);
1147 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1148 Ipv4Address destination;
1149 if (iface.GetMask() == Ipv4Mask::GetOnes())
1150 {
1151 destination = Ipv4Address("255.255.255.255");
1152 }
1153 else
1154 {
1155 destination = iface.GetBroadcast();
1156 }
1157 NS_LOG_DEBUG("Send RREQ with id " << rreqHeader.GetId() << " to socket");
1161 this,
1162 socket,
1163 packet,
1164 destination);
1165 }
1166 ScheduleRreqRetry(dst);
1167}
1168
1169void
1171{
1172 socket->SendTo(packet, 0, InetSocketAddress(destination, AODV_PORT));
1173}
1174
1175void
1177{
1178 NS_LOG_FUNCTION(this << dst);
1179 if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
1180 {
1182 m_addressReqTimer[dst] = timer;
1183 }
1185 m_addressReqTimer[dst].Cancel();
1186 m_addressReqTimer[dst].SetArguments(dst);
1188 m_routingTable.LookupRoute(dst, rt);
1189 Time retry;
1190 if (rt.GetHop() < m_netDiameter)
1191 {
1192 retry = 2 * m_nodeTraversalTime * (rt.GetHop() + m_timeoutBuffer);
1193 }
1194 else
1195 {
1196 NS_ABORT_MSG_UNLESS(rt.GetRreqCnt() > 0, "Unexpected value for GetRreqCount ()");
1197 uint16_t backoffFactor = rt.GetRreqCnt() - 1;
1198 NS_LOG_LOGIC("Applying binary exponential backoff factor " << backoffFactor);
1199 retry = m_netTraversalTime * (1 << backoffFactor);
1200 }
1201 m_addressReqTimer[dst].Schedule(retry);
1202 NS_LOG_LOGIC("Scheduled RREQ retry in " << retry.As(Time::S));
1203}
1204
1205void
1207{
1208 NS_LOG_FUNCTION(this << socket);
1209 Address sourceAddress;
1210 Ptr<Packet> packet = socket->RecvFrom(sourceAddress);
1211 InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom(sourceAddress);
1212 Ipv4Address sender = inetSourceAddr.GetIpv4();
1213 Ipv4Address receiver;
1214
1215 if (m_socketAddresses.find(socket) != m_socketAddresses.end())
1216 {
1217 receiver = m_socketAddresses[socket].GetLocal();
1218 }
1219 else if (m_socketSubnetBroadcastAddresses.find(socket) !=
1221 {
1222 receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal();
1223 }
1224 else
1225 {
1226 NS_ASSERT_MSG(false, "Received a packet from an unknown socket");
1227 }
1228 NS_LOG_DEBUG("AODV node " << this << " received a AODV packet from " << sender << " to "
1229 << receiver);
1230
1231 UpdateRouteToNeighbor(sender, receiver);
1232 TypeHeader tHeader(AODVTYPE_RREQ);
1233 packet->RemoveHeader(tHeader);
1234 if (!tHeader.IsValid())
1235 {
1236 NS_LOG_DEBUG("AODV message " << packet->GetUid() << " with unknown type received: "
1237 << tHeader.Get() << ". Drop");
1238 return; // drop
1239 }
1240 switch (tHeader.Get())
1241 {
1242 case AODVTYPE_RREQ: {
1243 RecvRequest(packet, receiver, sender);
1244 break;
1245 }
1246 case AODVTYPE_RREP: {
1247 RecvReply(packet, receiver, sender);
1248 break;
1249 }
1250 case AODVTYPE_RERR: {
1251 RecvError(packet, sender);
1252 break;
1253 }
1254 case AODVTYPE_RREP_ACK: {
1255 RecvReplyAck(sender);
1256 break;
1257 }
1258 }
1259}
1260
1261bool
1263{
1264 NS_LOG_FUNCTION(this << addr << lifetime);
1266 if (m_routingTable.LookupRoute(addr, rt))
1267 {
1268 if (rt.GetFlag() == VALID)
1269 {
1270 NS_LOG_DEBUG("Updating VALID route");
1271 rt.SetRreqCnt(0);
1272 rt.SetLifeTime(std::max(lifetime, rt.GetLifeTime()));
1274 return true;
1275 }
1276 }
1277 return false;
1278}
1279
1280void
1282{
1283 NS_LOG_FUNCTION(this << "sender " << sender << " receiver " << receiver);
1284 RoutingTableEntry toNeighbor;
1285 if (!m_routingTable.LookupRoute(sender, toNeighbor))
1286 {
1287 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1288 RoutingTableEntry newEntry(
1289 /*dev=*/dev,
1290 /*dst=*/sender,
1291 /*vSeqNo=*/false,
1292 /*seqNo=*/0,
1293 /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1294 /*hops=*/1,
1295 /*nextHop=*/sender,
1296 /*lifetime=*/m_activeRouteTimeout);
1297 m_routingTable.AddRoute(newEntry);
1298 }
1299 else
1300 {
1301 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1302 if (toNeighbor.GetValidSeqNo() && (toNeighbor.GetHop() == 1) &&
1303 (toNeighbor.GetOutputDevice() == dev))
1304 {
1305 toNeighbor.SetLifeTime(std::max(m_activeRouteTimeout, toNeighbor.GetLifeTime()));
1306 }
1307 else
1308 {
1309 RoutingTableEntry newEntry(
1310 /*dev=*/dev,
1311 /*dst=*/sender,
1312 /*vSeqNo=*/false,
1313 /*seqNo=*/0,
1314 /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1315 /*hops=*/1,
1316 /*nextHop=*/sender,
1317 /*lifetime=*/std::max(m_activeRouteTimeout, toNeighbor.GetLifeTime()));
1318 m_routingTable.Update(newEntry);
1319 }
1320 }
1321}
1322
1323void
1325{
1326 NS_LOG_FUNCTION(this);
1327 RreqHeader rreqHeader;
1328 p->RemoveHeader(rreqHeader);
1329
1330 // A node ignores all RREQs received from any node in its blacklist
1331 RoutingTableEntry toPrev;
1332 if (m_routingTable.LookupRoute(src, toPrev))
1333 {
1334 if (toPrev.IsUnidirectional())
1335 {
1336 NS_LOG_DEBUG("Ignoring RREQ from node in blacklist");
1337 return;
1338 }
1339 }
1340
1341 uint32_t id = rreqHeader.GetId();
1342 Ipv4Address origin = rreqHeader.GetOrigin();
1343
1344 /*
1345 * Node checks to determine whether it has received a RREQ with the same Originator IP Address
1346 * and RREQ ID. If such a RREQ has been received, the node silently discards the newly received
1347 * RREQ.
1348 */
1349 if (m_rreqIdCache.IsDuplicate(origin, id))
1350 {
1351 NS_LOG_DEBUG("Ignoring RREQ due to duplicate");
1352 return;
1353 }
1354
1355 // Increment RREQ hop count
1356 uint8_t hop = rreqHeader.GetHopCount() + 1;
1357 rreqHeader.SetHopCount(hop);
1358
1359 /*
1360 * When the reverse route is created or updated, the following actions on the route are also
1361 * carried out:
1362 * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination
1363 * sequence number in the route table entry and copied if greater than the existing value there
1364 * 2. the valid sequence number field is set to true;
1365 * 3. the next hop in the routing table becomes the node from which the RREQ was received
1366 * 4. the hop count is copied from the Hop Count in the RREQ message;
1367 * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1368 * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1369 */
1370 RoutingTableEntry toOrigin;
1371 if (!m_routingTable.LookupRoute(origin, toOrigin))
1372 {
1373 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1374 RoutingTableEntry newEntry(
1375 /*dev=*/dev,
1376 /*dst=*/origin,
1377 /*vSeqNo=*/true,
1378 /*seqNo=*/rreqHeader.GetOriginSeqno(),
1379 /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1380 /*hops=*/hop,
1381 /*nextHop=*/src,
1382 /*lifetime=*/Time(2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime));
1383 m_routingTable.AddRoute(newEntry);
1384 }
1385 else
1386 {
1387 if (toOrigin.GetValidSeqNo())
1388 {
1389 if (int32_t(rreqHeader.GetOriginSeqno()) - int32_t(toOrigin.GetSeqNo()) > 0)
1390 {
1391 toOrigin.SetSeqNo(rreqHeader.GetOriginSeqno());
1392 }
1393 }
1394 else
1395 {
1396 toOrigin.SetSeqNo(rreqHeader.GetOriginSeqno());
1397 }
1398 toOrigin.SetValidSeqNo(true);
1399 toOrigin.SetNextHop(src);
1400 toOrigin.SetOutputDevice(m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver)));
1401 toOrigin.SetInterface(m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0));
1402 toOrigin.SetHop(hop);
1403 toOrigin.SetLifeTime(std::max(Time(2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime),
1404 toOrigin.GetLifeTime()));
1405 m_routingTable.Update(toOrigin);
1406 // m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1407 }
1408
1409 RoutingTableEntry toNeighbor;
1410 if (!m_routingTable.LookupRoute(src, toNeighbor))
1411 {
1412 NS_LOG_DEBUG("Neighbor:" << src << " not found in routing table. Creating an entry");
1413 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1414 RoutingTableEntry newEntry(dev,
1415 src,
1416 false,
1417 rreqHeader.GetOriginSeqno(),
1418 m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1419 1,
1420 src,
1422 m_routingTable.AddRoute(newEntry);
1423 }
1424 else
1425 {
1427 toNeighbor.SetValidSeqNo(false);
1428 toNeighbor.SetSeqNo(rreqHeader.GetOriginSeqno());
1429 toNeighbor.SetFlag(VALID);
1430 toNeighbor.SetOutputDevice(m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver)));
1431 toNeighbor.SetInterface(m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0));
1432 toNeighbor.SetHop(1);
1433 toNeighbor.SetNextHop(src);
1434 m_routingTable.Update(toNeighbor);
1435 }
1437
1438 NS_LOG_LOGIC(receiver << " receive RREQ with hop count "
1439 << static_cast<uint32_t>(rreqHeader.GetHopCount()) << " ID "
1440 << rreqHeader.GetId() << " to destination " << rreqHeader.GetDst());
1441
1442 // A node generates a RREP if either:
1443 // (i) it is itself the destination,
1444 if (IsMyOwnAddress(rreqHeader.GetDst()))
1445 {
1446 m_routingTable.LookupRoute(origin, toOrigin);
1447 NS_LOG_DEBUG("Send reply since I am the destination");
1448 SendReply(rreqHeader, toOrigin);
1449 return;
1450 }
1451 /*
1452 * (ii) or it has an active route to the destination, the destination sequence number in the
1453 * node's existing route table entry for the destination is valid and greater than or equal to
1454 * the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1455 */
1456 RoutingTableEntry toDst;
1457 Ipv4Address dst = rreqHeader.GetDst();
1458 if (m_routingTable.LookupRoute(dst, toDst))
1459 {
1460 /*
1461 * Drop RREQ, This node RREP will make a loop.
1462 */
1463 if (toDst.GetNextHop() == src)
1464 {
1465 NS_LOG_DEBUG("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop());
1466 return;
1467 }
1468 /*
1469 * The Destination Sequence number for the requested destination is set to the maximum of
1470 * the corresponding value received in the RREQ message, and the destination sequence value
1471 * currently maintained by the node for the requested destination. However, the forwarding
1472 * node MUST NOT modify its maintained value for the destination sequence number, even if
1473 * the value received in the incoming RREQ is larger than the value currently maintained by
1474 * the forwarding node.
1475 */
1476 if ((rreqHeader.GetUnknownSeqno() ||
1477 (int32_t(toDst.GetSeqNo()) - int32_t(rreqHeader.GetDstSeqno()) >= 0)) &&
1478 toDst.GetValidSeqNo())
1479 {
1480 if (!rreqHeader.GetDestinationOnly() && toDst.GetFlag() == VALID)
1481 {
1482 m_routingTable.LookupRoute(origin, toOrigin);
1483 SendReplyByIntermediateNode(toDst, toOrigin, rreqHeader.GetGratuitousRrep());
1484 return;
1485 }
1486 rreqHeader.SetDstSeqno(toDst.GetSeqNo());
1487 rreqHeader.SetUnknownSeqno(false);
1488 }
1489 }
1490
1491 SocketIpTtlTag tag;
1492 p->RemovePacketTag(tag);
1493 if (tag.GetTtl() < 2)
1494 {
1495 NS_LOG_DEBUG("TTL exceeded. Drop RREQ origin " << src << " destination " << dst);
1496 return;
1497 }
1498
1499 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
1500 {
1501 Ptr<Socket> socket = j->first;
1502 Ipv4InterfaceAddress iface = j->second;
1503 Ptr<Packet> packet = Create<Packet>();
1504 SocketIpTtlTag ttl;
1505 ttl.SetTtl(tag.GetTtl() - 1);
1506 packet->AddPacketTag(ttl);
1507 packet->AddHeader(rreqHeader);
1508 TypeHeader tHeader(AODVTYPE_RREQ);
1509 packet->AddHeader(tHeader);
1510 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1511 Ipv4Address destination;
1512 if (iface.GetMask() == Ipv4Mask::GetOnes())
1513 {
1514 destination = Ipv4Address("255.255.255.255");
1515 }
1516 else
1517 {
1518 destination = iface.GetBroadcast();
1519 }
1523 this,
1524 socket,
1525 packet,
1526 destination);
1527 }
1528}
1529
1530void
1532{
1533 NS_LOG_FUNCTION(this << toOrigin.GetDestination());
1534 /*
1535 * Destination node MUST increment its own sequence number by one if the sequence number in the
1536 * RREQ packet is equal to that incremented value. Otherwise, the destination does not change
1537 * its sequence number before generating the RREP message.
1538 */
1539 if (!rreqHeader.GetUnknownSeqno() && (rreqHeader.GetDstSeqno() == m_seqNo + 1))
1540 {
1541 m_seqNo++;
1542 }
1543 RrepHeader rrepHeader(/*prefixSize=*/0,
1544 /*hopCount=*/0,
1545 /*dst=*/rreqHeader.GetDst(),
1546 /*dstSeqNo=*/m_seqNo,
1547 /*origin=*/toOrigin.GetDestination(),
1548 /*lifetime=*/m_myRouteTimeout);
1549 Ptr<Packet> packet = Create<Packet>();
1550 SocketIpTtlTag tag;
1551 tag.SetTtl(toOrigin.GetHop());
1552 packet->AddPacketTag(tag);
1553 packet->AddHeader(rrepHeader);
1554 TypeHeader tHeader(AODVTYPE_RREP);
1555 packet->AddHeader(tHeader);
1557 NS_ASSERT(socket);
1558 socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
1559}
1560
1561void
1563 RoutingTableEntry& toOrigin,
1564 bool gratRep)
1565{
1566 NS_LOG_FUNCTION(this);
1567 RrepHeader rrepHeader(/*prefixSize=*/0,
1568 /*hopCount=*/toDst.GetHop(),
1569 /*dst=*/toDst.GetDestination(),
1570 /*dstSeqNo=*/toDst.GetSeqNo(),
1571 /*origin=*/toOrigin.GetDestination(),
1572 /*lifetime=*/toDst.GetLifeTime());
1573 /* If the node we received a RREQ for is a neighbor we are
1574 * probably facing a unidirectional link... Better request a RREP-ack
1575 */
1576 if (toDst.GetHop() == 1)
1577 {
1578 rrepHeader.SetAckRequired(true);
1579 RoutingTableEntry toNextHop;
1580 m_routingTable.LookupRoute(toOrigin.GetNextHop(), toNextHop);
1584 }
1585 toDst.InsertPrecursor(toOrigin.GetNextHop());
1586 toOrigin.InsertPrecursor(toDst.GetNextHop());
1587 m_routingTable.Update(toDst);
1588 m_routingTable.Update(toOrigin);
1589
1590 Ptr<Packet> packet = Create<Packet>();
1591 SocketIpTtlTag tag;
1592 tag.SetTtl(toOrigin.GetHop());
1593 packet->AddPacketTag(tag);
1594 packet->AddHeader(rrepHeader);
1595 TypeHeader tHeader(AODVTYPE_RREP);
1596 packet->AddHeader(tHeader);
1598 NS_ASSERT(socket);
1599 socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
1600
1601 // Generating gratuitous RREPs
1602 if (gratRep)
1603 {
1604 RrepHeader gratRepHeader(/*prefixSize=*/0,
1605 /*hopCount=*/toOrigin.GetHop(),
1606 /*dst=*/toOrigin.GetDestination(),
1607 /*dstSeqNo=*/toOrigin.GetSeqNo(),
1608 /*origin=*/toDst.GetDestination(),
1609 /*lifetime=*/toOrigin.GetLifeTime());
1610 Ptr<Packet> packetToDst = Create<Packet>();
1611 SocketIpTtlTag gratTag;
1612 gratTag.SetTtl(toDst.GetHop());
1613 packetToDst->AddPacketTag(gratTag);
1614 packetToDst->AddHeader(gratRepHeader);
1616 packetToDst->AddHeader(type);
1618 NS_ASSERT(socket);
1619 NS_LOG_LOGIC("Send gratuitous RREP " << packet->GetUid());
1620 socket->SendTo(packetToDst, 0, InetSocketAddress(toDst.GetNextHop(), AODV_PORT));
1621 }
1622}
1623
1624void
1626{
1627 NS_LOG_FUNCTION(this << " to " << neighbor);
1628 RrepAckHeader h;
1629 TypeHeader typeHeader(AODVTYPE_RREP_ACK);
1630 Ptr<Packet> packet = Create<Packet>();
1631 SocketIpTtlTag tag;
1632 tag.SetTtl(1);
1633 packet->AddPacketTag(tag);
1634 packet->AddHeader(h);
1635 packet->AddHeader(typeHeader);
1636 RoutingTableEntry toNeighbor;
1637 m_routingTable.LookupRoute(neighbor, toNeighbor);
1639 NS_ASSERT(socket);
1640 socket->SendTo(packet, 0, InetSocketAddress(neighbor, AODV_PORT));
1641}
1642
1643void
1645{
1646 NS_LOG_FUNCTION(this << " src " << sender);
1647 RrepHeader rrepHeader;
1648 p->RemoveHeader(rrepHeader);
1649 Ipv4Address dst = rrepHeader.GetDst();
1650 NS_LOG_LOGIC("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin());
1651
1652 uint8_t hop = rrepHeader.GetHopCount() + 1;
1653 rrepHeader.SetHopCount(hop);
1654
1655 // If RREP is Hello message
1656 if (dst == rrepHeader.GetOrigin())
1657 {
1658 ProcessHello(rrepHeader, receiver);
1659 return;
1660 }
1661
1662 /*
1663 * If the route table entry to the destination is created or updated, then the following actions
1664 * occur:
1665 * - the route is marked as active,
1666 * - the destination sequence number is marked as valid,
1667 * - the next hop in the route entry is assigned to be the node from which the RREP is
1668 * received, which is indicated by the source IP address field in the IP header,
1669 * - the hop count is set to the value of the hop count from RREP message + 1
1670 * - the expiry time is set to the current time plus the value of the Lifetime in the RREP
1671 * message,
1672 * - and the destination sequence number is the Destination Sequence Number in the RREP
1673 * message.
1674 */
1675 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1676 RoutingTableEntry newEntry(
1677 /*dev=*/dev,
1678 /*dst=*/dst,
1679 /*vSeqNo=*/true,
1680 /*seqNo=*/rrepHeader.GetDstSeqno(),
1681 /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1682 /*hops=*/hop,
1683 /*nextHop=*/sender,
1684 /*lifetime=*/rrepHeader.GetLifeTime());
1685 RoutingTableEntry toDst;
1686 if (m_routingTable.LookupRoute(dst, toDst))
1687 {
1688 /*
1689 * The existing entry is updated only in the following circumstances:
1690 * (i) the sequence number in the routing table is marked as invalid in route table entry.
1691 */
1692 if (!toDst.GetValidSeqNo())
1693 {
1694 m_routingTable.Update(newEntry);
1695 }
1696 // (ii)the Destination Sequence Number in the RREP is greater than the node's copy of the
1697 // destination sequence number and the known value is valid,
1698 else if ((int32_t(rrepHeader.GetDstSeqno()) - int32_t(toDst.GetSeqNo())) > 0)
1699 {
1700 m_routingTable.Update(newEntry);
1701 }
1702 else
1703 {
1704 // (iii) the sequence numbers are the same, but the route is marked as inactive.
1705 if ((rrepHeader.GetDstSeqno() == toDst.GetSeqNo()) && (toDst.GetFlag() != VALID))
1706 {
1707 m_routingTable.Update(newEntry);
1708 }
1709 // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the
1710 // hop count in route table entry.
1711 else if ((rrepHeader.GetDstSeqno() == toDst.GetSeqNo()) && (hop < toDst.GetHop()))
1712 {
1713 m_routingTable.Update(newEntry);
1714 }
1715 }
1716 }
1717 else
1718 {
1719 // The forward route for this destination is created if it does not already exist.
1720 NS_LOG_LOGIC("add new route");
1721 m_routingTable.AddRoute(newEntry);
1722 }
1723 // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1724 if (rrepHeader.GetAckRequired())
1725 {
1726 SendReplyAck(sender);
1727 rrepHeader.SetAckRequired(false);
1728 }
1729 NS_LOG_LOGIC("receiver " << receiver << " origin " << rrepHeader.GetOrigin());
1730 if (IsMyOwnAddress(rrepHeader.GetOrigin()))
1731 {
1732 if (toDst.GetFlag() == IN_SEARCH)
1733 {
1734 m_routingTable.Update(newEntry);
1735 m_addressReqTimer[dst].Cancel();
1736 m_addressReqTimer.erase(dst);
1737 }
1738 m_routingTable.LookupRoute(dst, toDst);
1739 SendPacketFromQueue(dst, toDst.GetRoute());
1740 return;
1741 }
1742
1743 RoutingTableEntry toOrigin;
1744 if (!m_routingTable.LookupRoute(rrepHeader.GetOrigin(), toOrigin) ||
1745 toOrigin.GetFlag() == IN_SEARCH)
1746 {
1747 return; // Impossible! drop.
1748 }
1749 toOrigin.SetLifeTime(std::max(m_activeRouteTimeout, toOrigin.GetLifeTime()));
1750 m_routingTable.Update(toOrigin);
1751
1752 // Update information about precursors
1753 if (m_routingTable.LookupValidRoute(rrepHeader.GetDst(), toDst))
1754 {
1755 toDst.InsertPrecursor(toOrigin.GetNextHop());
1756 m_routingTable.Update(toDst);
1757
1758 RoutingTableEntry toNextHopToDst;
1759 m_routingTable.LookupRoute(toDst.GetNextHop(), toNextHopToDst);
1760 toNextHopToDst.InsertPrecursor(toOrigin.GetNextHop());
1761 m_routingTable.Update(toNextHopToDst);
1762
1763 toOrigin.InsertPrecursor(toDst.GetNextHop());
1764 m_routingTable.Update(toOrigin);
1765
1766 RoutingTableEntry toNextHopToOrigin;
1767 m_routingTable.LookupRoute(toOrigin.GetNextHop(), toNextHopToOrigin);
1768 toNextHopToOrigin.InsertPrecursor(toDst.GetNextHop());
1769 m_routingTable.Update(toNextHopToOrigin);
1770 }
1771 SocketIpTtlTag tag;
1772 p->RemovePacketTag(tag);
1773 if (tag.GetTtl() < 2)
1774 {
1775 NS_LOG_DEBUG("TTL exceeded. Drop RREP destination " << dst << " origin "
1776 << rrepHeader.GetOrigin());
1777 return;
1778 }
1779
1780 Ptr<Packet> packet = Create<Packet>();
1781 SocketIpTtlTag ttl;
1782 ttl.SetTtl(tag.GetTtl() - 1);
1783 packet->AddPacketTag(ttl);
1784 packet->AddHeader(rrepHeader);
1785 TypeHeader tHeader(AODVTYPE_RREP);
1786 packet->AddHeader(tHeader);
1788 NS_ASSERT(socket);
1789 socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
1790}
1791
1792void
1794{
1795 NS_LOG_FUNCTION(this);
1797 if (m_routingTable.LookupRoute(neighbor, rt))
1798 {
1799 rt.m_ackTimer.Cancel();
1800 rt.SetFlag(VALID);
1802 }
1803}
1804
1805void
1807{
1808 NS_LOG_FUNCTION(this << "from " << rrepHeader.GetDst());
1809 /*
1810 * Whenever a node receives a Hello message from a neighbor, the node
1811 * SHOULD make sure that it has an active route to the neighbor, and
1812 * create one if necessary.
1813 */
1814 RoutingTableEntry toNeighbor;
1815 if (!m_routingTable.LookupRoute(rrepHeader.GetDst(), toNeighbor))
1816 {
1817 Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver));
1818 RoutingTableEntry newEntry(
1819 /*dev=*/dev,
1820 /*dst=*/rrepHeader.GetDst(),
1821 /*vSeqNo=*/true,
1822 /*seqNo=*/rrepHeader.GetDstSeqno(),
1823 /*iface=*/m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0),
1824 /*hops=*/1,
1825 /*nextHop=*/rrepHeader.GetDst(),
1826 /*lifetime=*/rrepHeader.GetLifeTime());
1827 m_routingTable.AddRoute(newEntry);
1828 }
1829 else
1830 {
1831 toNeighbor.SetLifeTime(
1832 std::max(Time(m_allowedHelloLoss * m_helloInterval), toNeighbor.GetLifeTime()));
1833 toNeighbor.SetSeqNo(rrepHeader.GetDstSeqno());
1834 toNeighbor.SetValidSeqNo(true);
1835 toNeighbor.SetFlag(VALID);
1836 toNeighbor.SetOutputDevice(m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(receiver)));
1837 toNeighbor.SetInterface(m_ipv4->GetAddress(m_ipv4->GetInterfaceForAddress(receiver), 0));
1838 toNeighbor.SetHop(1);
1839 toNeighbor.SetNextHop(rrepHeader.GetDst());
1840 m_routingTable.Update(toNeighbor);
1841 }
1842 if (m_enableHello)
1843 {
1845 }
1846}
1847
1848void
1850{
1851 NS_LOG_FUNCTION(this << " from " << src);
1852 RerrHeader rerrHeader;
1853 p->RemoveHeader(rerrHeader);
1854 std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1855 std::map<Ipv4Address, uint32_t> unreachable;
1856 m_routingTable.GetListOfDestinationWithNextHop(src, dstWithNextHopSrc);
1857 std::pair<Ipv4Address, uint32_t> un;
1858 while (rerrHeader.RemoveUnDestination(un))
1859 {
1860 for (auto i = dstWithNextHopSrc.begin(); i != dstWithNextHopSrc.end(); ++i)
1861 {
1862 if (i->first == un.first)
1863 {
1864 unreachable.insert(un);
1865 }
1866 }
1867 }
1868
1869 std::vector<Ipv4Address> precursors;
1870 for (auto i = unreachable.begin(); i != unreachable.end();)
1871 {
1872 if (!rerrHeader.AddUnDestination(i->first, i->second))
1873 {
1874 TypeHeader typeHeader(AODVTYPE_RERR);
1875 Ptr<Packet> packet = Create<Packet>();
1876 SocketIpTtlTag tag;
1877 tag.SetTtl(1);
1878 packet->AddPacketTag(tag);
1879 packet->AddHeader(rerrHeader);
1880 packet->AddHeader(typeHeader);
1881 SendRerrMessage(packet, precursors);
1882 rerrHeader.Clear();
1883 }
1884 else
1885 {
1886 RoutingTableEntry toDst;
1887 m_routingTable.LookupRoute(i->first, toDst);
1888 toDst.GetPrecursors(precursors);
1889 ++i;
1890 }
1891 }
1892 if (rerrHeader.GetDestCount() != 0)
1893 {
1894 TypeHeader typeHeader(AODVTYPE_RERR);
1895 Ptr<Packet> packet = Create<Packet>();
1896 SocketIpTtlTag tag;
1897 tag.SetTtl(1);
1898 packet->AddPacketTag(tag);
1899 packet->AddHeader(rerrHeader);
1900 packet->AddHeader(typeHeader);
1901 SendRerrMessage(packet, precursors);
1902 }
1904}
1905
1906void
1908{
1909 NS_LOG_LOGIC(this);
1910 RoutingTableEntry toDst;
1911 if (m_routingTable.LookupValidRoute(dst, toDst))
1912 {
1913 SendPacketFromQueue(dst, toDst.GetRoute());
1914 NS_LOG_LOGIC("route to " << dst << " found");
1915 return;
1916 }
1917 /*
1918 * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1919 * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1920 * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the
1921 * application.
1922 */
1923 if (toDst.GetRreqCnt() == m_rreqRetries)
1924 {
1925 NS_LOG_LOGIC("route discovery to " << dst << " has been attempted RreqRetries ("
1926 << m_rreqRetries << ") times with ttl "
1927 << m_netDiameter);
1928 m_addressReqTimer.erase(dst);
1930 NS_LOG_DEBUG("Route not found. Drop all packets with dst " << dst);
1932 return;
1933 }
1934
1935 if (toDst.GetFlag() == IN_SEARCH)
1936 {
1937 NS_LOG_LOGIC("Resend RREQ to " << dst << " previous ttl " << toDst.GetHop());
1938 SendRequest(dst);
1939 }
1940 else
1941 {
1942 NS_LOG_DEBUG("Route down. Stop search. Drop packet with destination " << dst);
1943 m_addressReqTimer.erase(dst);
1946 }
1947}
1948
1949void
1951{
1952 NS_LOG_FUNCTION(this);
1953 Time offset = Time(Seconds(0));
1954 if (m_lastBcastTime > Time(Seconds(0)))
1955 {
1956 offset = Simulator::Now() - m_lastBcastTime;
1957 NS_LOG_DEBUG("Hello deferred due to last bcast at:" << m_lastBcastTime);
1958 }
1959 else
1960 {
1961 SendHello();
1962 }
1963 m_htimer.Cancel();
1964 Time diff = m_helloInterval - offset;
1965 m_htimer.Schedule(std::max(Time(Seconds(0)), diff));
1967}
1968
1969void
1971{
1972 NS_LOG_FUNCTION(this);
1973 m_rreqCount = 0;
1975}
1976
1977void
1979{
1980 NS_LOG_FUNCTION(this);
1981 m_rerrCount = 0;
1983}
1984
1985void
1987{
1988 NS_LOG_FUNCTION(this);
1989 m_routingTable.MarkLinkAsUnidirectional(neighbor, blacklistTimeout);
1990}
1991
1992void
1994{
1995 NS_LOG_FUNCTION(this);
1996 /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1997 * Destination IP Address The node's IP address.
1998 * Destination Sequence Number The node's latest sequence number.
1999 * Hop Count 0
2000 * Lifetime AllowedHelloLoss * HelloInterval
2001 */
2002 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
2003 {
2004 Ptr<Socket> socket = j->first;
2005 Ipv4InterfaceAddress iface = j->second;
2006 RrepHeader helloHeader(/*prefixSize=*/0,
2007 /*hopCount=*/0,
2008 /*dst=*/iface.GetLocal(),
2009 /*dstSeqNo=*/m_seqNo,
2010 /*origin=*/iface.GetLocal(),
2011 /*lifetime=*/Time(m_allowedHelloLoss * m_helloInterval));
2012 Ptr<Packet> packet = Create<Packet>();
2013 SocketIpTtlTag tag;
2014 tag.SetTtl(1);
2015 packet->AddPacketTag(tag);
2016 packet->AddHeader(helloHeader);
2017 TypeHeader tHeader(AODVTYPE_RREP);
2018 packet->AddHeader(tHeader);
2019 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2020 Ipv4Address destination;
2021 if (iface.GetMask() == Ipv4Mask::GetOnes())
2022 {
2023 destination = Ipv4Address("255.255.255.255");
2024 }
2025 else
2026 {
2027 destination = iface.GetBroadcast();
2028 }
2030 Simulator::Schedule(jitter, &RoutingProtocol::SendTo, this, socket, packet, destination);
2031 }
2032}
2033
2034void
2036{
2037 NS_LOG_FUNCTION(this);
2038 QueueEntry queueEntry;
2039 while (m_queue.Dequeue(dst, queueEntry))
2040 {
2042 Ptr<Packet> p = ConstCast<Packet>(queueEntry.GetPacket());
2043 if (p->RemovePacketTag(tag) && tag.GetInterface() != -1 &&
2044 tag.GetInterface() != m_ipv4->GetInterfaceForDevice(route->GetOutputDevice()))
2045 {
2046 NS_LOG_DEBUG("Output device doesn't match. Dropped.");
2047 return;
2048 }
2050 Ipv4Header header = queueEntry.GetIpv4Header();
2051 header.SetSource(route->GetSource());
2052 header.SetTtl(header.GetTtl() +
2053 1); // compensate extra TTL decrement by fake loopback routing
2054 ucb(route, p, header);
2055 }
2056}
2057
2058void
2060{
2061 NS_LOG_FUNCTION(this << nextHop);
2062 RerrHeader rerrHeader;
2063 std::vector<Ipv4Address> precursors;
2064 std::map<Ipv4Address, uint32_t> unreachable;
2065
2066 RoutingTableEntry toNextHop;
2067 if (!m_routingTable.LookupRoute(nextHop, toNextHop))
2068 {
2069 return;
2070 }
2071 toNextHop.GetPrecursors(precursors);
2072 rerrHeader.AddUnDestination(nextHop, toNextHop.GetSeqNo());
2073 m_routingTable.GetListOfDestinationWithNextHop(nextHop, unreachable);
2074 for (auto i = unreachable.begin(); i != unreachable.end();)
2075 {
2076 if (!rerrHeader.AddUnDestination(i->first, i->second))
2077 {
2078 NS_LOG_LOGIC("Send RERR message with maximum size.");
2079 TypeHeader typeHeader(AODVTYPE_RERR);
2080 Ptr<Packet> packet = Create<Packet>();
2081 SocketIpTtlTag tag;
2082 tag.SetTtl(1);
2083 packet->AddPacketTag(tag);
2084 packet->AddHeader(rerrHeader);
2085 packet->AddHeader(typeHeader);
2086 SendRerrMessage(packet, precursors);
2087 rerrHeader.Clear();
2088 }
2089 else
2090 {
2091 RoutingTableEntry toDst;
2092 m_routingTable.LookupRoute(i->first, toDst);
2093 toDst.GetPrecursors(precursors);
2094 ++i;
2095 }
2096 }
2097 if (rerrHeader.GetDestCount() != 0)
2098 {
2099 TypeHeader typeHeader(AODVTYPE_RERR);
2100 Ptr<Packet> packet = Create<Packet>();
2101 SocketIpTtlTag tag;
2102 tag.SetTtl(1);
2103 packet->AddPacketTag(tag);
2104 packet->AddHeader(rerrHeader);
2105 packet->AddHeader(typeHeader);
2106 SendRerrMessage(packet, precursors);
2107 }
2108 unreachable.insert(std::make_pair(nextHop, toNextHop.GetSeqNo()));
2110}
2111
2112void
2114 uint32_t dstSeqNo,
2115 Ipv4Address origin)
2116{
2117 NS_LOG_FUNCTION(this);
2118 // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2120 {
2121 // Just make sure that the RerrRateLimit timer is running and will expire
2123 // discard the packet and return
2124 NS_LOG_LOGIC("RerrRateLimit reached at "
2125 << Simulator::Now().As(Time::S) << " with timer delay left "
2126 << m_rerrRateLimitTimer.GetDelayLeft().As(Time::S) << "; suppressing RERR");
2127 return;
2128 }
2129 RerrHeader rerrHeader;
2130 rerrHeader.AddUnDestination(dst, dstSeqNo);
2131 RoutingTableEntry toOrigin;
2132 Ptr<Packet> packet = Create<Packet>();
2133 SocketIpTtlTag tag;
2134 tag.SetTtl(1);
2135 packet->AddPacketTag(tag);
2136 packet->AddHeader(rerrHeader);
2137 packet->AddHeader(TypeHeader(AODVTYPE_RERR));
2138 if (m_routingTable.LookupValidRoute(origin, toOrigin))
2139 {
2141 NS_ASSERT(socket);
2142 NS_LOG_LOGIC("Unicast RERR to the source of the data transmission");
2143 socket->SendTo(packet, 0, InetSocketAddress(toOrigin.GetNextHop(), AODV_PORT));
2144 }
2145 else
2146 {
2147 for (auto i = m_socketAddresses.begin(); i != m_socketAddresses.end(); ++i)
2148 {
2149 Ptr<Socket> socket = i->first;
2150 Ipv4InterfaceAddress iface = i->second;
2151 NS_ASSERT(socket);
2152 NS_LOG_LOGIC("Broadcast RERR message from interface " << iface.GetLocal());
2153 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2154 Ipv4Address destination;
2155 if (iface.GetMask() == Ipv4Mask::GetOnes())
2156 {
2157 destination = Ipv4Address("255.255.255.255");
2158 }
2159 else
2160 {
2161 destination = iface.GetBroadcast();
2162 }
2163 socket->SendTo(packet->Copy(), 0, InetSocketAddress(destination, AODV_PORT));
2164 }
2165 }
2166}
2167
2168void
2169RoutingProtocol::SendRerrMessage(Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
2170{
2171 NS_LOG_FUNCTION(this);
2172
2173 if (precursors.empty())
2174 {
2175 NS_LOG_LOGIC("No precursors");
2176 return;
2177 }
2178 // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2180 {
2181 // Just make sure that the RerrRateLimit timer is running and will expire
2183 // discard the packet and return
2184 NS_LOG_LOGIC("RerrRateLimit reached at "
2185 << Simulator::Now().As(Time::S) << " with timer delay left "
2186 << m_rerrRateLimitTimer.GetDelayLeft().As(Time::S) << "; suppressing RERR");
2187 return;
2188 }
2189 // If there is only one precursor, RERR SHOULD be unicast toward that precursor
2190 if (precursors.size() == 1)
2191 {
2192 RoutingTableEntry toPrecursor;
2193 if (m_routingTable.LookupValidRoute(precursors.front(), toPrecursor))
2194 {
2196 NS_ASSERT(socket);
2197 NS_LOG_LOGIC("one precursor => unicast RERR to "
2198 << toPrecursor.GetDestination() << " from "
2199 << toPrecursor.GetInterface().GetLocal());
2202 this,
2203 socket,
2204 packet,
2205 precursors.front());
2206 m_rerrCount++;
2207 }
2208 return;
2209 }
2210
2211 // Should only transmit RERR on those interfaces which have precursor nodes for the broken
2212 // route
2213 std::vector<Ipv4InterfaceAddress> ifaces;
2214 RoutingTableEntry toPrecursor;
2215 for (auto i = precursors.begin(); i != precursors.end(); ++i)
2216 {
2217 if (m_routingTable.LookupValidRoute(*i, toPrecursor) &&
2218 std::find(ifaces.begin(), ifaces.end(), toPrecursor.GetInterface()) == ifaces.end())
2219 {
2220 ifaces.push_back(toPrecursor.GetInterface());
2221 }
2222 }
2223
2224 for (auto i = ifaces.begin(); i != ifaces.end(); ++i)
2225 {
2227 NS_ASSERT(socket);
2228 NS_LOG_LOGIC("Broadcast RERR message from interface " << i->GetLocal());
2229 // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
2230 // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2231 Ptr<Packet> p = packet->Copy();
2232 Ipv4Address destination;
2233 if (i->GetMask() == Ipv4Mask::GetOnes())
2234 {
2235 destination = Ipv4Address("255.255.255.255");
2236 }
2237 else
2238 {
2239 destination = i->GetBroadcast();
2240 }
2243 this,
2244 socket,
2245 p,
2246 destination);
2247 }
2248}
2249
2252{
2253 NS_LOG_FUNCTION(this << addr);
2254 for (auto j = m_socketAddresses.begin(); j != m_socketAddresses.end(); ++j)
2255 {
2256 Ptr<Socket> socket = j->first;
2257 Ipv4InterfaceAddress iface = j->second;
2258 if (iface == addr)
2259 {
2260 return socket;
2261 }
2262 }
2263 Ptr<Socket> socket;
2264 return socket;
2265}
2266
2269{
2270 NS_LOG_FUNCTION(this << addr);
2271 for (auto j = m_socketSubnetBroadcastAddresses.begin();
2273 ++j)
2274 {
2275 Ptr<Socket> socket = j->first;
2276 Ipv4InterfaceAddress iface = j->second;
2277 if (iface == addr)
2278 {
2279 return socket;
2280 }
2281 }
2282 Ptr<Socket> socket;
2283 return socket;
2284}
2285
2286void
2288{
2289 NS_LOG_FUNCTION(this);
2290 uint32_t startTime;
2291 if (m_enableHello)
2292 {
2294 startTime = m_uniformRandomVariable->GetInteger(0, 100);
2295 NS_LOG_DEBUG("Starting at time " << startTime << "ms");
2296 m_htimer.Schedule(MilliSeconds(startTime));
2297 }
2299}
2300
2301} // namespace aodv
2302} // namespace ns3
a polymophic address class
Definition: address.h:101
Wifi MAC high model for an ad-hoc Wifi MAC.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
an Inet address class
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetLoopback()
bool IsMulticast() const
static Ipv4Address GetBroadcast()
bool IsBroadcast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
uint8_t GetProtocol() const
Definition: ipv4-header.cc:281
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:267
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
uint8_t GetTtl() const
Definition: ipv4-header.cc:274
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:295
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
Ipv4Address GetLocal() const
Get the local address.
Ipv4Address GetBroadcast() const
Get the broadcast address.
Implement the IPv4 layer.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
static Ipv4Mask GetOnes()
Abstract base class for IPv4 routing protocols.
A network Node.
Definition: node.h:57
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:451
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
Definition: simulator.cc:311
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1124
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:604
uint8_t GetTtl() const
Get the tag's TTL.
Definition: socket.cc:611
Hold variables of type string.
Definition: string.h:56
read and write tag data
Definition: tag-buffer.h:52
TAG_BUFFER_INLINE uint32_t ReadU32()
Definition: tag-buffer.h:217
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:187
tag a set of bytes in a packet
Definition: tag.h:39
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1406
A simple virtual Timer class.
Definition: timer.h:78
void SetDelay(const Time &delay)
Definition: timer.cc:76
void SetFunction(FN fn)
Definition: timer.h:279
Time GetDelayLeft() const
Definition: timer.cc:90
void SetArguments(Ts... args)
Definition: timer.h:295
@ CANCEL_ON_DESTROY
This policy cancels the event from the destructor of the Timer or from Suspend().
Definition: timer.h:97
void Cancel()
Cancel the currently-running event if there is one.
Definition: timer.cc:108
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:162
bool IsRunning() const
Definition: timer.cc:129
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Packet header for UDP packets.
Definition: udp-header.h:41
uint16_t GetDestinationPort() const
Definition: udp-header.cc:54
static const uint8_t PROT_NUMBER
protocol number (0x11)
static TypeId GetTypeId()
Get the type ID.
Hold an unsigned integer type.
Definition: uinteger.h:45
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
Hold together all Wifi-related objects.
Tag used by AODV implementation.
uint32_t GetSerializedSize() const override
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
static TypeId GetTypeId()
Get the type ID.
void Deserialize(TagBuffer i) override
int32_t GetInterface() const
Get the output interface.
int32_t m_oif
Positive if output device is fixed in RouteOutput.
void SetInterface(int32_t oif)
Set the output interface.
void Serialize(TagBuffer i) const override
DeferredRouteOutputTag(int32_t o=-1)
Constructor.
void Print(std::ostream &os) const override
bool IsDuplicate(Ptr< const Packet > p, const Ipv4Header &header)
Check if the packet is a duplicate.
Definition: aodv-dpd.cc:30
bool IsDuplicate(Ipv4Address addr, uint32_t id)
Check that entry (addr, id) exists in cache.
void ScheduleTimer()
Schedule m_ntimer.
void Clear()
Remove all entries.
void Update(Ipv4Address addr, Time expire)
Update expire time for entry with address addr, if it exists, else add new entry.
Callback< void, const WifiMacHeader & > GetTxErrorCallback() const
Get callback to ProcessTxError.
void SetCallback(Callback< void, Ipv4Address > cb)
Set link failure callback.
void DelArpCache(Ptr< ArpCache > a)
Don't use given ARP cache any more (interface is down)
void AddArpCache(Ptr< ArpCache > a)
Add ARP cache to be used to allow layer 2 notifications processing.
AODV Queue Entry.
Definition: aodv-rqueue.h:45
Ipv4Header GetIpv4Header() const
Get IPv4 header.
Definition: aodv-rqueue.h:145
Ptr< const Packet > GetPacket() const
Get packet from entry.
Definition: aodv-rqueue.h:127
UnicastForwardCallback GetUnicastForwardCallback() const
Get unicast forward callback.
Definition: aodv-rqueue.h:91
bool Dequeue(Ipv4Address dst, QueueEntry &entry)
Return first found (the earliest) entry for given destination.
Definition: aodv-rqueue.cc:91
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
Definition: aodv-rqueue.h:257
void SetQueueTimeout(Time t)
Set queue timeout.
Definition: aodv-rqueue.h:275
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:73
bool Enqueue(QueueEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
Definition: aodv-rqueue.cc:51
Route Error (RERR) Message Format.
Definition: aodv-packet.h:592
uint8_t GetDestCount() const
Definition: aodv-packet.h:640
void Clear()
Clear header.
Definition: aodv-packet.cc:643
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Add unreachable node address and its sequence number in RERR header.
Definition: aodv-packet.cc:617
bool RemoveUnDestination(std::pair< Ipv4Address, uint32_t > &un)
Delete pair (address + sequence number) from REER header, if the number of unreachable destinations >...
Definition: aodv-packet.cc:630
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
uint32_t m_requestId
Broadcast ID.
void RecvAodv(Ptr< Socket > socket)
Receive and process control packet.
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Update neighbor record.
Timer m_rerrRateLimitTimer
RERR rate limit timer.
Time m_lastBcastTime
Keep track of the last bcast time.
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
bool m_enableBroadcast
Indicates whether a a broadcast data packets forwarding enable.
bool GetBroadcastEnable() const
Get broadcast enable flag.
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Set lifetime field in routing table entry to the maximum of existing lifetime and lt,...
void RerrRateLimitTimerExpire()
Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
Time m_blackListTimeout
Time for which the node is put into the blacklist.
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses
Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP.
Time m_maxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
Time m_activeRouteTimeout
Period of time during which the route is considered to be valid.
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
uint32_t GetMaxQueueLen() const
Get the maximum queue length.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet and send route request.
void SendTo(Ptr< Socket > socket, Ptr< Packet > packet, Ipv4Address destination)
Send packet to destination socket.
DuplicatePacketDetection m_dpd
Handle duplicated broadcast/multicast packets.
Time m_netTraversalTime
Estimate of the average net traversal time.
void DoDispose() override
Destructor implementation.
void SendRequest(Ipv4Address dst)
Send RREQ.
Time m_pathDiscoveryTime
Estimate of maximum time needed to find route in network.
bool m_gratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
void HelloTimerExpire()
Schedule next send of hello message.
void NotifyTxError(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Notify that an MPDU was dropped.
RoutingTable m_routingTable
Routing table.
uint16_t m_rreqRateLimit
Maximum number of RREQ per second.
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
uint32_t m_netDiameter
Net diameter measures the maximum possible number of hops between two nodes in the network.
uint32_t m_maxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
uint16_t m_ttlThreshold
Maximum TTL value for expanding ring search, TTL = NetDiameter is used beyond this value.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetMaxQueueTime(Time t)
Set the maximum queue time.
uint16_t m_ttlIncrement
TTL increment for each attempt using the expanding ring search for RREQ dissemination.
Time m_myRouteTimeout
Value of lifetime field in RREP generating by this node.
uint16_t m_timeoutBuffer
Provide a buffer for the timeout.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find unicast socket with local interface address iface.
void NotifyInterfaceDown(uint32_t interface) override
void SetBroadcastEnable(bool f)
Set broadcast enable flag.
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
Forward packet from route request queue.
uint32_t m_allowedHelloLoss
Number of hello messages which may be loss for valid link.
bool IsMyOwnAddress(Ipv4Address src)
Test whether the provided address is assigned to an interface on this node.
void SetMaxQueueLen(uint32_t len)
Set the maximum queue length.
void ScheduleRreqRetry(Ipv4Address dst)
Repeated attempts by a source node at route discovery for a single destination use the expanding ring...
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
Send RREP by intermediate node.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw unicast socket per each IP interface, map socket -> iface address (IP + mask)
void SetGratuitousReplyFlag(bool f)
Set gratuitous reply flag.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
void Start()
Start protocol operation.
uint16_t m_rreqCount
Number of RREQs used for RREQ rate control.
IdCache m_rreqIdCache
Handle duplicated RREQ.
Time m_deletePeriod
DeletePeriod is intended to provide an upper bound on the time for which an upstream node A can have ...
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
Send RERR message when no route to forward input packet.
Time m_helloInterval
Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval.
void AckTimerExpire(Ipv4Address neighbor, Time blacklistTimeout)
Mark link to neighbor node as unidirectional for blacklistTimeout.
void SetHelloEnable(bool f)
Set hello enable.
bool m_destinationOnly
Indicates only the destination may respond to this RREQ.
void SetIpv4(Ptr< Ipv4 > ipv4) override
static TypeId GetTypeId()
Get the type ID.
void SetDestinationOnlyFlag(bool f)
Set destination only flag.
bool GetDestinationOnlyFlag() const
Get destination only flag.
void SendRerrMessage(Ptr< Packet > packet, std::vector< Ipv4Address > precursors)
Forward RERR.
uint16_t m_ttlStart
Initial TTL value for RREQ.
uint32_t m_rreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
uint32_t m_seqNo
Request sequence number.
bool m_enableHello
Indicates whether a hello messages enable.
Neighbors m_nb
Handle neighbors.
bool Forwarding(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
If route exists and is valid, forward packet.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
static const uint32_t AODV_PORT
UDP Port for AODV control traffic.
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
Time GetMaxQueueTime() const
Get maximum queue time.
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Time m_nodeTraversalTime
NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets and sh...
uint16_t m_rerrRateLimit
Maximum number of REER per second.
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
Ptr< Socket > FindSubnetBroadcastSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find subnet directed broadcast socket with local interface address iface.
void DoInitialize() override
Initialize() implementation.
bool GetHelloEnable() const
Get hello enable flag.
void SendRerrWhenBreaksLinkToNextHop(Ipv4Address nextHop)
Initiate RERR.
void RouteRequestTimerExpire(Ipv4Address dst)
Handle route discovery process.
void NotifyInterfaceUp(uint32_t interface) override
bool GetGratuitousReplyFlag() const
Get gratuitous reply flag.
void RecvError(Ptr< Packet > p, Ipv4Address src)
Receive RERR.
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
Time m_nextHopWait
Period of our waiting for the neighbour's RREP_ACK.
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
Ptr< Ipv4 > m_ipv4
IP protocol.
void RreqRateLimitTimerExpire()
Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
void ProcessHello(const RrepHeader &rrepHeader, Ipv4Address receiverIfaceAddr)
Process hello message.
void SendReply(const RreqHeader &rreqHeader, const RoutingTableEntry &toOrigin)
Send RREP.
RequestQueue m_queue
A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route.
Routing table entry.
Definition: aodv-rtable.h:62
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:362
void SetHop(uint16_t hop)
Set the number of hops.
Definition: aodv-rtable.h:249
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn't yet exist in the list.
Definition: aodv-rtable.cc:79
Ptr< NetDevice > GetOutputDevice() const
Get output device.
Definition: aodv-rtable.h:186
uint8_t GetRreqCnt() const
Get the RREQ count.
Definition: aodv-rtable.h:312
Ipv4InterfaceAddress GetInterface() const
Get the Ipv4InterfaceAddress.
Definition: aodv-rtable.h:195
void SetNextHop(Ipv4Address nextHop)
Set next hop address.
Definition: aodv-rtable.h:159
void SetLifeTime(Time lt)
Set the lifetime.
Definition: aodv-rtable.h:267
bool IsUnidirectional() const
Get the unidirectional flag.
Definition: aodv-rtable.h:338
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Inserts precursors in output parameter prec if they do not yet exist in vector.
Definition: aodv-rtable.cc:141
RouteFlags GetFlag() const
Get the route flags.
Definition: aodv-rtable.h:294
Ipv4Address GetNextHop() const
Get next hop address.
Definition: aodv-rtable.h:168
void IncrementRreqCnt()
Increment the RREQ count.
Definition: aodv-rtable.h:320
void SetSeqNo(uint32_t sn)
Set the sequence number.
Definition: aodv-rtable.h:231
void SetInterface(Ipv4InterfaceAddress iface)
Set the Ipv4InterfaceAddress.
Definition: aodv-rtable.h:204
void SetRreqCnt(uint8_t n)
Set the RREQ count.
Definition: aodv-rtable.h:303
void SetOutputDevice(Ptr< NetDevice > dev)
Set output device.
Definition: aodv-rtable.h:177
Ipv4Address GetDestination() const
Get destination address function.
Definition: aodv-rtable.h:132
uint16_t GetHop() const
Get the number of hops.
Definition: aodv-rtable.h:258
void SetValidSeqNo(bool s)
Set the valid sequence number.
Definition: aodv-rtable.h:213
uint32_t GetSeqNo() const
Get the sequence number.
Definition: aodv-rtable.h:240
bool GetValidSeqNo() const
Get the valid sequence number.
Definition: aodv-rtable.h:222
void SetFlag(RouteFlags flag)
Set the route flags.
Definition: aodv-rtable.h:285
Time GetLifeTime() const
Get the lifetime.
Definition: aodv-rtable.h:276
Ptr< Ipv4Route > GetRoute() const
Get route function.
Definition: aodv-rtable.h:141
void GetListOfDestinationWithNextHop(Ipv4Address nextHop, std::map< Ipv4Address, uint32_t > &unreachable)
Lookup routing entries with next hop Address dst and not empty list of precursors.
Definition: aodv-rtable.cc:330
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:254
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:388
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:295
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:282
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
Definition: aodv-rtable.cc:477
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:233
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:365
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:518
void InvalidateRoutesWithDst(const std::map< Ipv4Address, uint32_t > &unreachable)
Update routing entries with this destination as follows:
Definition: aodv-rtable.cc:347
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:460
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:268
Route Reply Acknowledgment (RREP-ACK) Message Format.
Definition: aodv-packet.h:538
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:358
bool GetAckRequired() const
get the ack required flag
Definition: aodv-packet.cc:407
Ipv4Address GetOrigin() const
Get the origin address.
Definition: aodv-packet.h:455
uint8_t GetHopCount() const
Get the hop count.
Definition: aodv-packet.h:401
void SetHopCount(uint8_t count)
Set the hop count.
Definition: aodv-packet.h:392
void SetAckRequired(bool f)
Set the ack required flag.
Definition: aodv-packet.cc:394
Time GetLifeTime() const
Get the lifetime.
Definition: aodv-packet.cc:387
uint32_t GetDstSeqno() const
Get the destination sequence number.
Definition: aodv-packet.h:437
Ipv4Address GetDst() const
Get the destination address.
Definition: aodv-packet.h:419
Route Request (RREQ) Message Format.
Definition: aodv-packet.h:138
uint32_t GetId() const
Get the request ID.
Definition: aodv-packet.h:204
void SetDst(Ipv4Address a)
Set the destination address.
Definition: aodv-packet.h:213
uint8_t GetHopCount() const
Get the hop count.
Definition: aodv-packet.h:186
bool GetUnknownSeqno() const
Get the unknown sequence number flag.
Definition: aodv-packet.cc:281
void SetId(uint32_t id)
Set the request ID.
Definition: aodv-packet.h:195
uint32_t GetOriginSeqno() const
Get the origin sequence number.
Definition: aodv-packet.h:276
void SetUnknownSeqno(bool f)
Set the unknown sequence number flag.
Definition: aodv-packet.cc:268
Ipv4Address GetOrigin() const
Get the origin address.
Definition: aodv-packet.h:258
void SetGratuitousRrep(bool f)
Set the gratuitous RREP flag.
Definition: aodv-packet.cc:230
void SetDestinationOnly(bool f)
Set the Destination only flag.
Definition: aodv-packet.cc:249
bool GetDestinationOnly() const
Get the Destination only flag.
Definition: aodv-packet.cc:262
void SetHopCount(uint8_t count)
Set the hop count.
Definition: aodv-packet.h:177
void SetDstSeqno(uint32_t s)
Set the destination sequence number.
Definition: aodv-packet.h:231
uint32_t GetDstSeqno() const
Get the destination sequence number.
Definition: aodv-packet.h:240
Ipv4Address GetDst() const
Get the destination address.
Definition: aodv-packet.h:222
void SetOriginSeqno(uint32_t s)
Set the origin sequence number.
Definition: aodv-packet.h:267
bool GetGratuitousRrep() const
Get the gratuitous RREP flag.
Definition: aodv-packet.cc:243
void SetOrigin(Ipv4Address a)
Set the origin address.
Definition: aodv-packet.h:249
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:91
MessageType Get() const
Definition: aodv-packet.h:82
@ IN_SEARCH
IN_SEARCH.
Definition: aodv-rtable.h:54
@ VALID
VALID.
Definition: aodv-rtable.h:52
@ AODVTYPE_RREP
AODVTYPE_RREP.
Definition: aodv-packet.h:50
@ AODVTYPE_RREP_ACK
AODVTYPE_RREP_ACK.
Definition: aodv-packet.h:52
@ AODVTYPE_RERR
AODVTYPE_RERR.
Definition: aodv-packet.h:51
@ AODVTYPE_RREQ
AODVTYPE_RREQ.
Definition: aodv-packet.h:49
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:80
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:706
STL namespace.