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