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")
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 ()
302  << "; Time: " << Now().As (Time::S)
303  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (Time::S)
304  << ", AODV Routing table" << std::endl;
305 
306  m_routingTable.Print (stream);
307  *stream->GetStream () << std::endl;
308 }
309 
310 int64_t
312 {
313  NS_LOG_FUNCTION (this << stream);
315  return 1;
316 }
317 
318 void
320 {
321  NS_LOG_FUNCTION (this);
322  if (EnableHello)
323  {
324  m_nb.ScheduleTimer ();
325  }
327  this);
329 
331  this);
333 
334 }
335 
338  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
339 {
340  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
341  if (!p)
342  {
343  NS_LOG_DEBUG("Packet is == 0");
344  return LoopbackRoute (header, oif); // later
345  }
346  if (m_socketAddresses.empty ())
347  {
348  sockerr = Socket::ERROR_NOROUTETOHOST;
349  NS_LOG_LOGIC ("No aodv interfaces");
350  Ptr<Ipv4Route> route;
351  return route;
352  }
353  sockerr = Socket::ERROR_NOTERROR;
354  Ptr<Ipv4Route> route;
355  Ipv4Address dst = header.GetDestination ();
357  if (m_routingTable.LookupValidRoute (dst, rt))
358  {
359  route = rt.GetRoute ();
360  NS_ASSERT (route != 0);
361  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
362  if (oif != 0 && route->GetOutputDevice () != oif)
363  {
364  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
365  sockerr = Socket::ERROR_NOROUTETOHOST;
366  return Ptr<Ipv4Route> ();
367  }
370  return route;
371  }
372 
373  // Valid route not found, in this case we return loopback.
374  // Actual route request will be deferred until packet will be fully formed,
375  // routed to loopback, received from loopback and passed to RouteInput (see below)
376  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
377  DeferredRouteOutputTag tag (iif);
378  NS_LOG_DEBUG ("Valid Route not found");
379  if (!p->PeekPacketTag (tag))
380  {
381  p->AddPacketTag (tag);
382  }
383  return LoopbackRoute (header, oif);
384 }
385 
386 void
389 {
390  NS_LOG_FUNCTION (this << p << header);
391  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
392 
393  QueueEntry newEntry (p, header, ucb, ecb);
394  bool result = m_queue.Enqueue (newEntry);
395  if (result)
396  {
397  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
399  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
400  if(!result || ((rt.GetFlag () != IN_SEARCH) && result))
401  {
402  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " <<header.GetDestination ());
403  SendRequest (header.GetDestination ());
404  }
405  }
406 }
407 
408 bool
412 {
413  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
414  if (m_socketAddresses.empty ())
415  {
416  NS_LOG_LOGIC ("No aodv interfaces");
417  return false;
418  }
419  NS_ASSERT (m_ipv4 != 0);
420  NS_ASSERT (p != 0);
421  // Check if input device supports IP
422  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
423  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
424 
425  Ipv4Address dst = header.GetDestination ();
426  Ipv4Address origin = header.GetSource ();
427 
428  // Deferred route request
429  if (idev == m_lo)
430  {
432  if (p->PeekPacketTag (tag))
433  {
434  DeferredRouteOutput (p, header, ucb, ecb);
435  return true;
436  }
437  }
438 
439  // Duplicate of own packet
440  if (IsMyOwnAddress (origin))
441  return true;
442 
443  // AODV is not a multicast routing protocol
444  if (dst.IsMulticast ())
445  {
446  return false;
447  }
448 
449  // Broadcast local delivery/forwarding
450  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
451  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
452  {
453  Ipv4InterfaceAddress iface = j->second;
454  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
455  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
456  {
457  if (m_dpd.IsDuplicate (p, header))
458  {
459  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
460  return true;
461  }
463  Ptr<Packet> packet = p->Copy ();
464  if (lcb.IsNull () == false)
465  {
466  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
467  lcb (p, header, iif);
468  // Fall through to additional processing
469  }
470  else
471  {
472  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
473  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
474  }
475  if (!EnableBroadcast)
476  {
477  return true;
478  }
479  if (header.GetTtl () > 1)
480  {
481  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
482  RoutingTableEntry toBroadcast;
483  if (m_routingTable.LookupRoute (dst, toBroadcast))
484  {
485  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
486  ucb (route, packet, header);
487  }
488  else
489  {
490  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
491  }
492  }
493  else
494  {
495  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
496  }
497  return true;
498  }
499  }
500 
501  // Unicast local delivery
502  if (m_ipv4->IsDestinationAddress (dst, iif))
503  {
505  RoutingTableEntry toOrigin;
506  if (m_routingTable.LookupValidRoute (origin, toOrigin))
507  {
509  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
510  }
511  if (lcb.IsNull () == false)
512  {
513  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
514  lcb (p, header, iif);
515  }
516  else
517  {
518  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
519  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
520  }
521  return true;
522  }
523 
524  // Forwarding
525  return Forwarding (p, header, ucb, ecb);
526 }
527 
528 bool
531 {
532  NS_LOG_FUNCTION (this);
533  Ipv4Address dst = header.GetDestination ();
534  Ipv4Address origin = header.GetSource ();
536  RoutingTableEntry toDst;
537  if (m_routingTable.LookupRoute (dst, toDst))
538  {
539  if (toDst.GetFlag () == VALID)
540  {
541  Ptr<Ipv4Route> route = toDst.GetRoute ();
542  NS_LOG_LOGIC (route->GetSource ()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
543 
544  /*
545  * Each time a route is used to forward a data packet, its Active Route
546  * Lifetime field of the source, destination and the next hop on the
547  * path to the destination is updated to be no less than the current
548  * time plus ActiveRouteTimeout.
549  */
553  /*
554  * Since the route between each originator and destination pair is expected to be symmetric, the
555  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
556  * to be no less than the current time plus ActiveRouteTimeout
557  */
558  RoutingTableEntry toOrigin;
559  m_routingTable.LookupRoute (origin, toOrigin);
560  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
561 
563  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
564 
565  ucb (route, p, header);
566  return true;
567  }
568  else
569  {
570  if (toDst.GetValidSeqNo ())
571  {
572  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
573  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
574  return false;
575  }
576  }
577  }
578  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
579  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
580  SendRerrWhenNoRouteToForward (dst, 0, origin);
581  return false;
582 }
583 
584 void
586 {
587  NS_ASSERT (ipv4 != 0);
588  NS_ASSERT (m_ipv4 == 0);
589 
590  m_ipv4 = ipv4;
591 
592  // Create lo route. It is asserted that the only one interface up for now is loopback
593  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
594  m_lo = m_ipv4->GetNetDevice (0);
595  NS_ASSERT (m_lo != 0);
596  // Remember lo route
597  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
598  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
599  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
600  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
602 
604 }
605 
606 void
608 {
609  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
610  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
611  if (l3->GetNAddresses (i) > 1)
612  {
613  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
614  }
615  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
616  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
617  return;
618 
619  // Create a socket to listen only on this interface
620  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
622  NS_ASSERT (socket != 0);
625  socket->BindToNetDevice (l3->GetNetDevice (i));
626  socket->SetAllowBroadcast (true);
627  socket->SetAttribute ("IpTtl", UintegerValue (1));
628  m_socketAddresses.insert (std::make_pair (socket, iface));
629 
630  // create also a subnet broadcast socket
631  socket = Socket::CreateSocket (GetObject<Node> (),
633  NS_ASSERT (socket != 0);
635  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
636  socket->BindToNetDevice (l3->GetNetDevice (i));
637  socket->SetAllowBroadcast (true);
638  socket->SetAttribute ("IpTtl", UintegerValue (1));
639  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
640 
641  // Add local broadcast record to the routing table
642  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
643  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
644  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
646 
647  if (l3->GetInterface (i)->GetArpCache ())
648  {
649  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
650  }
651 
652  // Allow neighbor manager use this interface for layer 2 feedback if possible
653  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
654  if (wifi == 0)
655  return;
656  Ptr<WifiMac> mac = wifi->GetMac ();
657  if (mac == 0)
658  return;
659 
660  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
661 }
662 
663 void
665 {
666  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
667 
668  // Disable layer 2 link state monitoring (if possible)
669  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
670  Ptr<NetDevice> dev = l3->GetNetDevice (i);
671  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
672  if (wifi != 0)
673  {
674  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
675  if (mac != 0)
676  {
677  mac->TraceDisconnectWithoutContext ("TxErrHeader",
679  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
680  }
681  }
682 
683  // Close socket
684  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
685  NS_ASSERT (socket);
686  socket->Close ();
687  m_socketAddresses.erase (socket);
688 
689  // Close socket
690  socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
691  NS_ASSERT (socket);
692  socket->Close ();
693  m_socketSubnetBroadcastAddresses.erase (socket);
694 
695  if (m_socketAddresses.empty ())
696  {
697  NS_LOG_LOGIC ("No aodv interfaces");
698  m_htimer.Cancel ();
699  m_nb.Clear ();
701  return;
702  }
704 }
705 
706 void
708 {
709  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
710  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
711  if (!l3->IsUp (i))
712  return;
713  if (l3->GetNAddresses (i) == 1)
714  {
715  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
717  if (!socket)
718  {
719  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
720  return;
721  // Create a socket to listen only on this interface
722  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
724  NS_ASSERT (socket != 0);
726  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
727  socket->BindToNetDevice (l3->GetNetDevice (i));
728  socket->SetAllowBroadcast (true);
729  m_socketAddresses.insert (std::make_pair (socket, iface));
730 
731  // create also a subnet directed broadcast socket
732  socket = Socket::CreateSocket (GetObject<Node> (),
734  NS_ASSERT (socket != 0);
736  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
737  socket->BindToNetDevice (l3->GetNetDevice (i));
738  socket->SetAllowBroadcast (true);
739  socket->SetAttribute ("IpTtl", UintegerValue (1));
740  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
741 
742  // Add local broadcast record to the routing table
743  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
744  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
745  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
746  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
747  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
749  }
750  }
751  else
752  {
753  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
754  }
755 }
756 
757 void
759 {
760  NS_LOG_FUNCTION (this);
761  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
762  if (socket)
763  {
765  socket->Close ();
766  m_socketAddresses.erase (socket);
767 
769  if (unicastSocket)
770  {
771  unicastSocket->Close ();
772  m_socketAddresses.erase (unicastSocket);
773  }
774 
775  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
776  if (l3->GetNAddresses (i))
777  {
778  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
779  // Create a socket to listen only on this interface
780  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
782  NS_ASSERT (socket != 0);
784  // Bind to any IP address so that broadcasts can be received
785  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
786  socket->BindToNetDevice (l3->GetNetDevice (i));
787  socket->SetAllowBroadcast (true);
788  socket->SetAttribute ("IpTtl", UintegerValue (1));
789  m_socketAddresses.insert (std::make_pair (socket, iface));
790 
791  // create also a unicast socket
792  socket = Socket::CreateSocket (GetObject<Node> (),
794  NS_ASSERT (socket != 0);
796  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
797  socket->BindToNetDevice (l3->GetNetDevice (i));
798  socket->SetAllowBroadcast (true);
799  socket->SetAttribute ("IpTtl", UintegerValue (1));
800  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
801 
802  // Add local broadcast record to the routing table
803  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
804  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
805  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
807  }
808  if (m_socketAddresses.empty ())
809  {
810  NS_LOG_LOGIC ("No aodv interfaces");
811  m_htimer.Cancel ();
812  m_nb.Clear ();
814  return;
815  }
816  }
817  else
818  {
819  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
820  }
821 }
822 
823 bool
825 {
826  NS_LOG_FUNCTION (this << src);
827  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
828  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
829  {
830  Ipv4InterfaceAddress iface = j->second;
831  if (src == iface.GetLocal ())
832  {
833  return true;
834  }
835  }
836  return false;
837 }
838 
841 {
842  NS_LOG_FUNCTION (this << hdr);
843  NS_ASSERT (m_lo != 0);
844  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
845  rt->SetDestination (hdr.GetDestination ());
846  //
847  // Source address selection here is tricky. The loopback route is
848  // returned when AODV does not have a route; this causes the packet
849  // to be looped back and handled (cached) in RouteInput() method
850  // while a route is found. However, connection-oriented protocols
851  // like TCP need to create an endpoint four-tuple (src, src port,
852  // dst, dst port) and create a pseudo-header for checksumming. So,
853  // AODV needs to guess correctly what the eventual source address
854  // will be.
855  //
856  // For single interface, single address nodes, this is not a problem.
857  // When there are possibly multiple outgoing interfaces, the policy
858  // implemented here is to pick the first available AODV interface.
859  // If RouteOutput() caller specified an outgoing interface, that
860  // further constrains the selection of source address
861  //
862  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
863  if (oif)
864  {
865  // Iterate to find an address on the oif device
866  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
867  {
868  Ipv4Address addr = j->second.GetLocal ();
869  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
870  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
871  {
872  rt->SetSource (addr);
873  break;
874  }
875  }
876  }
877  else
878  {
879  rt->SetSource (j->second.GetLocal ());
880  }
881  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
882  rt->SetGateway (Ipv4Address ("127.0.0.1"));
883  rt->SetOutputDevice (m_lo);
884  return rt;
885 }
886 
887 void
889 {
890  NS_LOG_FUNCTION ( this << dst);
891  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
892  if (m_rreqCount == RreqRateLimit)
893  {
895  &RoutingProtocol::SendRequest, this, dst);
896  return;
897  }
898  else
899  m_rreqCount++;
900  // Create RREQ header
901  RreqHeader rreqHeader;
902  rreqHeader.SetDst (dst);
903 
905  if (m_routingTable.LookupRoute (dst, rt))
906  {
907  rreqHeader.SetHopCount (rt.GetHop ());
908  if (rt.GetValidSeqNo ())
909  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
910  else
911  rreqHeader.SetUnknownSeqno (true);
912  rt.SetFlag (IN_SEARCH);
913  m_routingTable.Update (rt);
914  }
915  else
916  {
917  rreqHeader.SetUnknownSeqno (true);
918  Ptr<NetDevice> dev = 0;
919  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
920  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
921  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0));
922  newEntry.SetFlag (IN_SEARCH);
923  m_routingTable.AddRoute (newEntry);
924  }
925 
926  if (GratuitousReply)
927  rreqHeader.SetGratiousRrep (true);
928  if (DestinationOnly)
929  rreqHeader.SetDestinationOnly (true);
930 
931  m_seqNo++;
932  rreqHeader.SetOriginSeqno (m_seqNo);
933  m_requestId++;
934  rreqHeader.SetId (m_requestId);
935  rreqHeader.SetHopCount (0);
936 
937  // Send RREQ as subnet directed broadcast from each interface used by aodv
938  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
939  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
940  {
941  Ptr<Socket> socket = j->first;
942  Ipv4InterfaceAddress iface = j->second;
943 
944  rreqHeader.SetOrigin (iface.GetLocal ());
946 
947  Ptr<Packet> packet = Create<Packet> ();
948  packet->AddHeader (rreqHeader);
949  TypeHeader tHeader (AODVTYPE_RREQ);
950  packet->AddHeader (tHeader);
951  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
952  Ipv4Address destination;
953  if (iface.GetMask () == Ipv4Mask::GetOnes ())
954  {
955  destination = Ipv4Address ("255.255.255.255");
956  }
957  else
958  {
959  destination = iface.GetBroadcast ();
960  }
961  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
963  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
964  }
965  ScheduleRreqRetry (dst);
966 }
967 
968 void
970 {
971  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
972 
973 }
974 void
976 {
977  NS_LOG_FUNCTION (this << dst);
978  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
979  {
981  m_addressReqTimer[dst] = timer;
982  }
984  m_addressReqTimer[dst].Remove ();
985  m_addressReqTimer[dst].SetArguments (dst);
987  m_routingTable.LookupRoute (dst, rt);
988  rt.IncrementRreqCnt ();
989  m_routingTable.Update (rt);
990  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
991  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
992 }
993 
994 void
996 {
997  NS_LOG_FUNCTION (this << socket);
998  Address sourceAddress;
999  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
1000  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
1001  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
1002  Ipv4Address receiver;
1003 
1004  if (m_socketAddresses.find (socket) != m_socketAddresses.end ())
1005  {
1006  receiver = m_socketAddresses[socket].GetLocal ();
1007  }
1009  {
1010  receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal ();
1011  }
1012  else
1013  {
1014  NS_ASSERT_MSG (false, "Received a packet from an unknown socket");
1015  }
1016  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
1017 
1018  UpdateRouteToNeighbor (sender, receiver);
1019  TypeHeader tHeader (AODVTYPE_RREQ);
1020  packet->RemoveHeader (tHeader);
1021  if (!tHeader.IsValid ())
1022  {
1023  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
1024  return; // drop
1025  }
1026  switch (tHeader.Get ())
1027  {
1028  case AODVTYPE_RREQ:
1029  {
1030  RecvRequest (packet, receiver, sender);
1031  break;
1032  }
1033  case AODVTYPE_RREP:
1034  {
1035  RecvReply (packet, receiver, sender);
1036  break;
1037  }
1038  case AODVTYPE_RERR:
1039  {
1040  RecvError (packet, sender);
1041  break;
1042  }
1043  case AODVTYPE_RREP_ACK:
1044  {
1045  RecvReplyAck (sender);
1046  break;
1047  }
1048  }
1049 }
1050 
1051 bool
1053 {
1054  NS_LOG_FUNCTION (this << addr << lifetime);
1055  RoutingTableEntry rt;
1056  if (m_routingTable.LookupRoute (addr, rt))
1057  {
1058  if (rt.GetFlag () == VALID)
1059  {
1060  NS_LOG_DEBUG ("Updating VALID route");
1061  rt.SetRreqCnt (0);
1062  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
1063  m_routingTable.Update (rt);
1064  return true;
1065  }
1066  }
1067  return false;
1068 }
1069 
1070 void
1072 {
1073  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1074  RoutingTableEntry toNeighbor;
1075  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1076  {
1077  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1078  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1079  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1080  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout);
1081  m_routingTable.AddRoute (newEntry);
1082  }
1083  else
1084  {
1085  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1086  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1087  {
1088  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1089  }
1090  else
1091  {
1092  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1093  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1094  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1095  m_routingTable.Update (newEntry);
1096  }
1097  }
1098 
1099 }
1100 
1101 void
1103 {
1104  NS_LOG_FUNCTION (this);
1105  RreqHeader rreqHeader;
1106  p->RemoveHeader (rreqHeader);
1107 
1108  // A node ignores all RREQs received from any node in its blacklist
1109  RoutingTableEntry toPrev;
1110  if (m_routingTable.LookupRoute (src, toPrev))
1111  {
1112  if (toPrev.IsUnidirectional ())
1113  {
1114  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1115  return;
1116  }
1117  }
1118 
1119  uint32_t id = rreqHeader.GetId ();
1120  Ipv4Address origin = rreqHeader.GetOrigin ();
1121 
1122  /*
1123  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1124  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1125  */
1126  if (m_rreqIdCache.IsDuplicate (origin, id))
1127  {
1128  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1129  return;
1130  }
1131 
1132  // Increment RREQ hop count
1133  uint8_t hop = rreqHeader.GetHopCount () + 1;
1134  rreqHeader.SetHopCount (hop);
1135 
1136  /*
1137  * When the reverse route is created or updated, the following actions on the route are also carried out:
1138  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1139  * in the route table entry and copied if greater than the existing value there
1140  * 2. the valid sequence number field is set to true;
1141  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1142  * 4. the hop count is copied from the Hop Count in the RREQ message;
1143  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1144  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1145  */
1146  RoutingTableEntry toOrigin;
1147  if (!m_routingTable.LookupRoute (origin, toOrigin))
1148  {
1149  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1150  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1151  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1152  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)));
1153  m_routingTable.AddRoute (newEntry);
1154  }
1155  else
1156  {
1157  if (toOrigin.GetValidSeqNo ())
1158  {
1159  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1160  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1161  }
1162  else
1163  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1164  toOrigin.SetValidSeqNo (true);
1165  toOrigin.SetNextHop (src);
1166  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1167  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1168  toOrigin.SetHop (hop);
1169  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1170  toOrigin.GetLifeTime ()));
1171  m_routingTable.Update (toOrigin);
1172  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1173  }
1174 
1175 
1176  RoutingTableEntry toNeighbor;
1177  if (!m_routingTable.LookupRoute (src, toNeighbor))
1178  {
1179  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1180  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1181  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1182  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1183  1, src, ActiveRouteTimeout);
1184  m_routingTable.AddRoute (newEntry);
1185  }
1186  else
1187  {
1188  toNeighbor.SetLifeTime (ActiveRouteTimeout);
1189  toNeighbor.SetValidSeqNo (false);
1190  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1191  toNeighbor.SetFlag (VALID);
1192  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1193  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1194  toNeighbor.SetHop (1);
1195  toNeighbor.SetNextHop (src);
1196  m_routingTable.Update (toNeighbor);
1197  }
1199 
1200  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1201  << " ID " << rreqHeader.GetId ()
1202  << " to destination " << rreqHeader.GetDst ());
1203 
1204  // A node generates a RREP if either:
1205  // (i) it is itself the destination,
1206  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1207  {
1208  m_routingTable.LookupRoute (origin, toOrigin);
1209  NS_LOG_DEBUG ("Send reply since I am the destination");
1210  SendReply (rreqHeader, toOrigin);
1211  return;
1212  }
1213  /*
1214  * (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
1215  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1216  */
1217  RoutingTableEntry toDst;
1218  Ipv4Address dst = rreqHeader.GetDst ();
1219  if (m_routingTable.LookupRoute (dst, toDst))
1220  {
1221  /*
1222  * Drop RREQ, This node RREP wil make a loop.
1223  */
1224  if (toDst.GetNextHop () == src)
1225  {
1226  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1227  return;
1228  }
1229  /*
1230  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1231  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1232  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1233  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1234  */
1235  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1236  && toDst.GetValidSeqNo () )
1237  {
1238  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1239  {
1240  m_routingTable.LookupRoute (origin, toOrigin);
1241  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1242  return;
1243  }
1244  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1245  rreqHeader.SetUnknownSeqno (false);
1246  }
1247  }
1248 
1249  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1250  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1251  {
1252  Ptr<Socket> socket = j->first;
1253  Ipv4InterfaceAddress iface = j->second;
1254  Ptr<Packet> packet = Create<Packet> ();
1255  packet->AddHeader (rreqHeader);
1256  TypeHeader tHeader (AODVTYPE_RREQ);
1257  packet->AddHeader (tHeader);
1258  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1259  Ipv4Address destination;
1260  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1261  {
1262  destination = Ipv4Address ("255.255.255.255");
1263  }
1264  else
1265  {
1266  destination = iface.GetBroadcast ();
1267  }
1269  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1270 
1271  }
1272 }
1273 
1274 void
1275 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1276 {
1277  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1278  /*
1279  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1280  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1281  */
1282  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1283  m_seqNo++;
1284  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1285  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout);
1286  Ptr<Packet> packet = Create<Packet> ();
1287  packet->AddHeader (rrepHeader);
1288  TypeHeader tHeader (AODVTYPE_RREP);
1289  packet->AddHeader (tHeader);
1291  NS_ASSERT (socket);
1292  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1293 }
1294 
1295 void
1297 {
1298  NS_LOG_FUNCTION (this);
1299  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1300  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1301  /* If the node we received a RREQ for is a neighbor we are
1302  * probably facing a unidirectional link... Better request a RREP-ack
1303  */
1304  if (toDst.GetHop () == 1)
1305  {
1306  rrepHeader.SetAckRequired (true);
1307  RoutingTableEntry toNextHop;
1308  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1310  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1311  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1312  }
1313  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1314  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1315  m_routingTable.Update (toDst);
1316  m_routingTable.Update (toOrigin);
1317 
1318  Ptr<Packet> packet = Create<Packet> ();
1319  packet->AddHeader (rrepHeader);
1320  TypeHeader tHeader (AODVTYPE_RREP);
1321  packet->AddHeader (tHeader);
1323  NS_ASSERT (socket);
1324  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1325 
1326  // Generating gratuitous RREPs
1327  if (gratRep)
1328  {
1329  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1330  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1331  /*lifetime=*/ toOrigin.GetLifeTime ());
1332  Ptr<Packet> packetToDst = Create<Packet> ();
1333  packetToDst->AddHeader (gratRepHeader);
1334  TypeHeader type (AODVTYPE_RREP);
1335  packetToDst->AddHeader (type);
1337  NS_ASSERT (socket);
1338  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1339  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1340  }
1341 }
1342 
1343 void
1345 {
1346  NS_LOG_FUNCTION (this << " to " << neighbor);
1347  RrepAckHeader h;
1348  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1349  Ptr<Packet> packet = Create<Packet> ();
1350  packet->AddHeader (h);
1351  packet->AddHeader (typeHeader);
1352  RoutingTableEntry toNeighbor;
1353  m_routingTable.LookupRoute (neighbor, toNeighbor);
1354  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1355  NS_ASSERT (socket);
1356  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1357 }
1358 
1359 void
1361 {
1362  NS_LOG_FUNCTION (this << " src " << sender);
1363  RrepHeader rrepHeader;
1364  p->RemoveHeader (rrepHeader);
1365  Ipv4Address dst = rrepHeader.GetDst ();
1366  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1367 
1368  uint8_t hop = rrepHeader.GetHopCount () + 1;
1369  rrepHeader.SetHopCount (hop);
1370 
1371  // If RREP is Hello message
1372  if (dst == rrepHeader.GetOrigin ())
1373  {
1374  ProcessHello (rrepHeader, receiver);
1375  return;
1376  }
1377 
1378  /*
1379  * If the route table entry to the destination is created or updated, then the following actions occur:
1380  * - the route is marked as active,
1381  * - the destination sequence number is marked as valid,
1382  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1383  * which is indicated by the source IP address field in the IP header,
1384  * - the hop count is set to the value of the hop count from RREP message + 1
1385  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1386  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1387  */
1388  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1389  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1390  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1391  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1392  RoutingTableEntry toDst;
1393  if (m_routingTable.LookupRoute (dst, toDst))
1394  {
1395  /*
1396  * The existing entry is updated only in the following circumstances:
1397  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1398  */
1399  if (!toDst.GetValidSeqNo ())
1400  {
1401  m_routingTable.Update (newEntry);
1402  }
1403  // (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,
1404  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1405  {
1406  m_routingTable.Update (newEntry);
1407  }
1408  else
1409  {
1410  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1411  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1412  {
1413  m_routingTable.Update (newEntry);
1414  }
1415  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1416  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1417  {
1418  m_routingTable.Update (newEntry);
1419  }
1420  }
1421  }
1422  else
1423  {
1424  // The forward route for this destination is created if it does not already exist.
1425  NS_LOG_LOGIC ("add new route");
1426  m_routingTable.AddRoute (newEntry);
1427  }
1428  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1429  if (rrepHeader.GetAckRequired ())
1430  {
1431  SendReplyAck (sender);
1432  rrepHeader.SetAckRequired (false);
1433  }
1434  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1435  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1436  {
1437  if (toDst.GetFlag () == IN_SEARCH)
1438  {
1439  m_routingTable.Update (newEntry);
1440  m_addressReqTimer[dst].Remove ();
1441  m_addressReqTimer.erase (dst);
1442  }
1443  m_routingTable.LookupRoute (dst, toDst);
1444  SendPacketFromQueue (dst, toDst.GetRoute ());
1445  return;
1446  }
1447 
1448  RoutingTableEntry toOrigin;
1449  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1450  {
1451  return; // Impossible! drop.
1452  }
1453  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1454  m_routingTable.Update (toOrigin);
1455 
1456  // Update information about precursors
1457  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1458  {
1459  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1460  m_routingTable.Update (toDst);
1461 
1462  RoutingTableEntry toNextHopToDst;
1463  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1464  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1465  m_routingTable.Update (toNextHopToDst);
1466 
1467  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1468  m_routingTable.Update (toOrigin);
1469 
1470  RoutingTableEntry toNextHopToOrigin;
1471  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1472  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1473  m_routingTable.Update (toNextHopToOrigin);
1474  }
1475 
1476  Ptr<Packet> packet = Create<Packet> ();
1477  packet->AddHeader (rrepHeader);
1478  TypeHeader tHeader (AODVTYPE_RREP);
1479  packet->AddHeader (tHeader);
1481  NS_ASSERT (socket);
1482  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1483 }
1484 
1485 void
1487 {
1488  NS_LOG_FUNCTION (this);
1489  RoutingTableEntry rt;
1490  if(m_routingTable.LookupRoute (neighbor, rt))
1491  {
1492  rt.m_ackTimer.Cancel ();
1493  rt.SetFlag (VALID);
1494  m_routingTable.Update (rt);
1495  }
1496 }
1497 
1498 void
1500 {
1501  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1502  /*
1503  * Whenever a node receives a Hello message from a neighbor, the node
1504  * SHOULD make sure that it has an active route to the neighbor, and
1505  * create one if necessary.
1506  */
1507  RoutingTableEntry toNeighbor;
1508  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1509  {
1510  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1511  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1512  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1513  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1514  m_routingTable.AddRoute (newEntry);
1515  }
1516  else
1517  {
1518  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1519  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1520  toNeighbor.SetValidSeqNo (true);
1521  toNeighbor.SetFlag (VALID);
1522  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1523  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1524  toNeighbor.SetHop (1);
1525  toNeighbor.SetNextHop (rrepHeader.GetDst ());
1526  m_routingTable.Update (toNeighbor);
1527  }
1528  if (EnableHello)
1529  {
1530  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1531  }
1532 }
1533 
1534 void
1536 {
1537  NS_LOG_FUNCTION (this << " from " << src);
1538  RerrHeader rerrHeader;
1539  p->RemoveHeader (rerrHeader);
1540  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1541  std::map<Ipv4Address, uint32_t> unreachable;
1542  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1543  std::pair<Ipv4Address, uint32_t> un;
1544  while (rerrHeader.RemoveUnDestination (un))
1545  {
1546  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1547  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1548  {
1549  if (i->first == un.first)
1550  {
1551  unreachable.insert (un);
1552  }
1553  }
1554  }
1555 
1556  std::vector<Ipv4Address> precursors;
1557  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1558  i != unreachable.end ();)
1559  {
1560  if (!rerrHeader.AddUnDestination (i->first, i->second))
1561  {
1562  TypeHeader typeHeader (AODVTYPE_RERR);
1563  Ptr<Packet> packet = Create<Packet> ();
1564  packet->AddHeader (rerrHeader);
1565  packet->AddHeader (typeHeader);
1566  SendRerrMessage (packet, precursors);
1567  rerrHeader.Clear ();
1568  }
1569  else
1570  {
1571  RoutingTableEntry toDst;
1572  m_routingTable.LookupRoute (i->first, toDst);
1573  toDst.GetPrecursors (precursors);
1574  ++i;
1575  }
1576  }
1577  if (rerrHeader.GetDestCount () != 0)
1578  {
1579  TypeHeader typeHeader (AODVTYPE_RERR);
1580  Ptr<Packet> packet = Create<Packet> ();
1581  packet->AddHeader (rerrHeader);
1582  packet->AddHeader (typeHeader);
1583  SendRerrMessage (packet, precursors);
1584  }
1586 }
1587 
1588 void
1590 {
1591  NS_LOG_LOGIC (this);
1592  RoutingTableEntry toDst;
1593  if (m_routingTable.LookupValidRoute (dst, toDst))
1594  {
1595  SendPacketFromQueue (dst, toDst.GetRoute ());
1596  NS_LOG_LOGIC ("route to " << dst << " found");
1597  return;
1598  }
1599  /*
1600  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1601  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1602  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1603  */
1604  if (toDst.GetRreqCnt () == RreqRetries)
1605  {
1606  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1607  m_addressReqTimer.erase (dst);
1609  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1610  m_queue.DropPacketWithDst (dst);
1611  return;
1612  }
1613 
1614  if (toDst.GetFlag () == IN_SEARCH)
1615  {
1616  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1617  SendRequest (dst);
1618  }
1619  else
1620  {
1621  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1622  m_addressReqTimer.erase (dst);
1624  m_queue.DropPacketWithDst (dst);
1625  }
1626 }
1627 
1628 void
1630 {
1631  NS_LOG_FUNCTION (this);
1632  Time offset = Time (Seconds (0));
1633  if (m_lastBcastTime > Time (Seconds (0)))
1634  {
1635  offset = Simulator::Now () - m_lastBcastTime;
1636  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1637  }
1638  else
1639  {
1640  SendHello ();
1641  }
1642  m_htimer.Cancel ();
1643  Time diff = HelloInterval - offset;
1644  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1645  m_lastBcastTime = Time (Seconds (0));
1646 }
1647 
1648 void
1650 {
1651  NS_LOG_FUNCTION (this);
1652  m_rreqCount = 0;
1654 }
1655 
1656 void
1658 {
1659  NS_LOG_FUNCTION (this);
1660  m_rerrCount = 0;
1662 }
1663 
1664 void
1666 {
1667  NS_LOG_FUNCTION (this);
1668  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1669 }
1670 
1671 void
1673 {
1674  NS_LOG_FUNCTION (this);
1675  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1676  * Destination IP Address The node's IP address.
1677  * Destination Sequence Number The node's latest sequence number.
1678  * Hop Count 0
1679  * Lifetime AllowedHelloLoss * HelloInterval
1680  */
1681  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1682  {
1683  Ptr<Socket> socket = j->first;
1684  Ipv4InterfaceAddress iface = j->second;
1685  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1686  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval));
1687  Ptr<Packet> packet = Create<Packet> ();
1688  packet->AddHeader (helloHeader);
1689  TypeHeader tHeader (AODVTYPE_RREP);
1690  packet->AddHeader (tHeader);
1691  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1692  Ipv4Address destination;
1693  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1694  {
1695  destination = Ipv4Address ("255.255.255.255");
1696  }
1697  else
1698  {
1699  destination = iface.GetBroadcast ();
1700  }
1702  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this , socket, packet, destination);
1703  }
1704 }
1705 
1706 void
1708 {
1709  NS_LOG_FUNCTION (this);
1710  QueueEntry queueEntry;
1711  while (m_queue.Dequeue (dst, queueEntry))
1712  {
1714  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1715  if (p->RemovePacketTag (tag) &&
1716  tag.GetInterface() != -1 &&
1717  tag.GetInterface() != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1718  {
1719  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1720  return;
1721  }
1723  Ipv4Header header = queueEntry.GetIpv4Header ();
1724  header.SetSource (route->GetSource ());
1725  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1726  ucb (route, p, header);
1727  }
1728 }
1729 
1730 void
1732 {
1733  NS_LOG_FUNCTION (this << nextHop);
1734  RerrHeader rerrHeader;
1735  std::vector<Ipv4Address> precursors;
1736  std::map<Ipv4Address, uint32_t> unreachable;
1737 
1738  RoutingTableEntry toNextHop;
1739  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1740  return;
1741  toNextHop.GetPrecursors (precursors);
1742  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1743  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1744  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1745  != unreachable.end ();)
1746  {
1747  if (!rerrHeader.AddUnDestination (i->first, i->second))
1748  {
1749  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1750  TypeHeader typeHeader (AODVTYPE_RERR);
1751  Ptr<Packet> packet = Create<Packet> ();
1752  packet->AddHeader (rerrHeader);
1753  packet->AddHeader (typeHeader);
1754  SendRerrMessage (packet, precursors);
1755  rerrHeader.Clear ();
1756  }
1757  else
1758  {
1759  RoutingTableEntry toDst;
1760  m_routingTable.LookupRoute (i->first, toDst);
1761  toDst.GetPrecursors (precursors);
1762  ++i;
1763  }
1764  }
1765  if (rerrHeader.GetDestCount () != 0)
1766  {
1767  TypeHeader typeHeader (AODVTYPE_RERR);
1768  Ptr<Packet> packet = Create<Packet> ();
1769  packet->AddHeader (rerrHeader);
1770  packet->AddHeader (typeHeader);
1771  SendRerrMessage (packet, precursors);
1772  }
1773  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1775 }
1776 
1777 void
1779  uint32_t dstSeqNo, Ipv4Address origin)
1780 {
1781  NS_LOG_FUNCTION (this);
1782  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1783  if (m_rerrCount == RerrRateLimit)
1784  {
1785  // Just make sure that the RerrRateLimit timer is running and will expire
1787  // discard the packet and return
1788  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1790  << "; suppressing RERR");
1791  return;
1792  }
1793  RerrHeader rerrHeader;
1794  rerrHeader.AddUnDestination (dst, dstSeqNo);
1795  RoutingTableEntry toOrigin;
1796  Ptr<Packet> packet = Create<Packet> ();
1797  packet->AddHeader (rerrHeader);
1798  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1799  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1800  {
1802  toOrigin.GetInterface ());
1803  NS_ASSERT (socket);
1804  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1805  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1806  }
1807  else
1808  {
1809  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1810  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1811  {
1812  Ptr<Socket> socket = i->first;
1813  Ipv4InterfaceAddress iface = i->second;
1814  NS_ASSERT (socket);
1815  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1816  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1817  Ipv4Address destination;
1818  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1819  {
1820  destination = Ipv4Address ("255.255.255.255");
1821  }
1822  else
1823  {
1824  destination = iface.GetBroadcast ();
1825  }
1826  socket->SendTo (packet->Copy (), 0, InetSocketAddress (destination, AODV_PORT));
1827  }
1828  }
1829 }
1830 
1831 void
1832 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1833 {
1834  NS_LOG_FUNCTION (this);
1835 
1836  if (precursors.empty ())
1837  {
1838  NS_LOG_LOGIC ("No precursors");
1839  return;
1840  }
1841  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1842  if (m_rerrCount == RerrRateLimit)
1843  {
1844  // Just make sure that the RerrRateLimit timer is running and will expire
1846  // discard the packet and return
1847  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1849  << "; suppressing RERR");
1850  return;
1851  }
1852  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1853  if (precursors.size () == 1)
1854  {
1855  RoutingTableEntry toPrecursor;
1856  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1857  {
1858  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1859  NS_ASSERT (socket);
1860  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1861  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
1862  m_rerrCount++;
1863  }
1864  return;
1865  }
1866 
1867  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1868  std::vector<Ipv4InterfaceAddress> ifaces;
1869  RoutingTableEntry toPrecursor;
1870  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1871  {
1872  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1873  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1874  {
1875  ifaces.push_back (toPrecursor.GetInterface ());
1876  }
1877  }
1878 
1879  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1880  {
1882  NS_ASSERT (socket);
1883  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1884  // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
1885  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1886  Ptr<Packet> p = packet->Copy ();
1887  Ipv4Address destination;
1888  if (i->GetMask () == Ipv4Mask::GetOnes ())
1889  {
1890  destination = Ipv4Address ("255.255.255.255");
1891  }
1892  else
1893  {
1894  destination = i->GetBroadcast ();
1895  }
1896  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, p, destination);
1897  }
1898 }
1899 
1902 {
1903  NS_LOG_FUNCTION (this << addr);
1904  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1905  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1906  {
1907  Ptr<Socket> socket = j->first;
1908  Ipv4InterfaceAddress iface = j->second;
1909  if (iface == addr)
1910  return socket;
1911  }
1912  Ptr<Socket> socket;
1913  return socket;
1914 }
1915 
1918 {
1919  NS_LOG_FUNCTION (this << addr);
1920  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1922  {
1923  Ptr<Socket> socket = j->first;
1924  Ipv4InterfaceAddress iface = j->second;
1925  if (iface == addr)
1926  return socket;
1927  }
1928  Ptr<Socket> socket;
1929  return socket;
1930 }
1931 
1932 void
1934 {
1935  NS_LOG_FUNCTION (this);
1936  uint32_t startTime;
1937  if (EnableHello)
1938  {
1940  startTime = m_uniformRandomVariable->GetInteger (0, 100);
1941  NS_LOG_DEBUG ("Starting at time " << startTime << "ms");
1942  m_htimer.Schedule (MilliSeconds (startTime));
1943  }
1945 }
1946 
1947 } //namespace aodv
1948 } //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
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:346
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:1164
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.
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:234
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:824
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:368
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:1258
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:903
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...
second
Definition: nstime.h:114
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
bool IsMulticast(void) const
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(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:719
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
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
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:341
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:846
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.
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
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:220
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)
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1216
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
#define max(a, b)
Definition: 80211b.c:45
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:957
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:309
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:1480
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
tuple mac
Definition: third.py:92
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:324
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:1379
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:958
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)
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
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:831
A network Node.
Definition: node.h:56
#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:895
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:911
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
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.
tuple wifi
Definition: third.py:89
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:191
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:58
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)
Set the parent TypeId.
Definition: type-id.cc:826
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
virtual Address GetAddress(void) const =0
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
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.