A Discrete-Event Network Simulator
API
aodv-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Based on
19  * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
20  * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
21  *
22  * AODV-UU implementation by Erik Nordström of Uppsala University
23  * http://core.it.uu.se/core/index.php/AODV-UU
24  *
25  * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
26  * Pavel Boyko <boyko@iitp.ru>
27  */
28 #define NS_LOG_APPEND_CONTEXT \
29  if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
30 
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 namespace ns3
46 {
47 
48 NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
49 
50 namespace aodv
51 {
52 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
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 //-----------------------------------------------------------------------------
120  RreqRetries (2),
121  RreqRateLimit (10),
122  RerrRateLimit (10),
123  ActiveRouteTimeout (Seconds (3)),
124  NetDiameter (35),
125  NodeTraversalTime (MilliSeconds (40)),
126  NetTraversalTime (Time ((2 * NetDiameter) * NodeTraversalTime)),
127  PathDiscoveryTime ( Time (2 * NetTraversalTime)),
128  MyRouteTimeout (Time (2 * std::max (PathDiscoveryTime, ActiveRouteTimeout))),
129  HelloInterval (Seconds (1)),
130  AllowedHelloLoss (2),
131  DeletePeriod (Time (5 * std::max (ActiveRouteTimeout, HelloInterval))),
132  NextHopWait (NodeTraversalTime + MilliSeconds (10)),
133  BlackListTimeout (Time (RreqRetries * NetTraversalTime)),
134  MaxQueueLen (64),
135  MaxQueueTime (Seconds (30)),
136  DestinationOnly (false),
137  GratuitousReply (true),
138  EnableHello (false),
139  m_routingTable (DeletePeriod),
140  m_queue (MaxQueueLen, MaxQueueTime),
141  m_requestId (0),
142  m_seqNo (0),
143  m_rreqIdCache (PathDiscoveryTime),
144  m_dpd (PathDiscoveryTime),
145  m_nb (HelloInterval),
146  m_rreqCount (0),
147  m_rerrCount (0),
148  m_htimer (Timer::CANCEL_ON_DESTROY),
149  m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
150  m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY),
151  m_lastBcastTime (Seconds (0))
152 {
154 }
155 
156 TypeId
158 {
159  static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
161  .AddConstructor<RoutingProtocol> ()
162  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
163  TimeValue (Seconds (1)),
165  MakeTimeChecker ())
166  .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
167  UintegerValue (2),
169  MakeUintegerChecker<uint32_t> ())
170  .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
171  UintegerValue (10),
173  MakeUintegerChecker<uint32_t> ())
174  .AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
175  UintegerValue (10),
177  MakeUintegerChecker<uint32_t> ())
178  .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
179  "queuing delays, interrupt processing times and transfer times.",
180  TimeValue (MilliSeconds (40)),
182  MakeTimeChecker ())
183  .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
184  TimeValue (MilliSeconds (50)),
186  MakeTimeChecker ())
187  .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
188  TimeValue (Seconds (3)),
190  MakeTimeChecker ())
191  .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
192  TimeValue (Seconds (11.2)),
194  MakeTimeChecker ())
195  .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
196  TimeValue (Seconds (5.6)),
198  MakeTimeChecker ())
199  .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
200  "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
201  " = 5 * max (HelloInterval, ActiveRouteTimeout)",
202  TimeValue (Seconds (15)),
204  MakeTimeChecker ())
205  .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
206  UintegerValue (35),
208  MakeUintegerChecker<uint32_t> ())
209  .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
210  TimeValue (Seconds (2.8)),
212  MakeTimeChecker ())
213  .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
214  TimeValue (Seconds (5.6)),
216  MakeTimeChecker ())
217  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
218  UintegerValue (64),
221  MakeUintegerChecker<uint32_t> ())
222  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
223  TimeValue (Seconds (30)),
226  MakeTimeChecker ())
227  .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
228  UintegerValue (2),
230  MakeUintegerChecker<uint16_t> ())
231  .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
232  BooleanValue (true),
236  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
237  BooleanValue (false),
241  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
242  BooleanValue (true),
246  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
247  BooleanValue (true),
251  .AddAttribute ("UniformRv",
252  "Access to the underlying UniformRandomVariable",
253  StringValue ("ns3::UniformRandomVariable"),
255  MakePointerChecker<UniformRandomVariable> ())
256  ;
257  return tid;
258 }
259 
260 void
262 {
263  MaxQueueLen = len;
264  m_queue.SetMaxQueueLen (len);
265 }
266 void
268 {
269  MaxQueueTime = t;
271 }
272 
274 {
275 }
276 
277 void
279 {
280  m_ipv4 = 0;
281  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
282  m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
283  {
284  iter->first->Close ();
285  }
286  m_socketAddresses.clear ();
287  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
289  {
290  iter->first->Close ();
291  }
294 }
295 
296 void
298 {
299  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now ().GetSeconds () << "s ";
300  m_routingTable.Print (stream);
301 }
302 
303 int64_t
305 {
306  NS_LOG_FUNCTION (this << stream);
308  return 1;
309 }
310 
311 void
313 {
314  NS_LOG_FUNCTION (this);
315  if (EnableHello)
316  {
317  m_nb.ScheduleTimer ();
318  }
320  this);
322 
324  this);
326 
327 }
328 
331  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
332 {
333  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
334  if (!p)
335  {
336  NS_LOG_DEBUG("Packet is == 0");
337  return LoopbackRoute (header, oif); // later
338  }
339  if (m_socketAddresses.empty ())
340  {
341  sockerr = Socket::ERROR_NOROUTETOHOST;
342  NS_LOG_LOGIC ("No aodv interfaces");
343  Ptr<Ipv4Route> route;
344  return route;
345  }
346  sockerr = Socket::ERROR_NOTERROR;
347  Ptr<Ipv4Route> route;
348  Ipv4Address dst = header.GetDestination ();
350  if (m_routingTable.LookupValidRoute (dst, rt))
351  {
352  route = rt.GetRoute ();
353  NS_ASSERT (route != 0);
354  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
355  if (oif != 0 && route->GetOutputDevice () != oif)
356  {
357  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
358  sockerr = Socket::ERROR_NOROUTETOHOST;
359  return Ptr<Ipv4Route> ();
360  }
363  return route;
364  }
365 
366  // Valid route not found, in this case we return loopback.
367  // Actual route request will be deferred until packet will be fully formed,
368  // routed to loopback, received from loopback and passed to RouteInput (see below)
369  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
370  DeferredRouteOutputTag tag (iif);
371  NS_LOG_DEBUG ("Valid Route not found");
372  if (!p->PeekPacketTag (tag))
373  {
374  p->AddPacketTag (tag);
375  }
376  return LoopbackRoute (header, oif);
377 }
378 
379 void
382 {
383  NS_LOG_FUNCTION (this << p << header);
384  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
385 
386  QueueEntry newEntry (p, header, ucb, ecb);
387  bool result = m_queue.Enqueue (newEntry);
388  if (result)
389  {
390  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
392  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
393  if(!result || ((rt.GetFlag () != IN_SEARCH) && result))
394  {
395  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " <<header.GetDestination ());
396  SendRequest (header.GetDestination ());
397  }
398  }
399 }
400 
401 bool
405 {
406  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
407  if (m_socketAddresses.empty ())
408  {
409  NS_LOG_LOGIC ("No aodv interfaces");
410  return false;
411  }
412  NS_ASSERT (m_ipv4 != 0);
413  NS_ASSERT (p != 0);
414  // Check if input device supports IP
415  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
416  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
417 
418  Ipv4Address dst = header.GetDestination ();
419  Ipv4Address origin = header.GetSource ();
420 
421  // Deferred route request
422  if (idev == m_lo)
423  {
425  if (p->PeekPacketTag (tag))
426  {
427  DeferredRouteOutput (p, header, ucb, ecb);
428  return true;
429  }
430  }
431 
432  // Duplicate of own packet
433  if (IsMyOwnAddress (origin))
434  return true;
435 
436  // AODV is not a multicast routing protocol
437  if (dst.IsMulticast ())
438  {
439  return false;
440  }
441 
442  // Broadcast local delivery/forwarding
443  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
444  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
445  {
446  Ipv4InterfaceAddress iface = j->second;
447  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
448  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
449  {
450  if (m_dpd.IsDuplicate (p, header))
451  {
452  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
453  return true;
454  }
456  Ptr<Packet> packet = p->Copy ();
457  if (lcb.IsNull () == false)
458  {
459  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
460  lcb (p, header, iif);
461  // Fall through to additional processing
462  }
463  else
464  {
465  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
466  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
467  }
468  if (!EnableBroadcast)
469  {
470  return true;
471  }
472  if (header.GetTtl () > 1)
473  {
474  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
475  RoutingTableEntry toBroadcast;
476  if (m_routingTable.LookupRoute (dst, toBroadcast))
477  {
478  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
479  ucb (route, packet, header);
480  }
481  else
482  {
483  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
484  }
485  }
486  else
487  {
488  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
489  }
490  return true;
491  }
492  }
493 
494  // Unicast local delivery
495  if (m_ipv4->IsDestinationAddress (dst, iif))
496  {
498  RoutingTableEntry toOrigin;
499  if (m_routingTable.LookupValidRoute (origin, toOrigin))
500  {
502  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
503  }
504  if (lcb.IsNull () == false)
505  {
506  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
507  lcb (p, header, iif);
508  }
509  else
510  {
511  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
512  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
513  }
514  return true;
515  }
516 
517  // Forwarding
518  return Forwarding (p, header, ucb, ecb);
519 }
520 
521 bool
524 {
525  NS_LOG_FUNCTION (this);
526  Ipv4Address dst = header.GetDestination ();
527  Ipv4Address origin = header.GetSource ();
529  RoutingTableEntry toDst;
530  if (m_routingTable.LookupRoute (dst, toDst))
531  {
532  if (toDst.GetFlag () == VALID)
533  {
534  Ptr<Ipv4Route> route = toDst.GetRoute ();
535  NS_LOG_LOGIC (route->GetSource ()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
536 
537  /*
538  * Each time a route is used to forward a data packet, its Active Route
539  * Lifetime field of the source, destination and the next hop on the
540  * path to the destination is updated to be no less than the current
541  * time plus ActiveRouteTimeout.
542  */
546  /*
547  * Since the route between each originator and destination pair is expected to be symmetric, the
548  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
549  * to be no less than the current time plus ActiveRouteTimeout
550  */
551  RoutingTableEntry toOrigin;
552  m_routingTable.LookupRoute (origin, toOrigin);
553  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
554 
556  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
557 
558  ucb (route, p, header);
559  return true;
560  }
561  else
562  {
563  if (toDst.GetValidSeqNo ())
564  {
565  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
566  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
567  return false;
568  }
569  }
570  }
571  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
572  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
573  SendRerrWhenNoRouteToForward (dst, 0, origin);
574  return false;
575 }
576 
577 void
579 {
580  NS_ASSERT (ipv4 != 0);
581  NS_ASSERT (m_ipv4 == 0);
582 
583  if (EnableHello)
584  {
587  }
588 
589  m_ipv4 = ipv4;
590 
591  // Create lo route. It is asserted that the only one interface up for now is loopback
592  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
593  m_lo = m_ipv4->GetNetDevice (0);
594  NS_ASSERT (m_lo != 0);
595  // Remember lo route
596  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
597  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
598  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
599  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
601 
603 }
604 
605 void
607 {
608  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
609  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
610  if (l3->GetNAddresses (i) > 1)
611  {
612  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
613  }
614  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
615  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
616  return;
617 
618  // Create a socket to listen only on this interface
619  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
621  NS_ASSERT (socket != 0);
624  socket->BindToNetDevice (l3->GetNetDevice (i));
625  socket->SetAllowBroadcast (true);
626  socket->SetAttribute ("IpTtl", UintegerValue (1));
627  m_socketAddresses.insert (std::make_pair (socket, iface));
628 
629  // create also a subnet broadcast socket
630  socket = Socket::CreateSocket (GetObject<Node> (),
632  NS_ASSERT (socket != 0);
634  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
635  socket->BindToNetDevice (l3->GetNetDevice (i));
636  socket->SetAllowBroadcast (true);
637  socket->SetAttribute ("IpTtl", UintegerValue (1));
638  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
639 
640  // Add local broadcast record to the routing table
641  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
642  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
643  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
645 
646  if (l3->GetInterface (i)->GetArpCache ())
647  {
648  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
649  }
650 
651  // Allow neighbor manager use this interface for layer 2 feedback if possible
652  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
653  if (wifi == 0)
654  return;
655  Ptr<WifiMac> mac = wifi->GetMac ();
656  if (mac == 0)
657  return;
658 
659  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
660 }
661 
662 void
664 {
665  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
666 
667  // Disable layer 2 link state monitoring (if possible)
668  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
669  Ptr<NetDevice> dev = l3->GetNetDevice (i);
670  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
671  if (wifi != 0)
672  {
673  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
674  if (mac != 0)
675  {
676  mac->TraceDisconnectWithoutContext ("TxErrHeader",
678  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
679  }
680  }
681 
682  // Close socket
683  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
684  NS_ASSERT (socket);
685  socket->Close ();
686  m_socketAddresses.erase (socket);
687 
688  // Close socket
689  socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
690  NS_ASSERT (socket);
691  socket->Close ();
692  m_socketSubnetBroadcastAddresses.erase (socket);
693 
694  if (m_socketAddresses.empty ())
695  {
696  NS_LOG_LOGIC ("No aodv interfaces");
697  m_htimer.Cancel ();
698  m_nb.Clear ();
700  return;
701  }
703 }
704 
705 void
707 {
708  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
709  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
710  if (!l3->IsUp (i))
711  return;
712  if (l3->GetNAddresses (i) == 1)
713  {
714  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
716  if (!socket)
717  {
718  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
719  return;
720  // Create a socket to listen only on this interface
721  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
723  NS_ASSERT (socket != 0);
725  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
726  socket->BindToNetDevice (l3->GetNetDevice (i));
727  socket->SetAllowBroadcast (true);
728  m_socketAddresses.insert (std::make_pair (socket, iface));
729 
730  // create also a subnet directed broadcast socket
731  socket = Socket::CreateSocket (GetObject<Node> (),
733  NS_ASSERT (socket != 0);
735  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
736  socket->BindToNetDevice (l3->GetNetDevice (i));
737  socket->SetAllowBroadcast (true);
738  socket->SetAttribute ("IpTtl", UintegerValue (1));
739  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
740 
741  // Add local broadcast record to the routing table
742  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
743  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
744  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
745  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
746  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
748  }
749  }
750  else
751  {
752  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
753  }
754 }
755 
756 void
758 {
759  NS_LOG_FUNCTION (this);
760  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
761  if (socket)
762  {
764  socket->Close ();
765  m_socketAddresses.erase (socket);
766 
768  if (unicastSocket)
769  {
770  unicastSocket->Close ();
771  m_socketAddresses.erase (unicastSocket);
772  }
773 
774  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
775  if (l3->GetNAddresses (i))
776  {
777  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
778  // Create a socket to listen only on this interface
779  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
781  NS_ASSERT (socket != 0);
783  // Bind to any IP address so that broadcasts can be received
784  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
785  socket->BindToNetDevice (l3->GetNetDevice (i));
786  socket->SetAllowBroadcast (true);
787  socket->SetAttribute ("IpTtl", UintegerValue (1));
788  m_socketAddresses.insert (std::make_pair (socket, iface));
789 
790  // create also a unicast socket
791  socket = Socket::CreateSocket (GetObject<Node> (),
793  NS_ASSERT (socket != 0);
795  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
796  socket->BindToNetDevice (l3->GetNetDevice (i));
797  socket->SetAllowBroadcast (true);
798  socket->SetAttribute ("IpTtl", UintegerValue (1));
799  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
800 
801  // Add local broadcast record to the routing table
802  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
803  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
804  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
806  }
807  if (m_socketAddresses.empty ())
808  {
809  NS_LOG_LOGIC ("No aodv interfaces");
810  m_htimer.Cancel ();
811  m_nb.Clear ();
813  return;
814  }
815  }
816  else
817  {
818  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
819  }
820 }
821 
822 bool
824 {
825  NS_LOG_FUNCTION (this << src);
826  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
827  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
828  {
829  Ipv4InterfaceAddress iface = j->second;
830  if (src == iface.GetLocal ())
831  {
832  return true;
833  }
834  }
835  return false;
836 }
837 
840 {
841  NS_LOG_FUNCTION (this << hdr);
842  NS_ASSERT (m_lo != 0);
843  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
844  rt->SetDestination (hdr.GetDestination ());
845  //
846  // Source address selection here is tricky. The loopback route is
847  // returned when AODV does not have a route; this causes the packet
848  // to be looped back and handled (cached) in RouteInput() method
849  // while a route is found. However, connection-oriented protocols
850  // like TCP need to create an endpoint four-tuple (src, src port,
851  // dst, dst port) and create a pseudo-header for checksumming. So,
852  // AODV needs to guess correctly what the eventual source address
853  // will be.
854  //
855  // For single interface, single address nodes, this is not a problem.
856  // When there are possibly multiple outgoing interfaces, the policy
857  // implemented here is to pick the first available AODV interface.
858  // If RouteOutput() caller specified an outgoing interface, that
859  // further constrains the selection of source address
860  //
861  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
862  if (oif)
863  {
864  // Iterate to find an address on the oif device
865  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
866  {
867  Ipv4Address addr = j->second.GetLocal ();
868  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
869  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
870  {
871  rt->SetSource (addr);
872  break;
873  }
874  }
875  }
876  else
877  {
878  rt->SetSource (j->second.GetLocal ());
879  }
880  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
881  rt->SetGateway (Ipv4Address ("127.0.0.1"));
882  rt->SetOutputDevice (m_lo);
883  return rt;
884 }
885 
886 void
888 {
889  NS_LOG_FUNCTION ( this << dst);
890  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
891  if (m_rreqCount == RreqRateLimit)
892  {
894  &RoutingProtocol::SendRequest, this, dst);
895  return;
896  }
897  else
898  m_rreqCount++;
899  // Create RREQ header
900  RreqHeader rreqHeader;
901  rreqHeader.SetDst (dst);
902 
904  if (m_routingTable.LookupRoute (dst, rt))
905  {
906  rreqHeader.SetHopCount (rt.GetHop ());
907  if (rt.GetValidSeqNo ())
908  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
909  else
910  rreqHeader.SetUnknownSeqno (true);
911  rt.SetFlag (IN_SEARCH);
912  m_routingTable.Update (rt);
913  }
914  else
915  {
916  rreqHeader.SetUnknownSeqno (true);
917  Ptr<NetDevice> dev = 0;
918  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
919  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
920  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0));
921  newEntry.SetFlag (IN_SEARCH);
922  m_routingTable.AddRoute (newEntry);
923  }
924 
925  if (GratuitousReply)
926  rreqHeader.SetGratiousRrep (true);
927  if (DestinationOnly)
928  rreqHeader.SetDestinationOnly (true);
929 
930  m_seqNo++;
931  rreqHeader.SetOriginSeqno (m_seqNo);
932  m_requestId++;
933  rreqHeader.SetId (m_requestId);
934  rreqHeader.SetHopCount (0);
935 
936  // Send RREQ as subnet directed broadcast from each interface used by aodv
937  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
938  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
939  {
940  Ptr<Socket> socket = j->first;
941  Ipv4InterfaceAddress iface = j->second;
942 
943  rreqHeader.SetOrigin (iface.GetLocal ());
945 
946  Ptr<Packet> packet = Create<Packet> ();
947  packet->AddHeader (rreqHeader);
948  TypeHeader tHeader (AODVTYPE_RREQ);
949  packet->AddHeader (tHeader);
950  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
951  Ipv4Address destination;
952  if (iface.GetMask () == Ipv4Mask::GetOnes ())
953  {
954  destination = Ipv4Address ("255.255.255.255");
955  }
956  else
957  {
958  destination = iface.GetBroadcast ();
959  }
960  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
962  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
963  }
964  ScheduleRreqRetry (dst);
965 }
966 
967 void
969 {
970  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
971 
972 }
973 void
975 {
976  NS_LOG_FUNCTION (this << dst);
977  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
978  {
980  m_addressReqTimer[dst] = timer;
981  }
983  m_addressReqTimer[dst].Remove ();
984  m_addressReqTimer[dst].SetArguments (dst);
986  m_routingTable.LookupRoute (dst, rt);
987  rt.IncrementRreqCnt ();
988  m_routingTable.Update (rt);
989  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
990  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
991 }
992 
993 void
995 {
996  NS_LOG_FUNCTION (this << socket);
997  Address sourceAddress;
998  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
999  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
1000  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
1001  Ipv4Address receiver;
1002 
1003  if (m_socketAddresses.find (socket) != m_socketAddresses.end ())
1004  {
1005  receiver = m_socketAddresses[socket].GetLocal ();
1006  }
1008  {
1009  receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal ();
1010  }
1011  else
1012  {
1013  NS_ASSERT_MSG (false, "Received a packet from an unknown socket");
1014  }
1015  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
1016 
1017  UpdateRouteToNeighbor (sender, receiver);
1018  TypeHeader tHeader (AODVTYPE_RREQ);
1019  packet->RemoveHeader (tHeader);
1020  if (!tHeader.IsValid ())
1021  {
1022  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
1023  return; // drop
1024  }
1025  switch (tHeader.Get ())
1026  {
1027  case AODVTYPE_RREQ:
1028  {
1029  RecvRequest (packet, receiver, sender);
1030  break;
1031  }
1032  case AODVTYPE_RREP:
1033  {
1034  RecvReply (packet, receiver, sender);
1035  break;
1036  }
1037  case AODVTYPE_RERR:
1038  {
1039  RecvError (packet, sender);
1040  break;
1041  }
1042  case AODVTYPE_RREP_ACK:
1043  {
1044  RecvReplyAck (sender);
1045  break;
1046  }
1047  }
1048 }
1049 
1050 bool
1052 {
1053  NS_LOG_FUNCTION (this << addr << lifetime);
1054  RoutingTableEntry rt;
1055  if (m_routingTable.LookupRoute (addr, rt))
1056  {
1057  if (rt.GetFlag () == VALID)
1058  {
1059  NS_LOG_DEBUG ("Updating VALID route");
1060  rt.SetRreqCnt (0);
1061  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
1062  m_routingTable.Update (rt);
1063  return true;
1064  }
1065  }
1066  return false;
1067 }
1068 
1069 void
1071 {
1072  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1073  RoutingTableEntry toNeighbor;
1074  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1075  {
1076  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1077  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1078  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1079  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout);
1080  m_routingTable.AddRoute (newEntry);
1081  }
1082  else
1083  {
1084  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1085  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1086  {
1087  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1088  }
1089  else
1090  {
1091  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1092  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1093  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1094  m_routingTable.Update (newEntry);
1095  }
1096  }
1097 
1098 }
1099 
1100 void
1102 {
1103  NS_LOG_FUNCTION (this);
1104  RreqHeader rreqHeader;
1105  p->RemoveHeader (rreqHeader);
1106 
1107  // A node ignores all RREQs received from any node in its blacklist
1108  RoutingTableEntry toPrev;
1109  if (m_routingTable.LookupRoute (src, toPrev))
1110  {
1111  if (toPrev.IsUnidirectional ())
1112  {
1113  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1114  return;
1115  }
1116  }
1117 
1118  uint32_t id = rreqHeader.GetId ();
1119  Ipv4Address origin = rreqHeader.GetOrigin ();
1120 
1121  /*
1122  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1123  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1124  */
1125  if (m_rreqIdCache.IsDuplicate (origin, id))
1126  {
1127  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1128  return;
1129  }
1130 
1131  // Increment RREQ hop count
1132  uint8_t hop = rreqHeader.GetHopCount () + 1;
1133  rreqHeader.SetHopCount (hop);
1134 
1135  /*
1136  * When the reverse route is created or updated, the following actions on the route are also carried out:
1137  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1138  * in the route table entry and copied if greater than the existing value there
1139  * 2. the valid sequence number field is set to true;
1140  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1141  * 4. the hop count is copied from the Hop Count in the RREQ message;
1142  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1143  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1144  */
1145  RoutingTableEntry toOrigin;
1146  if (!m_routingTable.LookupRoute (origin, toOrigin))
1147  {
1148  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1149  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1150  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1151  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)));
1152  m_routingTable.AddRoute (newEntry);
1153  }
1154  else
1155  {
1156  if (toOrigin.GetValidSeqNo ())
1157  {
1158  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1159  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1160  }
1161  else
1162  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1163  toOrigin.SetValidSeqNo (true);
1164  toOrigin.SetNextHop (src);
1165  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1166  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1167  toOrigin.SetHop (hop);
1168  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1169  toOrigin.GetLifeTime ()));
1170  m_routingTable.Update (toOrigin);
1171  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1172  }
1173 
1174 
1175  RoutingTableEntry toNeighbor;
1176  if (!m_routingTable.LookupRoute (src, toNeighbor))
1177  {
1178  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1179  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1180  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1181  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1182  1, src, ActiveRouteTimeout);
1183  m_routingTable.AddRoute (newEntry);
1184  }
1185  else
1186  {
1187  toNeighbor.SetLifeTime (ActiveRouteTimeout);
1188  toNeighbor.SetValidSeqNo (false);
1189  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1190  toNeighbor.SetFlag (VALID);
1191  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1192  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1193  toNeighbor.SetHop (1);
1194  toNeighbor.SetNextHop (src);
1195  m_routingTable.Update (toNeighbor);
1196  }
1198 
1199  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1200  << " ID " << rreqHeader.GetId ()
1201  << " to destination " << rreqHeader.GetDst ());
1202 
1203  // A node generates a RREP if either:
1204  // (i) it is itself the destination,
1205  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1206  {
1207  m_routingTable.LookupRoute (origin, toOrigin);
1208  NS_LOG_DEBUG ("Send reply since I am the destination");
1209  SendReply (rreqHeader, toOrigin);
1210  return;
1211  }
1212  /*
1213  * (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
1214  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1215  */
1216  RoutingTableEntry toDst;
1217  Ipv4Address dst = rreqHeader.GetDst ();
1218  if (m_routingTable.LookupRoute (dst, toDst))
1219  {
1220  /*
1221  * Drop RREQ, This node RREP wil make a loop.
1222  */
1223  if (toDst.GetNextHop () == src)
1224  {
1225  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1226  return;
1227  }
1228  /*
1229  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1230  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1231  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1232  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1233  */
1234  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1235  && toDst.GetValidSeqNo () )
1236  {
1237  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1238  {
1239  m_routingTable.LookupRoute (origin, toOrigin);
1240  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1241  return;
1242  }
1243  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1244  rreqHeader.SetUnknownSeqno (false);
1245  }
1246  }
1247 
1248  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1249  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1250  {
1251  Ptr<Socket> socket = j->first;
1252  Ipv4InterfaceAddress iface = j->second;
1253  Ptr<Packet> packet = Create<Packet> ();
1254  packet->AddHeader (rreqHeader);
1255  TypeHeader tHeader (AODVTYPE_RREQ);
1256  packet->AddHeader (tHeader);
1257  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1258  Ipv4Address destination;
1259  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1260  {
1261  destination = Ipv4Address ("255.255.255.255");
1262  }
1263  else
1264  {
1265  destination = iface.GetBroadcast ();
1266  }
1268  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1269 
1270  }
1271 }
1272 
1273 void
1274 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1275 {
1276  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1277  /*
1278  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1279  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1280  */
1281  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1282  m_seqNo++;
1283  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1284  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout);
1285  Ptr<Packet> packet = Create<Packet> ();
1286  packet->AddHeader (rrepHeader);
1287  TypeHeader tHeader (AODVTYPE_RREP);
1288  packet->AddHeader (tHeader);
1290  NS_ASSERT (socket);
1291  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1292 }
1293 
1294 void
1296 {
1297  NS_LOG_FUNCTION (this);
1298  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1299  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1300  /* If the node we received a RREQ for is a neighbor we are
1301  * probably facing a unidirectional link... Better request a RREP-ack
1302  */
1303  if (toDst.GetHop () == 1)
1304  {
1305  rrepHeader.SetAckRequired (true);
1306  RoutingTableEntry toNextHop;
1307  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1309  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1310  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1311  }
1312  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1313  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1314  m_routingTable.Update (toDst);
1315  m_routingTable.Update (toOrigin);
1316 
1317  Ptr<Packet> packet = Create<Packet> ();
1318  packet->AddHeader (rrepHeader);
1319  TypeHeader tHeader (AODVTYPE_RREP);
1320  packet->AddHeader (tHeader);
1322  NS_ASSERT (socket);
1323  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1324 
1325  // Generating gratuitous RREPs
1326  if (gratRep)
1327  {
1328  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1329  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1330  /*lifetime=*/ toOrigin.GetLifeTime ());
1331  Ptr<Packet> packetToDst = Create<Packet> ();
1332  packetToDst->AddHeader (gratRepHeader);
1333  TypeHeader type (AODVTYPE_RREP);
1334  packetToDst->AddHeader (type);
1336  NS_ASSERT (socket);
1337  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1338  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1339  }
1340 }
1341 
1342 void
1344 {
1345  NS_LOG_FUNCTION (this << " to " << neighbor);
1346  RrepAckHeader h;
1347  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1348  Ptr<Packet> packet = Create<Packet> ();
1349  packet->AddHeader (h);
1350  packet->AddHeader (typeHeader);
1351  RoutingTableEntry toNeighbor;
1352  m_routingTable.LookupRoute (neighbor, toNeighbor);
1353  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1354  NS_ASSERT (socket);
1355  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1356 }
1357 
1358 void
1360 {
1361  NS_LOG_FUNCTION (this << " src " << sender);
1362  RrepHeader rrepHeader;
1363  p->RemoveHeader (rrepHeader);
1364  Ipv4Address dst = rrepHeader.GetDst ();
1365  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1366 
1367  uint8_t hop = rrepHeader.GetHopCount () + 1;
1368  rrepHeader.SetHopCount (hop);
1369 
1370  // If RREP is Hello message
1371  if (dst == rrepHeader.GetOrigin ())
1372  {
1373  ProcessHello (rrepHeader, receiver);
1374  return;
1375  }
1376 
1377  /*
1378  * If the route table entry to the destination is created or updated, then the following actions occur:
1379  * - the route is marked as active,
1380  * - the destination sequence number is marked as valid,
1381  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1382  * which is indicated by the source IP address field in the IP header,
1383  * - the hop count is set to the value of the hop count from RREP message + 1
1384  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1385  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1386  */
1387  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1388  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1389  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1390  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1391  RoutingTableEntry toDst;
1392  if (m_routingTable.LookupRoute (dst, toDst))
1393  {
1394  /*
1395  * The existing entry is updated only in the following circumstances:
1396  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1397  */
1398  if (!toDst.GetValidSeqNo ())
1399  {
1400  m_routingTable.Update (newEntry);
1401  }
1402  // (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,
1403  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1404  {
1405  m_routingTable.Update (newEntry);
1406  }
1407  else
1408  {
1409  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1410  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1411  {
1412  m_routingTable.Update (newEntry);
1413  }
1414  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1415  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1416  {
1417  m_routingTable.Update (newEntry);
1418  }
1419  }
1420  }
1421  else
1422  {
1423  // The forward route for this destination is created if it does not already exist.
1424  NS_LOG_LOGIC ("add new route");
1425  m_routingTable.AddRoute (newEntry);
1426  }
1427  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1428  if (rrepHeader.GetAckRequired ())
1429  {
1430  SendReplyAck (sender);
1431  rrepHeader.SetAckRequired (false);
1432  }
1433  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1434  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1435  {
1436  if (toDst.GetFlag () == IN_SEARCH)
1437  {
1438  m_routingTable.Update (newEntry);
1439  m_addressReqTimer[dst].Remove ();
1440  m_addressReqTimer.erase (dst);
1441  }
1442  m_routingTable.LookupRoute (dst, toDst);
1443  SendPacketFromQueue (dst, toDst.GetRoute ());
1444  return;
1445  }
1446 
1447  RoutingTableEntry toOrigin;
1448  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1449  {
1450  return; // Impossible! drop.
1451  }
1452  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1453  m_routingTable.Update (toOrigin);
1454 
1455  // Update information about precursors
1456  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1457  {
1458  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1459  m_routingTable.Update (toDst);
1460 
1461  RoutingTableEntry toNextHopToDst;
1462  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1463  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1464  m_routingTable.Update (toNextHopToDst);
1465 
1466  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1467  m_routingTable.Update (toOrigin);
1468 
1469  RoutingTableEntry toNextHopToOrigin;
1470  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1471  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1472  m_routingTable.Update (toNextHopToOrigin);
1473  }
1474 
1475  Ptr<Packet> packet = Create<Packet> ();
1476  packet->AddHeader (rrepHeader);
1477  TypeHeader tHeader (AODVTYPE_RREP);
1478  packet->AddHeader (tHeader);
1480  NS_ASSERT (socket);
1481  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1482 }
1483 
1484 void
1486 {
1487  NS_LOG_FUNCTION (this);
1488  RoutingTableEntry rt;
1489  if(m_routingTable.LookupRoute (neighbor, rt))
1490  {
1491  rt.m_ackTimer.Cancel ();
1492  rt.SetFlag (VALID);
1493  m_routingTable.Update (rt);
1494  }
1495 }
1496 
1497 void
1499 {
1500  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1501  /*
1502  * Whenever a node receives a Hello message from a neighbor, the node
1503  * SHOULD make sure that it has an active route to the neighbor, and
1504  * create one if necessary.
1505  */
1506  RoutingTableEntry toNeighbor;
1507  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1508  {
1509  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1510  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1511  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1512  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1513  m_routingTable.AddRoute (newEntry);
1514  }
1515  else
1516  {
1517  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1518  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1519  toNeighbor.SetValidSeqNo (true);
1520  toNeighbor.SetFlag (VALID);
1521  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1522  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1523  toNeighbor.SetHop (1);
1524  toNeighbor.SetNextHop (rrepHeader.GetDst ());
1525  m_routingTable.Update (toNeighbor);
1526  }
1527  if (EnableHello)
1528  {
1529  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1530  }
1531 }
1532 
1533 void
1535 {
1536  NS_LOG_FUNCTION (this << " from " << src);
1537  RerrHeader rerrHeader;
1538  p->RemoveHeader (rerrHeader);
1539  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1540  std::map<Ipv4Address, uint32_t> unreachable;
1541  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1542  std::pair<Ipv4Address, uint32_t> un;
1543  while (rerrHeader.RemoveUnDestination (un))
1544  {
1545  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1546  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1547  {
1548  if (i->first == un.first)
1549  {
1550  unreachable.insert (un);
1551  }
1552  }
1553  }
1554 
1555  std::vector<Ipv4Address> precursors;
1556  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1557  i != unreachable.end ();)
1558  {
1559  if (!rerrHeader.AddUnDestination (i->first, i->second))
1560  {
1561  TypeHeader typeHeader (AODVTYPE_RERR);
1562  Ptr<Packet> packet = Create<Packet> ();
1563  packet->AddHeader (rerrHeader);
1564  packet->AddHeader (typeHeader);
1565  SendRerrMessage (packet, precursors);
1566  rerrHeader.Clear ();
1567  }
1568  else
1569  {
1570  RoutingTableEntry toDst;
1571  m_routingTable.LookupRoute (i->first, toDst);
1572  toDst.GetPrecursors (precursors);
1573  ++i;
1574  }
1575  }
1576  if (rerrHeader.GetDestCount () != 0)
1577  {
1578  TypeHeader typeHeader (AODVTYPE_RERR);
1579  Ptr<Packet> packet = Create<Packet> ();
1580  packet->AddHeader (rerrHeader);
1581  packet->AddHeader (typeHeader);
1582  SendRerrMessage (packet, precursors);
1583  }
1585 }
1586 
1587 void
1589 {
1590  NS_LOG_LOGIC (this);
1591  RoutingTableEntry toDst;
1592  if (m_routingTable.LookupValidRoute (dst, toDst))
1593  {
1594  SendPacketFromQueue (dst, toDst.GetRoute ());
1595  NS_LOG_LOGIC ("route to " << dst << " found");
1596  return;
1597  }
1598  /*
1599  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1600  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1601  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1602  */
1603  if (toDst.GetRreqCnt () == RreqRetries)
1604  {
1605  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1606  m_addressReqTimer.erase (dst);
1608  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1609  m_queue.DropPacketWithDst (dst);
1610  return;
1611  }
1612 
1613  if (toDst.GetFlag () == IN_SEARCH)
1614  {
1615  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1616  SendRequest (dst);
1617  }
1618  else
1619  {
1620  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1621  m_addressReqTimer.erase (dst);
1623  m_queue.DropPacketWithDst (dst);
1624  }
1625 }
1626 
1627 void
1629 {
1630  NS_LOG_FUNCTION (this);
1631  Time offset = Time (Seconds (0));
1632  if (m_lastBcastTime > Time (Seconds (0)))
1633  {
1634  offset = Simulator::Now () - m_lastBcastTime;
1635  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1636  }
1637  else
1638  {
1639  SendHello ();
1640  }
1641  m_htimer.Cancel ();
1642  Time diff = HelloInterval - offset;
1643  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1644  m_lastBcastTime = Time (Seconds (0));
1645 }
1646 
1647 void
1649 {
1650  NS_LOG_FUNCTION (this);
1651  m_rreqCount = 0;
1653 }
1654 
1655 void
1657 {
1658  NS_LOG_FUNCTION (this);
1659  m_rerrCount = 0;
1661 }
1662 
1663 void
1665 {
1666  NS_LOG_FUNCTION (this);
1667  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1668 }
1669 
1670 void
1672 {
1673  NS_LOG_FUNCTION (this);
1674  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1675  * Destination IP Address The node's IP address.
1676  * Destination Sequence Number The node's latest sequence number.
1677  * Hop Count 0
1678  * Lifetime AllowedHelloLoss * HelloInterval
1679  */
1680  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1681  {
1682  Ptr<Socket> socket = j->first;
1683  Ipv4InterfaceAddress iface = j->second;
1684  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1685  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval));
1686  Ptr<Packet> packet = Create<Packet> ();
1687  packet->AddHeader (helloHeader);
1688  TypeHeader tHeader (AODVTYPE_RREP);
1689  packet->AddHeader (tHeader);
1690  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1691  Ipv4Address destination;
1692  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1693  {
1694  destination = Ipv4Address ("255.255.255.255");
1695  }
1696  else
1697  {
1698  destination = iface.GetBroadcast ();
1699  }
1701  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this , socket, packet, destination);
1702  }
1703 }
1704 
1705 void
1707 {
1708  NS_LOG_FUNCTION (this);
1709  QueueEntry queueEntry;
1710  while (m_queue.Dequeue (dst, queueEntry))
1711  {
1713  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1714  if (p->RemovePacketTag (tag) &&
1715  tag.GetInterface() != -1 &&
1716  tag.GetInterface() != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1717  {
1718  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1719  return;
1720  }
1722  Ipv4Header header = queueEntry.GetIpv4Header ();
1723  header.SetSource (route->GetSource ());
1724  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1725  ucb (route, p, header);
1726  }
1727 }
1728 
1729 void
1731 {
1732  NS_LOG_FUNCTION (this << nextHop);
1733  RerrHeader rerrHeader;
1734  std::vector<Ipv4Address> precursors;
1735  std::map<Ipv4Address, uint32_t> unreachable;
1736 
1737  RoutingTableEntry toNextHop;
1738  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1739  return;
1740  toNextHop.GetPrecursors (precursors);
1741  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1742  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1743  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1744  != unreachable.end ();)
1745  {
1746  if (!rerrHeader.AddUnDestination (i->first, i->second))
1747  {
1748  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1749  TypeHeader typeHeader (AODVTYPE_RERR);
1750  Ptr<Packet> packet = Create<Packet> ();
1751  packet->AddHeader (rerrHeader);
1752  packet->AddHeader (typeHeader);
1753  SendRerrMessage (packet, precursors);
1754  rerrHeader.Clear ();
1755  }
1756  else
1757  {
1758  RoutingTableEntry toDst;
1759  m_routingTable.LookupRoute (i->first, toDst);
1760  toDst.GetPrecursors (precursors);
1761  ++i;
1762  }
1763  }
1764  if (rerrHeader.GetDestCount () != 0)
1765  {
1766  TypeHeader typeHeader (AODVTYPE_RERR);
1767  Ptr<Packet> packet = Create<Packet> ();
1768  packet->AddHeader (rerrHeader);
1769  packet->AddHeader (typeHeader);
1770  SendRerrMessage (packet, precursors);
1771  }
1772  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1774 }
1775 
1776 void
1778  uint32_t dstSeqNo, Ipv4Address origin)
1779 {
1780  NS_LOG_FUNCTION (this);
1781  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1782  if (m_rerrCount == RerrRateLimit)
1783  {
1784  // Just make sure that the RerrRateLimit timer is running and will expire
1786  // discard the packet and return
1787  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1789  << "; suppressing RERR");
1790  return;
1791  }
1792  RerrHeader rerrHeader;
1793  rerrHeader.AddUnDestination (dst, dstSeqNo);
1794  RoutingTableEntry toOrigin;
1795  Ptr<Packet> packet = Create<Packet> ();
1796  packet->AddHeader (rerrHeader);
1797  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1798  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1799  {
1801  toOrigin.GetInterface ());
1802  NS_ASSERT (socket);
1803  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1804  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1805  }
1806  else
1807  {
1808  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1809  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1810  {
1811  Ptr<Socket> socket = i->first;
1812  Ipv4InterfaceAddress iface = i->second;
1813  NS_ASSERT (socket);
1814  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1815  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1816  Ipv4Address destination;
1817  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1818  {
1819  destination = Ipv4Address ("255.255.255.255");
1820  }
1821  else
1822  {
1823  destination = iface.GetBroadcast ();
1824  }
1825  socket->SendTo (packet->Copy (), 0, InetSocketAddress (destination, AODV_PORT));
1826  }
1827  }
1828 }
1829 
1830 void
1831 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1832 {
1833  NS_LOG_FUNCTION (this);
1834 
1835  if (precursors.empty ())
1836  {
1837  NS_LOG_LOGIC ("No precursors");
1838  return;
1839  }
1840  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1841  if (m_rerrCount == RerrRateLimit)
1842  {
1843  // Just make sure that the RerrRateLimit timer is running and will expire
1845  // discard the packet and return
1846  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1848  << "; suppressing RERR");
1849  return;
1850  }
1851  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1852  if (precursors.size () == 1)
1853  {
1854  RoutingTableEntry toPrecursor;
1855  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1856  {
1857  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1858  NS_ASSERT (socket);
1859  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1860  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
1861  m_rerrCount++;
1862  }
1863  return;
1864  }
1865 
1866  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1867  std::vector<Ipv4InterfaceAddress> ifaces;
1868  RoutingTableEntry toPrecursor;
1869  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1870  {
1871  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1872  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1873  {
1874  ifaces.push_back (toPrecursor.GetInterface ());
1875  }
1876  }
1877 
1878  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1879  {
1881  NS_ASSERT (socket);
1882  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1883  // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
1884  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1885  Ptr<Packet> p = packet->Copy ();
1886  Ipv4Address destination;
1887  if (i->GetMask () == Ipv4Mask::GetOnes ())
1888  {
1889  destination = Ipv4Address ("255.255.255.255");
1890  }
1891  else
1892  {
1893  destination = i->GetBroadcast ();
1894  }
1895  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, p, destination);
1896  }
1897 }
1898 
1901 {
1902  NS_LOG_FUNCTION (this << addr);
1903  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1904  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1905  {
1906  Ptr<Socket> socket = j->first;
1907  Ipv4InterfaceAddress iface = j->second;
1908  if (iface == addr)
1909  return socket;
1910  }
1911  Ptr<Socket> socket;
1912  return socket;
1913 }
1914 
1917 {
1918  NS_LOG_FUNCTION (this << addr);
1919  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1921  {
1922  Ptr<Socket> socket = j->first;
1923  Ipv4InterfaceAddress iface = j->second;
1924  if (iface == addr)
1925  return socket;
1926  }
1927  Ptr<Socket> socket;
1928  return socket;
1929 }
1930 
1931 }
1932 }
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:315
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:421
an Inet address class
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
void SetOutputDevice(Ptr< NetDevice > dev)
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.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
AttributeValue implementation for Boolean.
Definition: boolean.h:34
Ipv4Mask GetMask(void) const
Get the network mask.
Callback template class.
Definition: callback.h:978
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:200
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:235
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:73
Ipv4Header GetIpv4Header() const
Definition: aodv-rqueue.h:72
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void SetId(uint32_t id)
Definition: aodv-packet.h:120
bool GetAckRequired() const
Definition: aodv-packet.cc:377
Ipv4Address GetLocal(void) const
Get the local address.
Hold variables of type string.
Definition: string.h:41
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
Route Error (RERR) Message Format.
Definition: aodv-packet.h:272
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:226
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
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:836
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:261
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:380
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:133
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void IncrementRreqCnt()
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:1072
void SetMaxQueueLen(uint32_t len)
Definition: aodv-rqueue.h:117
#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:122
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:193
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:867
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual void DoDispose()
Destructor implementation.
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)
Destructor implementation.
Definition: object.cc:338
Ptr< NetDevice > GetOutputDevice() const
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:128
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:819
void SetLifeTime(Time lt)
Definition: aodv-rtable.h:121
uint32_t RreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
STL namespace.
Route Request (RREQ) Message Format.
Definition: aodv-packet.h:100
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:50
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 unicast socket with local interface address iface.
a polymophic address class
Definition: address.h:90
bool IsRunning(void) const
Definition: timer.cc:127
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:70
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:66
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:439
Time GetLifeTime() const
Definition: aodv-rtable.h:122
bool DestinationOnly
Indicates only the destination may respond to this RREQ.
void SetRreqCnt(uint8_t n)
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:858
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:188
bool IsMyOwnAddress(Ipv4Address src)
Check that packet is send from own interface.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:210
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:335
void HelloTimerExpire()
Schedule next send of hello message.
AttributeValue implementation for Time.
Definition: nstime.h:921
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
uint8_t GetDestCount() const
Return number of unreachable destinations in RERR message.
Definition: aodv-packet.h:302
Ipv4Address GetNextHop() const
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:305
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:44
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Update neighbor record.
Ipv4Address GetDst() const
Definition: aodv-packet.h:123
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)
Definition: aodv-rtable.h:117
uint16_t RreqRateLimit
Maximum number of RREQ per second.
void SetValidSeqNo(bool s)
Definition: aodv-rtable.h:115
void SetOriginSeqno(uint32_t s)
Definition: aodv-packet.h:128
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:1290
uint8_t GetHopCount() const
Definition: aodv-packet.h:119
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
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:75
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:72
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
static Ipv4Address GetBroadcast(void)
void SetDstSeqno(uint32_t s)
Definition: aodv-packet.h:124
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:172
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:298
void SetInterface(Ipv4InterfaceAddress iface)
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.
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:320
Implement the Ipv4 layer.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses
Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP + mask) ...
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
void SetFlag(RouteFlags flag)
Definition: aodv-rtable.h:123
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:195
uint16_t GetHop() const
Definition: aodv-rtable.h:120
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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
Ptr< Socket > FindSubnetBroadcastSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find subnet directed broadcast socket with local interface address iface.
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
void SetOrigin(Ipv4Address a)
Definition: aodv-packet.h:126
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw unicast 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:980
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:922
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 virtual time.
Definition: simulator.cc:223
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:191
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:232
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:125
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)
Definition: aodv-rtable.h:119
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
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:228
uint32_t GetSeqNo() const
Definition: aodv-rtable.h:118
void SetQueueTimeout(Time t)
Definition: aodv-rqueue.h:119
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: aodv-rtable.cc:249
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:843
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:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
uint32_t AllowedHelloLoss
Number of hello messages which may be loss for valid link.
Ipv4Address GetOrigin() const
Definition: aodv-packet.h:127
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)
Handle link failure callback.
Definition: aodv-neighbor.h:89
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:129
Abstract base class for IPv4 routing protocols.
void SetNextHop(Ipv4Address nextHop)
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.
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
Definition: aodv-rtable.h:107
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:875
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:220
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:89
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.
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
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:222
Time GetDelayLeft(void) const
Definition: timer.cc:87
This policy cancels the event from the destructor of the Timer to verify that the event has already e...
Definition: timer.h:86
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:190
bool IsUnidirectional() const
Definition: aodv-rtable.h:129
uint32_t GetId() const
Definition: aodv-packet.h:121
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:235
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:355
a unique identifier for an interface.
Definition: type-id.h:51
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
RouteFlags GetFlag() const
Definition: aodv-rtable.h:124
uint32_t m_requestId
Broadcast ID.
Ipv4Address GetDestination() const
Definition: aodv-rtable.h:106
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
MessageType Get() const
Return type.
Definition: aodv-packet.h:68
uint8_t GetHopCount() const
Definition: aodv-packet.h:189
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
Definition: aodv-rtable.h:126
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:336
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
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:118
bool EnableHello
Indicates whether a hello messages enable.