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