A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
31 #include "aodv-routing-protocol.h"
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/wifi-net-device.h"
39 #include "ns3/adhoc-wifi-mac.h"
40 #include "ns3/string.h"
41 #include "ns3/pointer.h"
42 #include <algorithm>
43 #include <limits>
44 
45 NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
46 
47 namespace ns3
48 {
49 namespace aodv
50 {
51 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol)
52  ;
53 
55 const uint32_t RoutingProtocol::AODV_PORT = 654;
56 
57 //-----------------------------------------------------------------------------
59 
61 {
62 
63 public:
64  DeferredRouteOutputTag (int32_t o = -1) : Tag (), m_oif (o) {}
65 
66  static TypeId GetTypeId ()
67  {
68  static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag").SetParent<Tag> ()
69  .SetParent<Tag> ()
70  .AddConstructor<DeferredRouteOutputTag> ()
71  ;
72  return tid;
73  }
74 
76  {
77  return GetTypeId ();
78  }
79 
80  int32_t GetInterface() const
81  {
82  return m_oif;
83  }
84 
85  void SetInterface(int32_t oif)
86  {
87  m_oif = oif;
88  }
89 
90  uint32_t GetSerializedSize () const
91  {
92  return sizeof(int32_t);
93  }
94 
95  void Serialize (TagBuffer i) const
96  {
97  i.WriteU32 (m_oif);
98  }
99 
101  {
102  m_oif = i.ReadU32 ();
103  }
104 
105  void Print (std::ostream &os) const
106  {
107  os << "DeferredRouteOutputTag: output interface = " << m_oif;
108  }
109 
110 private:
112  int32_t m_oif;
113 };
114 
116  ;
117 
118 
119 //-----------------------------------------------------------------------------
121  RreqRetries (2),
122  RreqRateLimit (10),
123  RerrRateLimit (10),
124  ActiveRouteTimeout (Seconds (3)),
125  NetDiameter (35),
126  NodeTraversalTime (MilliSeconds (40)),
127  NetTraversalTime (Time ((2 * NetDiameter) * NodeTraversalTime)),
128  PathDiscoveryTime ( Time (2 * NetTraversalTime)),
129  MyRouteTimeout (Time (2 * std::max (PathDiscoveryTime, ActiveRouteTimeout))),
130  HelloInterval (Seconds (1)),
131  AllowedHelloLoss (2),
132  DeletePeriod (Time (5 * std::max (ActiveRouteTimeout, HelloInterval))),
133  NextHopWait (NodeTraversalTime + MilliSeconds (10)),
134  BlackListTimeout (Time (RreqRetries * NetTraversalTime)),
135  MaxQueueLen (64),
136  MaxQueueTime (Seconds (30)),
137  DestinationOnly (false),
138  GratuitousReply (true),
139  EnableHello (false),
140  m_routingTable (DeletePeriod),
141  m_queue (MaxQueueLen, MaxQueueTime),
142  m_requestId (0),
143  m_seqNo (0),
144  m_rreqIdCache (PathDiscoveryTime),
145  m_dpd (PathDiscoveryTime),
146  m_nb (HelloInterval),
147  m_rreqCount (0),
148  m_rerrCount (0),
149  m_htimer (Timer::CANCEL_ON_DESTROY),
150  m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
151  m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY),
152  m_lastBcastTime (Seconds (0))
153 {
155 }
156 
157 TypeId
159 {
160  static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
162  .AddConstructor<RoutingProtocol> ()
163  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
164  TimeValue (Seconds (1)),
165  MakeTimeAccessor (&RoutingProtocol::HelloInterval),
166  MakeTimeChecker ())
167  .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
168  UintegerValue (2),
169  MakeUintegerAccessor (&RoutingProtocol::RreqRetries),
170  MakeUintegerChecker<uint32_t> ())
171  .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
172  UintegerValue (10),
173  MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
174  MakeUintegerChecker<uint32_t> ())
175  .AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
176  UintegerValue (10),
177  MakeUintegerAccessor (&RoutingProtocol::RerrRateLimit),
178  MakeUintegerChecker<uint32_t> ())
179  .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
180  "queuing delays, interrupt processing times and transfer times.",
181  TimeValue (MilliSeconds (40)),
182  MakeTimeAccessor (&RoutingProtocol::NodeTraversalTime),
183  MakeTimeChecker ())
184  .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
185  TimeValue (MilliSeconds (50)),
186  MakeTimeAccessor (&RoutingProtocol::NextHopWait),
187  MakeTimeChecker ())
188  .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
189  TimeValue (Seconds (3)),
190  MakeTimeAccessor (&RoutingProtocol::ActiveRouteTimeout),
191  MakeTimeChecker ())
192  .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
193  TimeValue (Seconds (11.2)),
194  MakeTimeAccessor (&RoutingProtocol::MyRouteTimeout),
195  MakeTimeChecker ())
196  .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
197  TimeValue (Seconds (5.6)),
198  MakeTimeAccessor (&RoutingProtocol::BlackListTimeout),
199  MakeTimeChecker ())
200  .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
201  "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
202  " = 5 * max (HelloInterval, ActiveRouteTimeout)",
203  TimeValue (Seconds (15)),
204  MakeTimeAccessor (&RoutingProtocol::DeletePeriod),
205  MakeTimeChecker ())
206  .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
207  UintegerValue (35),
208  MakeUintegerAccessor (&RoutingProtocol::NetDiameter),
209  MakeUintegerChecker<uint32_t> ())
210  .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
211  TimeValue (Seconds (2.8)),
212  MakeTimeAccessor (&RoutingProtocol::NetTraversalTime),
213  MakeTimeChecker ())
214  .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
215  TimeValue (Seconds (5.6)),
216  MakeTimeAccessor (&RoutingProtocol::PathDiscoveryTime),
217  MakeTimeChecker ())
218  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
219  UintegerValue (64),
220  MakeUintegerAccessor (&RoutingProtocol::SetMaxQueueLen,
222  MakeUintegerChecker<uint32_t> ())
223  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
224  TimeValue (Seconds (30)),
225  MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
227  MakeTimeChecker ())
228  .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
229  UintegerValue (2),
230  MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss),
231  MakeUintegerChecker<uint16_t> ())
232  .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
233  BooleanValue (true),
234  MakeBooleanAccessor (&RoutingProtocol::SetGratuitousReplyFlag,
236  MakeBooleanChecker ())
237  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
238  BooleanValue (false),
239  MakeBooleanAccessor (&RoutingProtocol::SetDesinationOnlyFlag,
241  MakeBooleanChecker ())
242  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
243  BooleanValue (true),
244  MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
246  MakeBooleanChecker ())
247  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
248  BooleanValue (true),
249  MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
251  MakeBooleanChecker ())
252  .AddAttribute ("UniformRv",
253  "Access to the underlying UniformRandomVariable",
254  StringValue ("ns3::UniformRandomVariable"),
255  MakePointerAccessor (&RoutingProtocol::m_uniformRandomVariable),
256  MakePointerChecker<UniformRandomVariable> ())
257  ;
258  return tid;
259 }
260 
261 void
263 {
264  MaxQueueLen = len;
265  m_queue.SetMaxQueueLen (len);
266 }
267 void
269 {
270  MaxQueueTime = t;
272 }
273 
275 {
276 }
277 
278 void
280 {
281  m_ipv4 = 0;
282  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
283  m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
284  {
285  iter->first->Close ();
286  }
287  m_socketAddresses.clear ();
289 }
290 
291 void
293 {
294  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now ().GetSeconds () << "s ";
295  m_routingTable.Print (stream);
296 }
297 
298 int64_t
300 {
301  NS_LOG_FUNCTION (this << stream);
303  return 1;
304 }
305 
306 void
308 {
309  NS_LOG_FUNCTION (this);
310  if (EnableHello)
311  {
312  m_nb.ScheduleTimer ();
313  }
315  this);
316  m_rreqRateLimitTimer.Schedule (Seconds (1));
317 
319  this);
320  m_rerrRateLimitTimer.Schedule (Seconds (1));
321 
322 }
323 
326  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
327 {
328  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
329  if (!p)
330  {
331  NS_LOG_DEBUG("Packet is == 0");
332  return LoopbackRoute (header, oif); // later
333  }
334  if (m_socketAddresses.empty ())
335  {
336  sockerr = Socket::ERROR_NOROUTETOHOST;
337  NS_LOG_LOGIC ("No aodv interfaces");
338  Ptr<Ipv4Route> route;
339  return route;
340  }
341  sockerr = Socket::ERROR_NOTERROR;
342  Ptr<Ipv4Route> route;
343  Ipv4Address dst = header.GetDestination ();
345  if (m_routingTable.LookupValidRoute (dst, rt))
346  {
347  route = rt.GetRoute ();
348  NS_ASSERT (route != 0);
349  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
350  if (oif != 0 && route->GetOutputDevice () != oif)
351  {
352  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
353  sockerr = Socket::ERROR_NOROUTETOHOST;
354  return Ptr<Ipv4Route> ();
355  }
358  return route;
359  }
360 
361  // Valid route not found, in this case we return loopback.
362  // Actual route request will be deferred until packet will be fully formed,
363  // routed to loopback, received from loopback and passed to RouteInput (see below)
364  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
365  DeferredRouteOutputTag tag (iif);
366  NS_LOG_DEBUG ("Valid Route not found");
367  if (!p->PeekPacketTag (tag))
368  {
369  p->AddPacketTag (tag);
370  }
371  return LoopbackRoute (header, oif);
372 }
373 
374 void
377 {
378  NS_LOG_FUNCTION (this << p << header);
379  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
380 
381  QueueEntry newEntry (p, header, ucb, ecb);
382  bool result = m_queue.Enqueue (newEntry);
383  if (result)
384  {
385  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
387  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
388  if(!result || ((rt.GetFlag () != IN_SEARCH) && result))
389  {
390  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " <<header.GetDestination ());
391  SendRequest (header.GetDestination ());
392  }
393  }
394 }
395 
396 bool
400 {
401  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
402  if (m_socketAddresses.empty ())
403  {
404  NS_LOG_LOGIC ("No aodv interfaces");
405  return false;
406  }
407  NS_ASSERT (m_ipv4 != 0);
408  NS_ASSERT (p != 0);
409  // Check if input device supports IP
410  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
411  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
412 
413  Ipv4Address dst = header.GetDestination ();
414  Ipv4Address origin = header.GetSource ();
415 
416  // Deferred route request
417  if (idev == m_lo)
418  {
420  if (p->PeekPacketTag (tag))
421  {
422  DeferredRouteOutput (p, header, ucb, ecb);
423  return true;
424  }
425  }
426 
427  // Duplicate of own packet
428  if (IsMyOwnAddress (origin))
429  return true;
430 
431  // AODV is not a multicast routing protocol
432  if (dst.IsMulticast ())
433  {
434  return false;
435  }
436 
437  // Broadcast local delivery/forwarding
438  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
439  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
440  {
441  Ipv4InterfaceAddress iface = j->second;
442  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
443  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
444  {
445  if (m_dpd.IsDuplicate (p, header))
446  {
447  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
448  return true;
449  }
451  Ptr<Packet> packet = p->Copy ();
452  if (lcb.IsNull () == false)
453  {
454  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
455  lcb (p, header, iif);
456  // Fall through to additional processing
457  }
458  else
459  {
460  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
461  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
462  }
463  if (!EnableBroadcast)
464  {
465  return true;
466  }
467  if (header.GetTtl () > 1)
468  {
469  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
470  RoutingTableEntry toBroadcast;
471  if (m_routingTable.LookupRoute (dst, toBroadcast))
472  {
473  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
474  ucb (route, packet, header);
475  }
476  else
477  {
478  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
479  }
480  }
481  else
482  {
483  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
484  }
485  return true;
486  }
487  }
488 
489  // Unicast local delivery
490  if (m_ipv4->IsDestinationAddress (dst, iif))
491  {
493  RoutingTableEntry toOrigin;
494  if (m_routingTable.LookupValidRoute (origin, toOrigin))
495  {
497  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
498  }
499  if (lcb.IsNull () == false)
500  {
501  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
502  lcb (p, header, iif);
503  }
504  else
505  {
506  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
507  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
508  }
509  return true;
510  }
511 
512  // Forwarding
513  return Forwarding (p, header, ucb, ecb);
514 }
515 
516 bool
519 {
520  NS_LOG_FUNCTION (this);
521  Ipv4Address dst = header.GetDestination ();
522  Ipv4Address origin = header.GetSource ();
524  RoutingTableEntry toDst;
525  if (m_routingTable.LookupRoute (dst, toDst))
526  {
527  if (toDst.GetFlag () == VALID)
528  {
529  Ptr<Ipv4Route> route = toDst.GetRoute ();
530  NS_LOG_LOGIC (route->GetSource ()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
531 
532  /*
533  * Each time a route is used to forward a data packet, its Active Route
534  * Lifetime field of the source, destination and the next hop on the
535  * path to the destination is updated to be no less than the current
536  * time plus ActiveRouteTimeout.
537  */
541  /*
542  * Since the route between each originator and destination pair is expected to be symmetric, the
543  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
544  * to be no less than the current time plus ActiveRouteTimeout
545  */
546  RoutingTableEntry toOrigin;
547  m_routingTable.LookupRoute (origin, toOrigin);
548  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
549 
551  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
552 
553  ucb (route, p, header);
554  return true;
555  }
556  else
557  {
558  if (toDst.GetValidSeqNo ())
559  {
560  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
561  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
562  return false;
563  }
564  }
565  }
566  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
567  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
568  SendRerrWhenNoRouteToForward (dst, 0, origin);
569  return false;
570 }
571 
572 void
574 {
575  NS_ASSERT (ipv4 != 0);
576  NS_ASSERT (m_ipv4 == 0);
577 
578  if (EnableHello)
579  {
581  m_htimer.Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 100)));
582  }
583 
584  m_ipv4 = ipv4;
585 
586  // Create lo route. It is asserted that the only one interface up for now is loopback
587  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
588  m_lo = m_ipv4->GetNetDevice (0);
589  NS_ASSERT (m_lo != 0);
590  // Remember lo route
591  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
592  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
593  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
594  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
596 
598 }
599 
600 void
602 {
603  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
604  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
605  if (l3->GetNAddresses (i) > 1)
606  {
607  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
608  }
609  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
610  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
611  return;
612 
613  // Create a socket to listen only on this interface
614  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
616  NS_ASSERT (socket != 0);
618  socket->BindToNetDevice (l3->GetNetDevice (i));
620  socket->SetAllowBroadcast (true);
621  socket->SetAttribute ("IpTtl", UintegerValue (1));
622  m_socketAddresses.insert (std::make_pair (socket, iface));
623 
624  // Add local broadcast record to the routing table
625  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
626  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
627  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
629 
630  // Allow neighbor manager use this interface for layer 2 feedback if possible
631  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
632  if (wifi == 0)
633  return;
634  Ptr<WifiMac> mac = wifi->GetMac ();
635  if (mac == 0)
636  return;
637 
638  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
639  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
640 }
641 
642 void
644 {
645  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
646 
647  // Disable layer 2 link state monitoring (if possible)
648  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
649  Ptr<NetDevice> dev = l3->GetNetDevice (i);
650  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
651  if (wifi != 0)
652  {
653  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
654  if (mac != 0)
655  {
656  mac->TraceDisconnectWithoutContext ("TxErrHeader",
658  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
659  }
660  }
661 
662  // Close socket
663  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
664  NS_ASSERT (socket);
665  socket->Close ();
666  m_socketAddresses.erase (socket);
667  if (m_socketAddresses.empty ())
668  {
669  NS_LOG_LOGIC ("No aodv interfaces");
670  m_htimer.Cancel ();
671  m_nb.Clear ();
673  return;
674  }
676 }
677 
678 void
680 {
681  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
682  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
683  if (!l3->IsUp (i))
684  return;
685  if (l3->GetNAddresses (i) == 1)
686  {
687  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
689  if (!socket)
690  {
691  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
692  return;
693  // Create a socket to listen only on this interface
694  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
696  NS_ASSERT (socket != 0);
698  socket->BindToNetDevice (l3->GetNetDevice (i));
699  // Bind to any IP address so that broadcasts can be received
701  socket->SetAllowBroadcast (true);
702  m_socketAddresses.insert (std::make_pair (socket, iface));
703 
704  // Add local broadcast record to the routing table
705  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
706  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
707  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
708  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
709  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
711  }
712  }
713  else
714  {
715  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
716  }
717 }
718 
719 void
721 {
722  NS_LOG_FUNCTION (this);
723  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
724  if (socket)
725  {
727  m_socketAddresses.erase (socket);
728  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
729  if (l3->GetNAddresses (i))
730  {
731  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
732  // Create a socket to listen only on this interface
733  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
735  NS_ASSERT (socket != 0);
737  // Bind to any IP address so that broadcasts can be received
739  socket->SetAllowBroadcast (true);
740  m_socketAddresses.insert (std::make_pair (socket, iface));
741 
742  // Add local broadcast record to the routing table
743  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
744  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
745  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
747  }
748  if (m_socketAddresses.empty ())
749  {
750  NS_LOG_LOGIC ("No aodv interfaces");
751  m_htimer.Cancel ();
752  m_nb.Clear ();
754  return;
755  }
756  }
757  else
758  {
759  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
760  }
761 }
762 
763 bool
765 {
766  NS_LOG_FUNCTION (this << src);
767  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
768  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
769  {
770  Ipv4InterfaceAddress iface = j->second;
771  if (src == iface.GetLocal ())
772  {
773  return true;
774  }
775  }
776  return false;
777 }
778 
781 {
782  NS_LOG_FUNCTION (this << hdr);
783  NS_ASSERT (m_lo != 0);
784  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
785  rt->SetDestination (hdr.GetDestination ());
786  //
787  // Source address selection here is tricky. The loopback route is
788  // returned when AODV does not have a route; this causes the packet
789  // to be looped back and handled (cached) in RouteInput() method
790  // while a route is found. However, connection-oriented protocols
791  // like TCP need to create an endpoint four-tuple (src, src port,
792  // dst, dst port) and create a pseudo-header for checksumming. So,
793  // AODV needs to guess correctly what the eventual source address
794  // will be.
795  //
796  // For single interface, single address nodes, this is not a problem.
797  // When there are possibly multiple outgoing interfaces, the policy
798  // implemented here is to pick the first available AODV interface.
799  // If RouteOutput() caller specified an outgoing interface, that
800  // further constrains the selection of source address
801  //
802  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
803  if (oif)
804  {
805  // Iterate to find an address on the oif device
806  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
807  {
808  Ipv4Address addr = j->second.GetLocal ();
809  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
810  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
811  {
812  rt->SetSource (addr);
813  break;
814  }
815  }
816  }
817  else
818  {
819  rt->SetSource (j->second.GetLocal ());
820  }
821  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
822  rt->SetGateway (Ipv4Address ("127.0.0.1"));
823  rt->SetOutputDevice (m_lo);
824  return rt;
825 }
826 
827 void
829 {
830  NS_LOG_FUNCTION ( this << dst);
831  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
832  if (m_rreqCount == RreqRateLimit)
833  {
834  Simulator::Schedule (m_rreqRateLimitTimer.GetDelayLeft () + MicroSeconds (100),
835  &RoutingProtocol::SendRequest, this, dst);
836  return;
837  }
838  else
839  m_rreqCount++;
840  // Create RREQ header
841  RreqHeader rreqHeader;
842  rreqHeader.SetDst (dst);
843 
845  if (m_routingTable.LookupRoute (dst, rt))
846  {
847  rreqHeader.SetHopCount (rt.GetHop ());
848  if (rt.GetValidSeqNo ())
849  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
850  else
851  rreqHeader.SetUnknownSeqno (true);
852  rt.SetFlag (IN_SEARCH);
853  m_routingTable.Update (rt);
854  }
855  else
856  {
857  rreqHeader.SetUnknownSeqno (true);
858  Ptr<NetDevice> dev = 0;
859  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
860  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
861  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0));
862  newEntry.SetFlag (IN_SEARCH);
863  m_routingTable.AddRoute (newEntry);
864  }
865 
866  if (GratuitousReply)
867  rreqHeader.SetGratiousRrep (true);
868  if (DestinationOnly)
869  rreqHeader.SetDestinationOnly (true);
870 
871  m_seqNo++;
872  rreqHeader.SetOriginSeqno (m_seqNo);
873  m_requestId++;
874  rreqHeader.SetId (m_requestId);
875  rreqHeader.SetHopCount (0);
876 
877  // Send RREQ as subnet directed broadcast from each interface used by aodv
878  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
879  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
880  {
881  Ptr<Socket> socket = j->first;
882  Ipv4InterfaceAddress iface = j->second;
883 
884  rreqHeader.SetOrigin (iface.GetLocal ());
886 
887  Ptr<Packet> packet = Create<Packet> ();
888  packet->AddHeader (rreqHeader);
889  TypeHeader tHeader (AODVTYPE_RREQ);
890  packet->AddHeader (tHeader);
891  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
892  Ipv4Address destination;
893  if (iface.GetMask () == Ipv4Mask::GetOnes ())
894  {
895  destination = Ipv4Address ("255.255.255.255");
896  }
897  else
898  {
899  destination = iface.GetBroadcast ();
900  }
901  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
903  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
904  }
905  ScheduleRreqRetry (dst);
906 }
907 
908 void
910 {
911  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
912 
913 }
914 void
916 {
917  NS_LOG_FUNCTION (this << dst);
918  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
919  {
921  m_addressReqTimer[dst] = timer;
922  }
924  m_addressReqTimer[dst].Remove ();
925  m_addressReqTimer[dst].SetArguments (dst);
927  m_routingTable.LookupRoute (dst, rt);
928  rt.IncrementRreqCnt ();
929  m_routingTable.Update (rt);
930  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
931  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
932 }
933 
934 void
936 {
937  NS_LOG_FUNCTION (this << socket);
938  Address sourceAddress;
939  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
940  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
941  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
942  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
943  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
944 
945  UpdateRouteToNeighbor (sender, receiver);
946  TypeHeader tHeader (AODVTYPE_RREQ);
947  packet->RemoveHeader (tHeader);
948  if (!tHeader.IsValid ())
949  {
950  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
951  return; // drop
952  }
953  switch (tHeader.Get ())
954  {
955  case AODVTYPE_RREQ:
956  {
957  RecvRequest (packet, receiver, sender);
958  break;
959  }
960  case AODVTYPE_RREP:
961  {
962  RecvReply (packet, receiver, sender);
963  break;
964  }
965  case AODVTYPE_RERR:
966  {
967  RecvError (packet, sender);
968  break;
969  }
970  case AODVTYPE_RREP_ACK:
971  {
972  RecvReplyAck (sender);
973  break;
974  }
975  }
976 }
977 
978 bool
980 {
981  NS_LOG_FUNCTION (this << addr << lifetime);
983  if (m_routingTable.LookupRoute (addr, rt))
984  {
985  if (rt.GetFlag () == VALID)
986  {
987  NS_LOG_DEBUG ("Updating VALID route");
988  rt.SetRreqCnt (0);
989  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
990  m_routingTable.Update (rt);
991  return true;
992  }
993  }
994  return false;
995 }
996 
997 void
999 {
1000  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1001  RoutingTableEntry toNeighbor;
1002  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1003  {
1004  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1005  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1006  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1007  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout);
1008  m_routingTable.AddRoute (newEntry);
1009  }
1010  else
1011  {
1012  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1013  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1014  {
1015  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1016  }
1017  else
1018  {
1019  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1020  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1021  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1022  m_routingTable.Update (newEntry);
1023  }
1024  }
1025 
1026 }
1027 
1028 void
1030 {
1031  NS_LOG_FUNCTION (this);
1032  RreqHeader rreqHeader;
1033  p->RemoveHeader (rreqHeader);
1034 
1035  // A node ignores all RREQs received from any node in its blacklist
1036  RoutingTableEntry toPrev;
1037  if (m_routingTable.LookupRoute (src, toPrev))
1038  {
1039  if (toPrev.IsUnidirectional ())
1040  {
1041  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1042  return;
1043  }
1044  }
1045 
1046  uint32_t id = rreqHeader.GetId ();
1047  Ipv4Address origin = rreqHeader.GetOrigin ();
1048 
1049  /*
1050  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1051  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1052  */
1053  if (m_rreqIdCache.IsDuplicate (origin, id))
1054  {
1055  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1056  return;
1057  }
1058 
1059  // Increment RREQ hop count
1060  uint8_t hop = rreqHeader.GetHopCount () + 1;
1061  rreqHeader.SetHopCount (hop);
1062 
1063  /*
1064  * When the reverse route is created or updated, the following actions on the route are also carried out:
1065  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1066  * in the route table entry and copied if greater than the existing value there
1067  * 2. the valid sequence number field is set to true;
1068  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1069  * 4. the hop count is copied from the Hop Count in the RREQ message;
1070  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1071  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1072  */
1073  RoutingTableEntry toOrigin;
1074  if (!m_routingTable.LookupRoute (origin, toOrigin))
1075  {
1076  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1077  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1078  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1079  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)));
1080  m_routingTable.AddRoute (newEntry);
1081  }
1082  else
1083  {
1084  if (toOrigin.GetValidSeqNo ())
1085  {
1086  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1087  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1088  }
1089  else
1090  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1091  toOrigin.SetValidSeqNo (true);
1092  toOrigin.SetNextHop (src);
1093  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1094  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1095  toOrigin.SetHop (hop);
1096  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1097  toOrigin.GetLifeTime ()));
1098  m_routingTable.Update (toOrigin);
1099  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1100  }
1101 
1102 
1103  RoutingTableEntry toNeighbor;
1104  if (!m_routingTable.LookupRoute (src, toNeighbor))
1105  {
1106  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1107  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1108  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1109  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1110  1, src, ActiveRouteTimeout);
1111  m_routingTable.AddRoute (newEntry);
1112  }
1113  else
1114  {
1115  toNeighbor.SetLifeTime (ActiveRouteTimeout);
1116  toNeighbor.SetValidSeqNo (false);
1117  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1118  toNeighbor.SetFlag (VALID);
1119  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1120  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1121  m_routingTable.Update (toNeighbor);
1122  }
1124 
1125  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1126  << " ID " << rreqHeader.GetId ()
1127  << " to destination " << rreqHeader.GetDst ());
1128 
1129  // A node generates a RREP if either:
1130  // (i) it is itself the destination,
1131  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1132  {
1133  m_routingTable.LookupRoute (origin, toOrigin);
1134  NS_LOG_DEBUG ("Send reply since I am the destination");
1135  SendReply (rreqHeader, toOrigin);
1136  return;
1137  }
1138  /*
1139  * (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
1140  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1141  */
1142  RoutingTableEntry toDst;
1143  Ipv4Address dst = rreqHeader.GetDst ();
1144  if (m_routingTable.LookupRoute (dst, toDst))
1145  {
1146  /*
1147  * Drop RREQ, This node RREP wil make a loop.
1148  */
1149  if (toDst.GetNextHop () == src)
1150  {
1151  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1152  return;
1153  }
1154  /*
1155  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1156  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1157  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1158  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1159  */
1160  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1161  && toDst.GetValidSeqNo () )
1162  {
1163  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1164  {
1165  m_routingTable.LookupRoute (origin, toOrigin);
1166  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1167  return;
1168  }
1169  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1170  rreqHeader.SetUnknownSeqno (false);
1171  }
1172  }
1173 
1174  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1175  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1176  {
1177  Ptr<Socket> socket = j->first;
1178  Ipv4InterfaceAddress iface = j->second;
1179  Ptr<Packet> packet = Create<Packet> ();
1180  packet->AddHeader (rreqHeader);
1181  TypeHeader tHeader (AODVTYPE_RREQ);
1182  packet->AddHeader (tHeader);
1183  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1184  Ipv4Address destination;
1185  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1186  {
1187  destination = Ipv4Address ("255.255.255.255");
1188  }
1189  else
1190  {
1191  destination = iface.GetBroadcast ();
1192  }
1194  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1195 
1196  }
1197 }
1198 
1199 void
1200 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1201 {
1202  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1203  /*
1204  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1205  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1206  */
1207  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1208  m_seqNo++;
1209  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1210  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout);
1211  Ptr<Packet> packet = Create<Packet> ();
1212  packet->AddHeader (rrepHeader);
1213  TypeHeader tHeader (AODVTYPE_RREP);
1214  packet->AddHeader (tHeader);
1216  NS_ASSERT (socket);
1217  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1218 }
1219 
1220 void
1222 {
1223  NS_LOG_FUNCTION (this);
1224  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1225  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1226  /* If the node we received a RREQ for is a neighbor we are
1227  * probably facing a unidirectional link... Better request a RREP-ack
1228  */
1229  if (toDst.GetHop () == 1)
1230  {
1231  rrepHeader.SetAckRequired (true);
1232  RoutingTableEntry toNextHop;
1233  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1235  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1236  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1237  }
1238  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1239  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1240  m_routingTable.Update (toDst);
1241  m_routingTable.Update (toOrigin);
1242 
1243  Ptr<Packet> packet = Create<Packet> ();
1244  packet->AddHeader (rrepHeader);
1245  TypeHeader tHeader (AODVTYPE_RREP);
1246  packet->AddHeader (tHeader);
1248  NS_ASSERT (socket);
1249  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1250 
1251  // Generating gratuitous RREPs
1252  if (gratRep)
1253  {
1254  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1255  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1256  /*lifetime=*/ toOrigin.GetLifeTime ());
1257  Ptr<Packet> packetToDst = Create<Packet> ();
1258  packetToDst->AddHeader (gratRepHeader);
1259  TypeHeader type (AODVTYPE_RREP);
1260  packetToDst->AddHeader (type);
1262  NS_ASSERT (socket);
1263  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1264  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1265  }
1266 }
1267 
1268 void
1270 {
1271  NS_LOG_FUNCTION (this << " to " << neighbor);
1272  RrepAckHeader h;
1273  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1274  Ptr<Packet> packet = Create<Packet> ();
1275  packet->AddHeader (h);
1276  packet->AddHeader (typeHeader);
1277  RoutingTableEntry toNeighbor;
1278  m_routingTable.LookupRoute (neighbor, toNeighbor);
1279  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1280  NS_ASSERT (socket);
1281  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1282 }
1283 
1284 void
1286 {
1287  NS_LOG_FUNCTION (this << " src " << sender);
1288  RrepHeader rrepHeader;
1289  p->RemoveHeader (rrepHeader);
1290  Ipv4Address dst = rrepHeader.GetDst ();
1291  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1292 
1293  uint8_t hop = rrepHeader.GetHopCount () + 1;
1294  rrepHeader.SetHopCount (hop);
1295 
1296  // If RREP is Hello message
1297  if (dst == rrepHeader.GetOrigin ())
1298  {
1299  ProcessHello (rrepHeader, receiver);
1300  return;
1301  }
1302 
1303  /*
1304  * If the route table entry to the destination is created or updated, then the following actions occur:
1305  * - the route is marked as active,
1306  * - the destination sequence number is marked as valid,
1307  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1308  * which is indicated by the source IP address field in the IP header,
1309  * - the hop count is set to the value of the hop count from RREP message + 1
1310  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1311  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1312  */
1313  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1314  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1315  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1316  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1317  RoutingTableEntry toDst;
1318  if (m_routingTable.LookupRoute (dst, toDst))
1319  {
1320  /*
1321  * The existing entry is updated only in the following circumstances:
1322  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1323  */
1324  if (!toDst.GetValidSeqNo ())
1325  {
1326  m_routingTable.Update (newEntry);
1327  }
1328  // (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,
1329  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1330  {
1331  m_routingTable.Update (newEntry);
1332  }
1333  else
1334  {
1335  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1336  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1337  {
1338  m_routingTable.Update (newEntry);
1339  }
1340  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1341  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1342  {
1343  m_routingTable.Update (newEntry);
1344  }
1345  }
1346  }
1347  else
1348  {
1349  // The forward route for this destination is created if it does not already exist.
1350  NS_LOG_LOGIC ("add new route");
1351  m_routingTable.AddRoute (newEntry);
1352  }
1353  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1354  if (rrepHeader.GetAckRequired ())
1355  {
1356  SendReplyAck (sender);
1357  rrepHeader.SetAckRequired (false);
1358  }
1359  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1360  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1361  {
1362  if (toDst.GetFlag () == IN_SEARCH)
1363  {
1364  m_routingTable.Update (newEntry);
1365  m_addressReqTimer[dst].Remove ();
1366  m_addressReqTimer.erase (dst);
1367  }
1368  m_routingTable.LookupRoute (dst, toDst);
1369  SendPacketFromQueue (dst, toDst.GetRoute ());
1370  return;
1371  }
1372 
1373  RoutingTableEntry toOrigin;
1374  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1375  {
1376  return; // Impossible! drop.
1377  }
1378  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1379  m_routingTable.Update (toOrigin);
1380 
1381  // Update information about precursors
1382  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1383  {
1384  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1385  m_routingTable.Update (toDst);
1386 
1387  RoutingTableEntry toNextHopToDst;
1388  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1389  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1390  m_routingTable.Update (toNextHopToDst);
1391 
1392  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1393  m_routingTable.Update (toOrigin);
1394 
1395  RoutingTableEntry toNextHopToOrigin;
1396  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1397  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1398  m_routingTable.Update (toNextHopToOrigin);
1399  }
1400 
1401  Ptr<Packet> packet = Create<Packet> ();
1402  packet->AddHeader (rrepHeader);
1403  TypeHeader tHeader (AODVTYPE_RREP);
1404  packet->AddHeader (tHeader);
1406  NS_ASSERT (socket);
1407  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1408 }
1409 
1410 void
1412 {
1413  NS_LOG_FUNCTION (this);
1414  RoutingTableEntry rt;
1415  if(m_routingTable.LookupRoute (neighbor, rt))
1416  {
1417  rt.m_ackTimer.Cancel ();
1418  rt.SetFlag (VALID);
1419  m_routingTable.Update (rt);
1420  }
1421 }
1422 
1423 void
1425 {
1426  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1427  /*
1428  * Whenever a node receives a Hello message from a neighbor, the node
1429  * SHOULD make sure that it has an active route to the neighbor, and
1430  * create one if necessary.
1431  */
1432  RoutingTableEntry toNeighbor;
1433  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1434  {
1435  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1436  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1437  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1438  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1439  m_routingTable.AddRoute (newEntry);
1440  }
1441  else
1442  {
1443  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1444  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1445  toNeighbor.SetValidSeqNo (true);
1446  toNeighbor.SetFlag (VALID);
1447  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1448  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1449  m_routingTable.Update (toNeighbor);
1450  }
1451  if (EnableHello)
1452  {
1453  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1454  }
1455 }
1456 
1457 void
1459 {
1460  NS_LOG_FUNCTION (this << " from " << src);
1461  RerrHeader rerrHeader;
1462  p->RemoveHeader (rerrHeader);
1463  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1464  std::map<Ipv4Address, uint32_t> unreachable;
1465  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1466  std::pair<Ipv4Address, uint32_t> un;
1467  while (rerrHeader.RemoveUnDestination (un))
1468  {
1469  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1470  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1471  {
1472  if (i->first == un.first)
1473  {
1474  unreachable.insert (un);
1475  }
1476  }
1477  }
1478 
1479  std::vector<Ipv4Address> precursors;
1480  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1481  i != unreachable.end ();)
1482  {
1483  if (!rerrHeader.AddUnDestination (i->first, i->second))
1484  {
1485  TypeHeader typeHeader (AODVTYPE_RERR);
1486  Ptr<Packet> packet = Create<Packet> ();
1487  packet->AddHeader (rerrHeader);
1488  packet->AddHeader (typeHeader);
1489  SendRerrMessage (packet, precursors);
1490  rerrHeader.Clear ();
1491  }
1492  else
1493  {
1494  RoutingTableEntry toDst;
1495  m_routingTable.LookupRoute (i->first, toDst);
1496  toDst.GetPrecursors (precursors);
1497  ++i;
1498  }
1499  }
1500  if (rerrHeader.GetDestCount () != 0)
1501  {
1502  TypeHeader typeHeader (AODVTYPE_RERR);
1503  Ptr<Packet> packet = Create<Packet> ();
1504  packet->AddHeader (rerrHeader);
1505  packet->AddHeader (typeHeader);
1506  SendRerrMessage (packet, precursors);
1507  }
1509 }
1510 
1511 void
1513 {
1514  NS_LOG_LOGIC (this);
1515  RoutingTableEntry toDst;
1516  if (m_routingTable.LookupValidRoute (dst, toDst))
1517  {
1518  SendPacketFromQueue (dst, toDst.GetRoute ());
1519  NS_LOG_LOGIC ("route to " << dst << " found");
1520  return;
1521  }
1522  /*
1523  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1524  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1525  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1526  */
1527  if (toDst.GetRreqCnt () == RreqRetries)
1528  {
1529  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1530  m_addressReqTimer.erase (dst);
1532  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1533  m_queue.DropPacketWithDst (dst);
1534  return;
1535  }
1536 
1537  if (toDst.GetFlag () == IN_SEARCH)
1538  {
1539  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1540  SendRequest (dst);
1541  }
1542  else
1543  {
1544  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1545  m_addressReqTimer.erase (dst);
1547  m_queue.DropPacketWithDst (dst);
1548  }
1549 }
1550 
1551 void
1553 {
1554  NS_LOG_FUNCTION (this);
1555  Time offset = Time (Seconds (0));
1556  if (m_lastBcastTime > Time (Seconds (0)))
1557  {
1558  offset = Simulator::Now () - m_lastBcastTime;
1559  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1560  }
1561  else
1562  {
1563  SendHello ();
1564  }
1565  m_htimer.Cancel ();
1566  Time diff = HelloInterval - offset;
1567  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1568  m_lastBcastTime = Time (Seconds (0));
1569 }
1570 
1571 void
1573 {
1574  NS_LOG_FUNCTION (this);
1575  m_rreqCount = 0;
1576  m_rreqRateLimitTimer.Schedule (Seconds (1));
1577 }
1578 
1579 void
1581 {
1582  NS_LOG_FUNCTION (this);
1583  m_rerrCount = 0;
1584  m_rerrRateLimitTimer.Schedule (Seconds (1));
1585 }
1586 
1587 void
1589 {
1590  NS_LOG_FUNCTION (this);
1591  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1592 }
1593 
1594 void
1596 {
1597  NS_LOG_FUNCTION (this);
1598  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1599  * Destination IP Address The node's IP address.
1600  * Destination Sequence Number The node's latest sequence number.
1601  * Hop Count 0
1602  * Lifetime AllowedHelloLoss * HelloInterval
1603  */
1604  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1605  {
1606  Ptr<Socket> socket = j->first;
1607  Ipv4InterfaceAddress iface = j->second;
1608  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1609  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval));
1610  Ptr<Packet> packet = Create<Packet> ();
1611  packet->AddHeader (helloHeader);
1612  TypeHeader tHeader (AODVTYPE_RREP);
1613  packet->AddHeader (tHeader);
1614  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1615  Ipv4Address destination;
1616  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1617  {
1618  destination = Ipv4Address ("255.255.255.255");
1619  }
1620  else
1621  {
1622  destination = iface.GetBroadcast ();
1623  }
1624  Time jitter = Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10)));
1625  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this , socket, packet, destination);
1626  }
1627 }
1628 
1629 void
1631 {
1632  NS_LOG_FUNCTION (this);
1633  QueueEntry queueEntry;
1634  while (m_queue.Dequeue (dst, queueEntry))
1635  {
1637  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1638  if (p->RemovePacketTag (tag) &&
1639  tag.GetInterface() != -1 &&
1640  tag.GetInterface() != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1641  {
1642  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1643  return;
1644  }
1646  Ipv4Header header = queueEntry.GetIpv4Header ();
1647  header.SetSource (route->GetSource ());
1648  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1649  ucb (route, p, header);
1650  }
1651 }
1652 
1653 void
1655 {
1656  NS_LOG_FUNCTION (this << nextHop);
1657  RerrHeader rerrHeader;
1658  std::vector<Ipv4Address> precursors;
1659  std::map<Ipv4Address, uint32_t> unreachable;
1660 
1661  RoutingTableEntry toNextHop;
1662  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1663  return;
1664  toNextHop.GetPrecursors (precursors);
1665  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1666  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1667  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1668  != unreachable.end ();)
1669  {
1670  if (!rerrHeader.AddUnDestination (i->first, i->second))
1671  {
1672  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1673  TypeHeader typeHeader (AODVTYPE_RERR);
1674  Ptr<Packet> packet = Create<Packet> ();
1675  packet->AddHeader (rerrHeader);
1676  packet->AddHeader (typeHeader);
1677  SendRerrMessage (packet, precursors);
1678  rerrHeader.Clear ();
1679  }
1680  else
1681  {
1682  RoutingTableEntry toDst;
1683  m_routingTable.LookupRoute (i->first, toDst);
1684  toDst.GetPrecursors (precursors);
1685  ++i;
1686  }
1687  }
1688  if (rerrHeader.GetDestCount () != 0)
1689  {
1690  TypeHeader typeHeader (AODVTYPE_RERR);
1691  Ptr<Packet> packet = Create<Packet> ();
1692  packet->AddHeader (rerrHeader);
1693  packet->AddHeader (typeHeader);
1694  SendRerrMessage (packet, precursors);
1695  }
1696  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1698 }
1699 
1700 void
1702  uint32_t dstSeqNo, Ipv4Address origin)
1703 {
1704  NS_LOG_FUNCTION (this);
1705  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1706  if (m_rerrCount == RerrRateLimit)
1707  {
1708  // Just make sure that the RerrRateLimit timer is running and will expire
1710  // discard the packet and return
1711  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1713  << "; suppressing RERR");
1714  return;
1715  }
1716  RerrHeader rerrHeader;
1717  rerrHeader.AddUnDestination (dst, dstSeqNo);
1718  RoutingTableEntry toOrigin;
1719  Ptr<Packet> packet = Create<Packet> ();
1720  packet->AddHeader (rerrHeader);
1721  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1722  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1723  {
1725  toOrigin.GetInterface ());
1726  NS_ASSERT (socket);
1727  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1728  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1729  }
1730  else
1731  {
1732  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1733  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1734  {
1735  Ptr<Socket> socket = i->first;
1736  Ipv4InterfaceAddress iface = i->second;
1737  NS_ASSERT (socket);
1738  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1739  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1740  Ipv4Address destination;
1741  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1742  {
1743  destination = Ipv4Address ("255.255.255.255");
1744  }
1745  else
1746  {
1747  destination = iface.GetBroadcast ();
1748  }
1749  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1750  }
1751  }
1752 }
1753 
1754 void
1755 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1756 {
1757  NS_LOG_FUNCTION (this);
1758 
1759  if (precursors.empty ())
1760  {
1761  NS_LOG_LOGIC ("No precursors");
1762  return;
1763  }
1764  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1765  if (m_rerrCount == RerrRateLimit)
1766  {
1767  // Just make sure that the RerrRateLimit timer is running and will expire
1769  // discard the packet and return
1770  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1772  << "; suppressing RERR");
1773  return;
1774  }
1775  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1776  if (precursors.size () == 1)
1777  {
1778  RoutingTableEntry toPrecursor;
1779  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1780  {
1781  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1782  NS_ASSERT (socket);
1783  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1784  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
1785  m_rerrCount++;
1786  }
1787  return;
1788  }
1789 
1790  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1791  std::vector<Ipv4InterfaceAddress> ifaces;
1792  RoutingTableEntry toPrecursor;
1793  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1794  {
1795  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1796  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1797  {
1798  ifaces.push_back (toPrecursor.GetInterface ());
1799  }
1800  }
1801 
1802  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1803  {
1805  NS_ASSERT (socket);
1806  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1807  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1808  Ipv4Address destination;
1809  if (i->GetMask () == Ipv4Mask::GetOnes ())
1810  {
1811  destination = Ipv4Address ("255.255.255.255");
1812  }
1813  else
1814  {
1815  destination = i->GetBroadcast ();
1816  }
1817  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1818  }
1819 }
1820 
1823 {
1824  NS_LOG_FUNCTION (this << addr);
1825  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1826  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1827  {
1828  Ptr<Socket> socket = j->first;
1829  Ipv4InterfaceAddress iface = j->second;
1830  if (iface == addr)
1831  return socket;
1832  }
1833  Ptr<Socket> socket;
1834  return socket;
1835 }
1836 
1837 }
1838 }
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
UnicastForwardCallback GetUnicastForwardCallback() const
Definition: aodv-rqueue.h:66
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
static TypeId GetTypeId(void)
Get the type ID.
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
static Ipv4Mask GetOnes(void)
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Update routing entries with this destinations as follows:
Definition: aodv-rtable.cc:314
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:420
an Inet address class
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
void SetOutputDevice(Ptr< NetDevice > dev)
RREP_ACK timer.
Definition: aodv-rtable.h:111
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
uint16_t m_rreqCount
Number of RREQs used for RREQ rate control.
Hold a bool native type.
Definition: boolean.h:38
Ipv4Mask GetMask(void) const
Get the network mask.
Callback template class.
Definition: callback.h:920
Time MaxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
NS_LOG_COMPONENT_DEFINE("AodvRoutingProtocol")
bool GetUnknownSeqno() const
Definition: aodv-packet.cc:264
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:199
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:236
void SendTo(Ptr< Socket > socket, Ptr< Packet > packet, Ipv4Address destination)
RoutingTable m_routingTable
Routing table.
uint32_t GetInteger(uint32_t min, uint32_t max)
Returns a random unsigned integer from a uniform distribution over the interval [min,max] including both ends.
a simple Timer class
Definition: timer.h:45
Ipv4Header GetIpv4Header() const
Definition: aodv-rqueue.h:72
void SetId(uint32_t id)
Definition: aodv-packet.h:125
bool GetAckRequired() const
Definition: aodv-packet.cc:380
Ipv4Address GetLocal(void) const
Get the local address.
hold variables of type string
Definition: string.h:19
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
Route Error (RERR) Message Format.
Definition: aodv-packet.h:288
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
Routing table entry.
Definition: aodv-rtable.h:59
Tag used by AODV implementation.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
uint32_t MaxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
Ptr< Ipv4 > m_ipv4
IP protocol.
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:260
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
uint64_t GetUid(void) const
A packet is allocated a new uid when it is created empty or with zero-filled payload.
Definition: packet.cc:393
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:133
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void IncrementRreqCnt()
RREP_ACK timer.
Definition: aodv-rtable.h:127
bool Forwarding(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
If route exists and valid, forward packet.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1014
void SetMaxQueueLen(uint32_t len)
Definition: aodv-rqueue.h:116
#define NS_ASSERT(condition)
Definition: assert.h:64
void SetDst(Ipv4Address a)
Definition: aodv-packet.h:127
void DelArpCache(Ptr< ArpCache >)
Don't use given ARP cache any more (interface is down)
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
uint32_t GetDstSeqno() const
Definition: aodv-packet.h:204
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
bool IsMulticast(void) const
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
Ptr< NetDevice > GetOutputDevice() const
RREP_ACK timer.
Definition: aodv-rtable.h:112
Time NetTraversalTime
Estimate of the average net traversal time.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Neighbors m_nb
Handle neighbors.
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Inserts precursors in vector prec if they does not yet exist in vector.
Definition: aodv-rtable.cc:127
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:199
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
void SetLifeTime(Time lt)
RREP_ACK timer.
Definition: aodv-rtable.h:121
uint32_t RreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
Route Request (RREQ) Message Format.
Definition: aodv-packet.h:102
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Time m_lastBcastTime
Keep track of the last bcast time.
AODVTYPE_RERR.
Definition: aodv-packet.h:45
RequestQueue m_queue
A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route...
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:49
uint32_t m_seqNo
Request sequence number.
void ScheduleRreqRetry(Ipv4Address dst)
To reduce congestion in a network, repeated attempts by a source node at route discovery for a single...
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find socket with local interface address iface.
a polymophic address class
Definition: address.h:86
bool IsRunning(void) const
Definition: timer.cc:121
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:72
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
void RecvAodv(Ptr< Socket > socket)
Receive and process control packet.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
void Clear()
Clear header.
Definition: aodv-packet.cc:611
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn't yet exist in the list.
Definition: aodv-rtable.cc:65
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Definition: nstime.h:274
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:438
Time GetLifeTime() const
RREP_ACK timer.
Definition: aodv-rtable.h:122
bool DestinationOnly
Indicates only the destination may respond to this RREQ.
void SetRreqCnt(uint8_t n)
RREP_ACK timer.
Definition: aodv-rtable.h:125
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:863
bool IsDuplicate(Ptr< const Packet > p, const Ipv4Header &header)
Check that the packet is duplicated. If not, save information about this packet.
Definition: aodv-dpd.cc:31
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
Forward packet from route request queue.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet and send route request.
void SetHopCount(uint8_t count)
Definition: aodv-packet.h:199
bool IsMyOwnAddress(Ipv4Address src)
Check that packet is send from own interface.
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 RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
bool GetGratiousRrep() const
Definition: aodv-packet.cc:234
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:334
void HelloTimerExpire()
Schedule next send of hello message.
hold objects of type ns3::Time
Definition: nstime.h:961
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:152
uint8_t GetDestCount() const
Return number of unreachable destinations in RERR message.
Definition: aodv-packet.h:322
Ipv4Address GetNextHop() const
RREP_ACK timer.
Definition: aodv-rtable.h:110
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Add unreachable node address and its sequence number in RERR header.
Definition: aodv-packet.cc:589
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:254
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Set lifetime field in routing table entry to the maximum of existing lifetime and lt...
Hold an unsigned integer type.
Definition: uinteger.h:46
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Update neighbor record.
Ipv4Address GetDst() const
Definition: aodv-packet.h:128
Time HelloInterval
Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval...
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:170
bool IsBroadcast(void) const
void SetSeqNo(uint32_t sn)
RREP_ACK timer.
Definition: aodv-rtable.h:117
uint16_t RreqRateLimit
Maximum number of RREQ per second.
void SetValidSeqNo(bool s)
RREP_ACK timer.
Definition: aodv-rtable.h:115
void SetOriginSeqno(uint32_t s)
Definition: aodv-packet.h:133
int32_t m_oif
Positive if output device is fixed in RouteOutput.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
Hold together all Wifi-related objects.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
uint8_t GetHopCount() const
Definition: aodv-packet.h:124
void SetDestinationOnly(bool f)
Definition: aodv-packet.cc:240
void SetRecvCallback(Callback< void, Ptr< Socket > >)
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
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
Send RREP by intermediate node.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
void AddArpCache(Ptr< ArpCache >)
Add ARP cache to be used to allow layer 2 notifications processing.
AODVTYPE_RREP.
Definition: aodv-packet.h:44
Ptr< const Packet > GetPacket() const
Definition: aodv-rqueue.h:70
Ipv4InterfaceAddress GetInterface() const
RREP_ACK timer.
Definition: aodv-rtable.h:113
Callback< void, WifiMacHeader const & > GetTxErrorCallback() const
Get callback to ProcessTxError.
Definition: aodv-neighbor.h:86
void SetDelay(const Time &delay)
Definition: timer.cc:69
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:71
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
void SetDstSeqno(uint32_t s)
Definition: aodv-packet.h:129
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:180
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:297
void SetInterface(Ipv4InterfaceAddress iface)
RREP_ACK timer.
Definition: aodv-rtable.h:114
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
AODV Queue Entry.
Definition: aodv-rqueue.h:43
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
Send RERR message when no route to forward input packet.
This policy cancels the event from the destructor of the Timer to verify that the event has already e...
Definition: timer.h:58
tag a set of bytes in a packet
Definition: tag.h:36
void Clear()
Remove all entries.
Definition: aodv-neighbor.h:79
void SendRerrWhenBreaksLinkToNextHop(Ipv4Address nextHop)
Initiate RERR.
Time NodeTraversalTime
NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets and sh...
void SetArguments(T1 a1)
Definition: timer.h:269
Implement the Ipv4 layer.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
static InetSocketAddress ConvertFrom(const Address &address)
void SetFlag(RouteFlags flag)
RREP_ACK timer.
Definition: aodv-rtable.h:123
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:206
uint16_t GetHop() const
RREP_ACK timer.
Definition: aodv-rtable.h:120
Time ActiveRouteTimeout
Period of time during which the route is considered to be valid.
AODVTYPE_RREP_ACK.
Definition: aodv-packet.h:46
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:600
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
void SetOrigin(Ipv4Address a)
Definition: aodv-packet.h:131
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw socket per each IP interface, map socket -> iface address (IP + mask)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:985
void Update(Ipv4Address addr, Time expire)
Update expire time for entry with address addr, if it exists, else add new entry. ...
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
void ProcessHello(RrepHeader const &rrepHeader, Ipv4Address receiverIfaceAddr)
Process hello message.
static Ipv4Address GetLoopback(void)
virtual void NotifyInterfaceUp(uint32_t interface)
Time GetLifeTime() const
Definition: aodv-packet.cc:364
AODVTYPE_RREQ.
Definition: aodv-packet.h:43
Ipv4Address GetDst() const
Definition: aodv-packet.h:202
DuplicatePacketDetection m_dpd
Handle duplicated broadcast/multicast packets.
bool EnableBroadcast
Indicates whether a a broadcast data packets forwarding enable.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
Route Reply Acknowledgment (RREP-ACK) Message Format.
Definition: aodv-packet.h:246
void RecvError(Ptr< Packet > p, Ipv4Address src)
Receive RERR from node with address src.
void RreqRateLimitTimerExpire()
Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t GetDstSeqno() const
Definition: aodv-packet.h:130
Time PathDiscoveryTime
Estimate of maximum time needed to find route in network.
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
Time BlackListTimeout
Time for which the node is put into the blacklist.
void SetHop(uint16_t hop)
RREP_ACK timer.
Definition: aodv-rtable.h:119
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Time NextHopWait
Period of our waiting for the neighbour's RREP_ACK.
Time DeletePeriod
DeletePeriod is intended to provide an upper bound on the time for which an upstream node A can have ...
read and write tag data
Definition: tag-buffer.h:51
Ipv4Address GetBroadcast(void) const
Get the broadcast address.
virtual void NotifyInterfaceDown(uint32_t interface)
Time MyRouteTimeout
Value of lifetime field in RREP generating by this node.
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Definition: log.h:280
uint32_t GetSeqNo() const
RREP_ACK timer.
Definition: aodv-rtable.h:118
void SetQueueTimeout(Time t)
Definition: aodv-rqueue.h:118
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:248
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
A network Node.
Definition: node.h:55
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:103
uint32_t AllowedHelloLoss
Number of hello messages which may be loss for valid link.
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:132
void SendRerrMessage(Ptr< Packet > packet, std::vector< Ipv4Address > precursors)
Forward RERR.
bool IsDuplicate(Ipv4Address addr, uint32_t id)
Check that entry (addr, id) exists in cache. Add entry, if it doesn't exist.
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
void SetCallback(Callback< void, Ipv4Address > cb)
Definition: aodv-neighbor.h:90
void SetAckRequired(bool f)
Definition: aodv-packet.cc:371
void Print(std::ostream &os) const
void SendReply(RreqHeader const &rreqHeader, RoutingTableEntry const &toOrigin)
Send RREP.
uint32_t GetOriginSeqno() const
Definition: aodv-packet.h:134
Abstract base class for IPv4 routing protocols.
void SetNextHop(Ipv4Address nextHop)
RREP_ACK timer.
Definition: aodv-rtable.h:109
bool GetDestinationOnly() const
Definition: aodv-packet.cc:249
uint32_t NetDiameter
Net diameter measures the maximum possible number of hops between two nodes in the network...
Timer m_rerrRateLimitTimer
RERR rate limit timer.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
void AckTimerExpire(Ipv4Address neighbor, Time blacklistTimeout)
Mark link to neighbor node as unidirectional for blacklistTimeout.
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
Ptr< Ipv4Route > GetRoute() const
RREP_ACK timer.
Definition: aodv-rtable.h:107
bool GratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery...
#define NS_LOG_ERROR(msg)
Definition: log.h:271
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
uint16_t RerrRateLimit
Maximum number of REER per second.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetGratiousRrep(bool f)
Definition: aodv-packet.cc:225
void SendRequest(Ipv4Address dst)
Send RREQ.
bool Dequeue(Ipv4Address dst, QueueEntry &entry)
Return first found (the earliest) entry for given destination.
Definition: aodv-rqueue.cc:88
void RerrRateLimitTimerExpire()
Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
tuple address
Definition: first.py:37
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.
IdCache m_rreqIdCache
Handle duplicated RREQ.
void RouteRequestTimerExpire(Ipv4Address dst)
Handle route discovery process.
void Start()
Start protocol operation.
virtual int Close(void)=0
Close a socket.
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:221
Time GetDelayLeft(void) const
Definition: timer.cc:81
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:161
bool IsUnidirectional() const
RREP_ACK timer.
Definition: aodv-rtable.h:129
uint32_t GetId() const
Definition: aodv-packet.h:126
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:234
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:354
a unique identifier for an interface.
Definition: type-id.h:49
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
RouteFlags GetFlag() const
RREP_ACK timer.
Definition: aodv-rtable.h:124
uint32_t m_requestId
Broadcast ID.
Ipv4Address GetDestination() const
RREP_ACK timer.
Definition: aodv-rtable.h:106
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
MessageType Get() const
Return type.
Definition: aodv-packet.h:70
uint8_t GetHopCount() const
Definition: aodv-packet.h:200
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.
uint8_t GetRreqCnt() const
RREP_ACK timer.
Definition: aodv-rtable.h:126
static Time GetMaximumSimulationTime(void)
Definition: simulator.cc:293
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void SetUnknownSeqno(bool f)
Definition: aodv-packet.cc:255
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void ScheduleTimer()
Schedule m_ntimer.
bool GetValidSeqNo() const
RREP_ACK timer.
Definition: aodv-rtable.h:116
static const uint32_t AODV_PORT
UDP Port for AODV control traffic.
void SetHopCount(uint8_t count)
Definition: aodv-packet.h:123
bool EnableHello
Indicates whether a hello messages enable.