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