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