A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
aodv-routing-protocol.cc
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 
114 NS_OBJECT_ENSURE_REGISTERED (DeferredRouteOutputTag);
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  TimeoutBuffer (2),
133  BlackListTimeout (Time (RreqRetries * NetTraversalTime)),
134  MaxQueueLen (64),
135  MaxQueueTime (Seconds (30)),
136  DestinationOnly (false),
137  GratuitousReply (true),
138  EnableHello (true),
139  m_routingTable (DeletePeriod),
140  m_queue (MaxQueueLen, MaxQueueTime),
141  m_requestId (0),
142  m_seqNo (0),
143  m_rreqIdCache (PathDiscoveryTime),
144  m_dpd (PathDiscoveryTime),
145  m_nb (HelloInterval),
146  m_rreqCount (0),
147  m_rerrCount (0),
148  m_htimer (Timer::CANCEL_ON_DESTROY),
149  m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
150  m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY)
151 {
152  if (EnableHello)
153  {
155  }
156 }
157 
158 TypeId
159 RoutingProtocol::GetTypeId (void)
160 {
161  static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
163  .AddConstructor<RoutingProtocol> ()
164  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
165  TimeValue (Seconds (1)),
166  MakeTimeAccessor (&RoutingProtocol::HelloInterval),
167  MakeTimeChecker ())
168  .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
169  UintegerValue (2),
170  MakeUintegerAccessor (&RoutingProtocol::RreqRetries),
171  MakeUintegerChecker<uint32_t> ())
172  .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
173  UintegerValue (10),
174  MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
175  MakeUintegerChecker<uint32_t> ())
176  .AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
177  UintegerValue (10),
178  MakeUintegerAccessor (&RoutingProtocol::RerrRateLimit),
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)),
183  MakeTimeAccessor (&RoutingProtocol::NodeTraversalTime),
184  MakeTimeChecker ())
185  .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
186  TimeValue (MilliSeconds (50)),
187  MakeTimeAccessor (&RoutingProtocol::NextHopWait),
188  MakeTimeChecker ())
189  .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
190  TimeValue (Seconds (3)),
191  MakeTimeAccessor (&RoutingProtocol::ActiveRouteTimeout),
192  MakeTimeChecker ())
193  .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
194  TimeValue (Seconds (11.2)),
195  MakeTimeAccessor (&RoutingProtocol::MyRouteTimeout),
196  MakeTimeChecker ())
197  .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
198  TimeValue (Seconds (5.6)),
199  MakeTimeAccessor (&RoutingProtocol::BlackListTimeout),
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)),
205  MakeTimeAccessor (&RoutingProtocol::DeletePeriod),
206  MakeTimeChecker ())
207  .AddAttribute ("TimeoutBuffer", "Its purpose is to provide a buffer for the timeout so that if the RREP is delayed"
208  " due to congestion, a timeout is less likely to occur while the RREP is still en route back to the source.",
209  UintegerValue (2),
210  MakeUintegerAccessor (&RoutingProtocol::TimeoutBuffer),
211  MakeUintegerChecker<uint16_t> ())
212  .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
213  UintegerValue (35),
214  MakeUintegerAccessor (&RoutingProtocol::NetDiameter),
215  MakeUintegerChecker<uint32_t> ())
216  .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
217  TimeValue (Seconds (2.8)),
218  MakeTimeAccessor (&RoutingProtocol::NetTraversalTime),
219  MakeTimeChecker ())
220  .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
221  TimeValue (Seconds (5.6)),
222  MakeTimeAccessor (&RoutingProtocol::PathDiscoveryTime),
223  MakeTimeChecker ())
224  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
225  UintegerValue (64),
226  MakeUintegerAccessor (&RoutingProtocol::SetMaxQueueLen,
227  &RoutingProtocol::GetMaxQueueLen),
228  MakeUintegerChecker<uint32_t> ())
229  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
230  TimeValue (Seconds (30)),
231  MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
232  &RoutingProtocol::GetMaxQueueTime),
233  MakeTimeChecker ())
234  .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
235  UintegerValue (2),
236  MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss),
237  MakeUintegerChecker<uint16_t> ())
238  .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
239  BooleanValue (true),
240  MakeBooleanAccessor (&RoutingProtocol::SetGratuitousReplyFlag,
241  &RoutingProtocol::GetGratuitousReplyFlag),
242  MakeBooleanChecker ())
243  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
244  BooleanValue (false),
245  MakeBooleanAccessor (&RoutingProtocol::SetDesinationOnlyFlag,
246  &RoutingProtocol::GetDesinationOnlyFlag),
247  MakeBooleanChecker ())
248  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
249  BooleanValue (true),
250  MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
251  &RoutingProtocol::GetHelloEnable),
252  MakeBooleanChecker ())
253  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
254  BooleanValue (true),
255  MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
256  &RoutingProtocol::GetBroadcastEnable),
257  MakeBooleanChecker ())
258  .AddAttribute ("UniformRv",
259  "Access to the underlying UniformRandomVariable",
260  StringValue ("ns3::UniformRandomVariable"),
261  MakePointerAccessor (&RoutingProtocol::m_uniformRandomVariable),
262  MakePointerChecker<UniformRandomVariable> ())
263  ;
264  return tid;
265 }
266 
267 void
268 RoutingProtocol::SetMaxQueueLen (uint32_t len)
269 {
270  MaxQueueLen = len;
271  m_queue.SetMaxQueueLen (len);
272 }
273 void
274 RoutingProtocol::SetMaxQueueTime (Time t)
275 {
276  MaxQueueTime = t;
277  m_queue.SetQueueTimeout (t);
278 }
279 
280 RoutingProtocol::~RoutingProtocol ()
281 {
282 }
283 
284 void
286 {
287  m_ipv4 = 0;
288  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
289  m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
290  {
291  iter->first->Close ();
292  }
293  m_socketAddresses.clear ();
295 }
296 
297 void
299 {
300  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId () << " Time: " << Simulator::Now ().GetSeconds () << "s ";
301  m_routingTable.Print (stream);
302 }
303 
304 int64_t
306 {
307  NS_LOG_FUNCTION (this << stream);
309  return 1;
310 }
311 
312 void
314 {
315  NS_LOG_FUNCTION (this);
316  if (EnableHello)
317  {
318  m_nb.ScheduleTimer ();
319  }
321  this);
323 
325  this);
327 
328 }
329 
332  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
333 {
334  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
335  if (!p)
336  {
337  return LoopbackRoute (header, oif); // later
338  }
339  if (m_socketAddresses.empty ())
340  {
341  sockerr = Socket::ERROR_NOROUTETOHOST;
342  NS_LOG_LOGIC ("No aodv interfaces");
343  Ptr<Ipv4Route> route;
344  return route;
345  }
346  sockerr = Socket::ERROR_NOTERROR;
347  Ptr<Ipv4Route> route;
348  Ipv4Address dst = header.GetDestination ();
350  if (m_routingTable.LookupValidRoute (dst, rt))
351  {
352  route = rt.GetRoute ();
353  NS_ASSERT (route != 0);
354  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
355  if (oif != 0 && route->GetOutputDevice () != oif)
356  {
357  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
358  sockerr = Socket::ERROR_NOROUTETOHOST;
359  return Ptr<Ipv4Route> ();
360  }
363  uint16_t channel = 1;
364  PacketTypePacketTag ptpt;
365  bool found = p->PeekPacketTag(ptpt);
366  if (!found)
367  channel = rt.GetChannel();
369 
370  p->AddPacketTag(cbt);
371  return route;
372  }
373 
374  // Valid route not found, in this case we return loopback.
375  // Actual route request will be deferred until packet will be fully formed,
376  // routed to loopback, received from loopback and passed to RouteInput (see below)
377  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
378  DeferredRouteOutputTag tag (iif);
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  {
508  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
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  //before sending out to dst, make sure you change the packet's tag
566  Ptr<Packet> packet = p->Copy();
568  packet->RemovePacketTag(pcpt);
569  pcpt = ns3::PacketChannelPacketTag(toDst.GetChannel());
570  packet->AddPacketTag(pcpt);
571 
572  ucb (route, packet, header);
573  return true;
574  }
575  else
576  {
577  if (toDst.GetValidSeqNo ())
578  {
579  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
580  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
581  return false;
582  }
583  }
584  }
585  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
586  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
587  SendRerrWhenNoRouteToForward (dst, 0, origin);
588  return false;
589 }
590 
591 void
593 {
594  NS_ASSERT (ipv4 != 0);
595  NS_ASSERT (m_ipv4 == 0);
596 
597  if (EnableHello)
598  {
601  }
602 
603  m_ipv4 = ipv4;
604 
605  // Create lo route. It is asserted that the only one interface up for now is loopback
606  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
607  m_lo = m_ipv4->GetNetDevice (0);
608  NS_ASSERT (m_lo != 0);
609  // Remember lo route
610  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
611  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
612  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
613  /*lifetime=*/ Simulator::GetMaximumSimulationTime (),
614  /*channel=*/1);
616 
618 }
619 
620 void
622 {
623  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
624  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
625  if (l3->GetNAddresses (i) > 1)
626  {
627  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
628  }
629  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
630  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
631  return;
632 
633  // Create a socket to listen only on this interface
634  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
635  UdpSocketFactory::GetTypeId ());
636  NS_ASSERT (socket != 0);
638  socket->BindToNetDevice (l3->GetNetDevice (i));
640  socket->SetAllowBroadcast (true);
641  socket->SetAttribute ("IpTtl", UintegerValue (1));
642  m_socketAddresses.insert (std::make_pair (socket, iface));
643 
644  // Add local broadcast record to the routing table
645  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
646  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
647  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime (),
648  /*channel=*/1);
650 
651  // Allow neighbor manager use this interface for layer 2 feedback if possible
652  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
653  if (wifi == 0)
654  return;
655  Ptr<WifiMac> mac = wifi->GetMac ();
656  if (mac == 0)
657  return;
658 
659  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
660  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
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  if (m_socketAddresses.empty ())
689  {
690  NS_LOG_LOGIC ("No aodv interfaces");
691  m_htimer.Cancel ();
692  m_nb.Clear ();
694  return;
695  }
697 }
698 
699 void
701 {
702  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
703  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
704  if (!l3->IsUp (i))
705  return;
706  if (l3->GetNAddresses (i) == 1)
707  {
708  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
710  if (!socket)
711  {
712  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
713  return;
714  // Create a socket to listen only on this interface
715  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
716  UdpSocketFactory::GetTypeId ());
717  NS_ASSERT (socket != 0);
719  socket->BindToNetDevice (l3->GetNetDevice (i));
720  // Bind to any IP address so that broadcasts can be received
722  socket->SetAllowBroadcast (true);
723  m_socketAddresses.insert (std::make_pair (socket, iface));
724 
725  // Add local broadcast record to the routing table
726  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
727  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
728  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
729  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
730  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime (),
731  /*channel=*/1);
733  }
734  }
735  else
736  {
737  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
738  }
739 }
740 
741 void
743 {
744  NS_LOG_FUNCTION (this);
745  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
746  if (socket)
747  {
749  m_socketAddresses.erase (socket);
750  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
751  if (l3->GetNAddresses (i))
752  {
753  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
754  // Create a socket to listen only on this interface
755  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
756  UdpSocketFactory::GetTypeId ());
757  NS_ASSERT (socket != 0);
759  // Bind to any IP address so that broadcasts can be received
761  socket->SetAllowBroadcast (true);
762  m_socketAddresses.insert (std::make_pair (socket, iface));
763 
764  // Add local broadcast record to the routing table
765  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
766  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
767  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime (),
768  /*channel=*/1);
770  }
771  if (m_socketAddresses.empty ())
772  {
773  NS_LOG_LOGIC ("No aodv interfaces");
774  m_htimer.Cancel ();
775  m_nb.Clear ();
777  return;
778  }
779  }
780  else
781  {
782  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
783  }
784 }
785 
786 bool
788 {
789  NS_LOG_FUNCTION (this << src);
790  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
791  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
792  {
793  Ipv4InterfaceAddress iface = j->second;
794  if (src == iface.GetLocal ())
795  {
796  return true;
797  }
798  }
799  return false;
800 }
801 
804 {
805  NS_LOG_FUNCTION (this << hdr);
806  NS_ASSERT (m_lo != 0);
807  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
808  rt->SetDestination (hdr.GetDestination ());
809  //
810  // Source address selection here is tricky. The loopback route is
811  // returned when AODV does not have a route; this causes the packet
812  // to be looped back and handled (cached) in RouteInput() method
813  // while a route is found. However, connection-oriented protocols
814  // like TCP need to create an endpoint four-tuple (src, src port,
815  // dst, dst port) and create a pseudo-header for checksumming. So,
816  // AODV needs to guess correctly what the eventual source address
817  // will be.
818  //
819  // For single interface, single address nodes, this is not a problem.
820  // When there are possibly multiple outgoing interfaces, the policy
821  // implemented here is to pick the first available AODV interface.
822  // If RouteOutput() caller specified an outgoing interface, that
823  // further constrains the selection of source address
824  //
825  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
826  if (oif)
827  {
828  // Iterate to find an address on the oif device
829  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
830  {
831  Ipv4Address addr = j->second.GetLocal ();
832  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
833  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
834  {
835  rt->SetSource (addr);
836  break;
837  }
838  }
839  }
840  else
841  {
842  rt->SetSource (j->second.GetLocal ());
843  }
844  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
845  rt->SetGateway (Ipv4Address ("127.0.0.1"));
846  rt->SetOutputDevice (m_lo);
847  return rt;
848 }
849 
850 void
852 {
853  NS_LOG_FUNCTION ( this << dst);
854  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
855  if (m_rreqCount == RreqRateLimit)
856  {
858  &RoutingProtocol::SendRequest, this, dst);
859  return;
860  }
861  else
862  m_rreqCount++;
863  // Create RREQ header
864  RreqHeader rreqHeader;
865  rreqHeader.SetDst (dst);
866 
868  if (m_routingTable.LookupRoute (dst, rt))
869  {
870  rreqHeader.SetHopCount (rt.GetHop ());
871  if (rt.GetValidSeqNo ())
872  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
873  else
874  rreqHeader.SetUnknownSeqno (true);
875  rt.SetFlag (IN_SEARCH);
876  m_routingTable.Update (rt);
877  }
878  else
879  {
880  rreqHeader.SetUnknownSeqno (true);
881  Ptr<NetDevice> dev = 0;
882  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
883  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
884  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0),
885  /*channel=*/1);
886  newEntry.SetFlag (IN_SEARCH);
887  m_routingTable.AddRoute (newEntry);
888  }
889 
890  if (GratuitousReply)
891  rreqHeader.SetGratiousRrep (true);
892  if (DestinationOnly)
893  rreqHeader.SetDestinationOnly (true);
894 
895  m_seqNo++;
896  rreqHeader.SetOriginSeqno (m_seqNo);
897  m_requestId++;
898  rreqHeader.SetId (m_requestId);
899  rreqHeader.SetHopCount (0);
900 
901  // Send RREQ as subnet directed broadcast from each interface used by aodv
902  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
903  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
904  {
905  Ptr<Socket> socket = j->first;
906  Ipv4InterfaceAddress iface = j->second;
907 
908  rreqHeader.SetOrigin (iface.GetLocal ());
909  rreqHeader.SetRXChannel (m_crRepository->GetRxChannel(m_ipv4->GetObject <Node>()->GetId()));
910  NS_LOG_LOGIC ("sending request with channel = " << m_crRepository->GetRxChannel(m_ipv4->GetObject<Node>()->GetId()));
911  m_rreqIdCache.IsDuplicate (iface.GetLocal (), m_requestId);
912 
913  Ptr<Packet> packet = Create<Packet> ();
915  packet->AddPacketTag(bt);
916  packet->AddHeader (rreqHeader);
917  TypeHeader tHeader (AODVTYPE_RREQ);
918  packet->AddHeader (tHeader);
919  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
920  Ipv4Address destination;
921  if (iface.GetMask () == Ipv4Mask::GetOnes ())
922  {
923  destination = Ipv4Address ("255.255.255.255");
924  }
925  else
926  {
927  destination = iface.GetBroadcast ();
928  }
929  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
930  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
931  }
932  ScheduleRreqRetry (dst);
933  if (EnableHello)
934  {
935  if (!m_htimer.IsRunning ())
936  {
937  m_htimer.Cancel ();
939  }
940  }
941 }
942 
943 void
945 {
946  NS_LOG_FUNCTION (this << dst);
947  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
948  {
950  m_addressReqTimer[dst] = timer;
951  }
953  m_addressReqTimer[dst].Remove ();
954  m_addressReqTimer[dst].SetArguments (dst);
956  m_routingTable.LookupRoute (dst, rt);
957  rt.IncrementRreqCnt ();
958  m_routingTable.Update (rt);
959  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
960  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
961 }
962 
963 void
965 {
966  NS_LOG_FUNCTION (this << socket);
967  Address sourceAddress;
968  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
969  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
970  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
971  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
972  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
973 
974  UpdateRouteToNeighbor (sender, receiver);
975  TypeHeader tHeader (AODVTYPE_RREQ);
976  packet->RemoveHeader (tHeader);
977  if (!tHeader.IsValid ())
978  {
979  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
980  return; // drop
981  }
982  switch (tHeader.Get ())
983  {
984  case AODVTYPE_RREQ:
985  {
986  RecvRequest (packet, receiver, sender);
987  break;
988  }
989  case AODVTYPE_RREP:
990  {
991  RecvReply (packet, receiver, sender);
992  break;
993  }
994  case AODVTYPE_RERR:
995  {
996  RecvError (packet, sender);
997  break;
998  }
999  case AODVTYPE_RREP_ACK:
1000  {
1001  RecvReplyAck (sender);
1002  break;
1003  }
1004  }
1005 }
1006 
1007 bool
1009 {
1010  NS_LOG_FUNCTION (this << addr << lifetime);
1011  RoutingTableEntry rt;
1012  if (m_routingTable.LookupRoute (addr, rt))
1013  {
1014  if (rt.GetFlag () == VALID)
1015  {
1016  NS_LOG_DEBUG ("Updating VALID route");
1017  rt.SetRreqCnt (0);
1018  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
1019  m_routingTable.Update (rt);
1020  return true;
1021  }
1022  }
1023  return false;
1024 }
1025 
1026 void
1028 {
1029  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1030  RoutingTableEntry toNeighbor;
1031  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1032  {
1033  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1034  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1035  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1036  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout,
1037  /*channel=*/ 1);
1038  m_routingTable.AddRoute (newEntry);
1039  }
1040  else
1041  {
1042  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1043  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1044  {
1045  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1046  }
1047  else
1048  {
1049  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1050  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1051  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()),
1052  /*channel=*/toNeighbor.GetChannel());
1053  m_routingTable.Update (newEntry);
1054  }
1055  }
1056 
1057 }
1058 
1059 void
1061 {
1062  NS_LOG_FUNCTION (this);
1063  RreqHeader rreqHeader;
1064  p->RemoveHeader (rreqHeader);
1065 
1066  // A node ignores all RREQs received from any node in its blacklist
1067  RoutingTableEntry toPrev;
1068  if (m_routingTable.LookupRoute (src, toPrev))
1069  {
1070  if (toPrev.IsUnidirectional ())
1071  {
1072  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1073  return;
1074  }
1075  }
1076 
1077  uint32_t id = rreqHeader.GetId ();
1078  Ipv4Address origin = rreqHeader.GetOrigin ();
1079 
1080  /*
1081  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1082  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1083  */
1084  if (m_rreqIdCache.IsDuplicate (origin, id))
1085  {
1086  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1087  return;
1088  }
1089 
1090  // Increment RREQ hop count
1091  uint8_t hop = rreqHeader.GetHopCount () + 1;
1092  rreqHeader.SetHopCount (hop);
1093 
1094  /*
1095  * When the reverse route is created or updated, the following actions on the route are also carried out:
1096  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1097  * in the route table entry and copied if greater than the existing value there
1098  * 2. the valid sequence number field is set to true;
1099  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1100  * 4. the hop count is copied from the Hop Count in the RREQ message;
1101  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1102  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1103  */
1104  RoutingTableEntry toOrigin;
1105  if (!m_routingTable.LookupRoute (origin, toOrigin))
1106  {
1107  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1108  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1109  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1110  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)),
1111  /*channel=*/rreqHeader.GetRXChannel());
1112  m_routingTable.AddRoute (newEntry);
1113  }
1114  else
1115  {
1116  if (toOrigin.GetValidSeqNo ())
1117  {
1118  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1119  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1120  }
1121  else
1122  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1123  toOrigin.SetValidSeqNo (true);
1124  toOrigin.SetNextHop (src);
1125  toOrigin.SetChannel (rreqHeader.GetRXChannel());
1126  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1127  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1128  toOrigin.SetHop (hop);
1129  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1130  toOrigin.GetLifeTime ()));
1131  m_routingTable.Update (toOrigin);
1132  }
1133  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1134  << " ID " << rreqHeader.GetId ()
1135  << " to destination " << rreqHeader.GetDst ()
1136  << " Originator RX channel = " << rreqHeader.GetRXChannel ());
1137 
1138  // A node generates a RREP if either:
1139  // (i) it is itself the destination,
1140  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1141  {
1142  m_routingTable.LookupRoute (origin, toOrigin);
1143  NS_LOG_DEBUG ("Send reply since I am the destination");
1144  SendReply (rreqHeader, toOrigin);
1145  return;
1146  }
1147  /*
1148  * (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
1149  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1150  */
1151  RoutingTableEntry toDst;
1152  Ipv4Address dst = rreqHeader.GetDst ();
1153  if (m_routingTable.LookupRoute (dst, toDst))
1154  {
1155  /*
1156  * Drop RREQ, This node RREP wil make a loop.
1157  */
1158  if (toDst.GetNextHop () == src)
1159  {
1160  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1161  return;
1162  }
1163  /*
1164  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1165  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1166  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1167  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1168  */
1169  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1170  && toDst.GetValidSeqNo () )
1171  {
1172  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1173  {
1174  m_routingTable.LookupRoute (origin, toOrigin);
1175  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1176  return;
1177  }
1178  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1179  rreqHeader.SetUnknownSeqno (false);
1180  }
1181  }
1182 
1183  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1184  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1185  {
1186  Ptr<Socket> socket = j->first;
1187  Ipv4InterfaceAddress iface = j->second;
1188  Ptr<Packet> packet = Create<Packet> ();
1190  packet->AddPacketTag(bt);
1191  rreqHeader.SetRXChannel(m_crRepository->GetRxChannel(m_ipv4->GetObject<Node> ()->GetId()));
1192  packet->AddHeader (rreqHeader);
1193  TypeHeader tHeader (AODVTYPE_RREQ);
1194  packet->AddHeader (tHeader);
1195  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1196  Ipv4Address destination;
1197  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1198  {
1199  destination = Ipv4Address ("255.255.255.255");
1200  }
1201  else
1202  {
1203  destination = iface.GetBroadcast ();
1204  }
1205  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1206  }
1207 
1208  if (EnableHello)
1209  {
1210  if (!m_htimer.IsRunning ())
1211  {
1212  m_htimer.Cancel ();
1214  }
1215  }
1216 }
1217 
1218 void
1219 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1220 {
1221  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1222  /*
1223  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1224  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1225  */
1226  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1227  m_seqNo++;
1228  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1229  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout,
1230  m_crRepository->GetRxChannel(m_ipv4->GetObject<Node> ()->GetId()));
1231  Ptr<Packet> packet = Create<Packet> ();
1233  packet->AddPacketTag(bt);
1234  packet->AddHeader (rrepHeader);
1235  TypeHeader tHeader (AODVTYPE_RREP);
1236  packet->AddHeader (tHeader);
1237  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
1238  NS_ASSERT (socket);
1239  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1240 }
1241 
1242 void
1244 {
1245  NS_LOG_FUNCTION (this);
1246  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1247  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime (),
1248  m_crRepository->GetRxChannel(m_ipv4->GetObject<Node> ()->GetId()));
1249  /* If the node we received a RREQ for is a neighbor we are
1250  * probably facing a unidirectional link... Better request a RREP-ack
1251  */
1252  if (toDst.GetHop () == 1)
1253  {
1254  rrepHeader.SetAckRequired (true);
1255  RoutingTableEntry toNextHop;
1256  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1258  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1259  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1260  }
1261  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1262  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1263  m_routingTable.Update (toDst);
1264  m_routingTable.Update (toOrigin);
1265 
1266  Ptr<Packet> packet = Create<Packet> ();
1268  packet->AddPacketTag(bt);
1269  packet->AddHeader (rrepHeader);
1270  TypeHeader tHeader (AODVTYPE_RREP);
1271  packet->AddHeader (tHeader);
1272  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
1273  NS_ASSERT (socket);
1274  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1275 
1276  // Generating gratuitous RREPs
1277  if (gratRep)
1278  {
1279  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1280  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1281  /*lifetime=*/ toOrigin.GetLifeTime (),
1282  m_crRepository->GetRxChannel(m_ipv4->GetObject<Node>()->GetId()));
1283  Ptr<Packet> packetToDst = Create<Packet> ();
1285  packetToDst->AddPacketTag(bt);
1286  packetToDst->AddHeader (gratRepHeader);
1287  TypeHeader type (AODVTYPE_RREP);
1288  packetToDst->AddHeader (type);
1289  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toDst.GetInterface ());
1290  NS_ASSERT (socket);
1291  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1292  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1293  }
1294 }
1295 
1296 void
1298 {
1299  NS_LOG_FUNCTION (this << " to " << neighbor);
1300  RrepAckHeader h;
1301  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1302  Ptr<Packet> packet = Create<Packet> ();
1304  packet->AddPacketTag(bt);
1305  packet->AddHeader (h);
1306  packet->AddHeader (typeHeader);
1307  RoutingTableEntry toNeighbor;
1308  m_routingTable.LookupRoute (neighbor, toNeighbor);
1309  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1310  NS_ASSERT (socket);
1311  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1312 }
1313 
1314 void
1316 {
1317  NS_LOG_FUNCTION (this << " src " << sender);
1318  RrepHeader rrepHeader;
1319  p->RemoveHeader (rrepHeader);
1320  Ipv4Address dst = rrepHeader.GetDst ();
1321  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ()
1322  << " channel number: " << rrepHeader.GetRXChannel());
1323 
1324  uint8_t hop = rrepHeader.GetHopCount () + 1;
1325  rrepHeader.SetHopCount (hop);
1326 
1327  // If RREP is Hello message
1328  if (dst == rrepHeader.GetOrigin ())
1329  {
1330  ProcessHello (rrepHeader, receiver);
1331  return;
1332  }
1333 
1334  /*
1335  * If the route table entry to the destination is created or updated, then the following actions occur:
1336  * - the route is marked as active,
1337  * - the destination sequence number is marked as valid,
1338  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1339  * which is indicated by the source IP address field in the IP header,
1340  * - the hop count is set to the value of the hop count from RREP message + 1
1341  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1342  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1343  */
1344  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1345  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1346  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1347  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime (), rrepHeader.GetRXChannel());
1348  RoutingTableEntry toDst;
1349  if (m_routingTable.LookupRoute (dst, toDst))
1350  {
1351  /*
1352  * The existing entry is updated only in the following circumstances:
1353  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1354  */
1355  if (!toDst.GetValidSeqNo ())
1356  {
1357  m_routingTable.Update (newEntry);
1358  }
1359  // (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,
1360  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1361  {
1362  m_routingTable.Update (newEntry);
1363  }
1364  else
1365  {
1366  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1367  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1368  {
1369  m_routingTable.Update (newEntry);
1370  }
1371  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1372  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1373  {
1374  m_routingTable.Update (newEntry);
1375  }
1376  }
1377  }
1378  else
1379  {
1380  // The forward route for this destination is created if it does not already exist.
1381  NS_LOG_LOGIC ("add new route");
1382  m_routingTable.AddRoute (newEntry);
1383  }
1384  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1385  if (rrepHeader.GetAckRequired ())
1386  {
1387  SendReplyAck (sender);
1388  rrepHeader.SetAckRequired (false);
1389  }
1390  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1391  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1392  {
1393  if (toDst.GetFlag () == IN_SEARCH)
1394  {
1395  m_routingTable.Update (newEntry);
1396  m_addressReqTimer[dst].Remove ();
1397  m_addressReqTimer.erase (dst);
1398  }
1399  m_routingTable.LookupRoute (dst, toDst);
1400  SendPacketFromQueue (dst, toDst.GetRoute (), toDst.GetChannel());
1401  return;
1402  }
1403 
1404  RoutingTableEntry toOrigin;
1405  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1406  {
1407  return; // Impossible! drop.
1408  }
1409  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1410  m_routingTable.Update (toOrigin);
1411 
1412  // Update information about precursors
1413  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1414  {
1415  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1416  m_routingTable.Update (toDst);
1417 
1418  RoutingTableEntry toNextHopToDst;
1419  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1420  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1421  m_routingTable.Update (toNextHopToDst);
1422 
1423  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1424  m_routingTable.Update (toOrigin);
1425 
1426  RoutingTableEntry toNextHopToOrigin;
1427  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1428  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1429  m_routingTable.Update (toNextHopToOrigin);
1430  }
1431 
1432  Ptr<Packet> packet = Create<Packet> ();
1434  packet->AddPacketTag(bt);
1435  rrepHeader.SetRXChannel(m_crRepository->GetRxChannel(m_ipv4->GetObject <Node>()->GetId()));
1436  packet->AddHeader (rrepHeader);
1437  TypeHeader tHeader (AODVTYPE_RREP);
1438  packet->AddHeader (tHeader);
1439  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toOrigin.GetInterface ());
1440  NS_ASSERT (socket);
1441  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1442 }
1443 
1444 void
1446 {
1447  NS_LOG_FUNCTION (this);
1448  RoutingTableEntry rt;
1449  if(m_routingTable.LookupRoute (neighbor, rt))
1450  {
1451  rt.m_ackTimer.Cancel ();
1452  rt.SetFlag (VALID);
1453  m_routingTable.Update (rt);
1454  }
1455 }
1456 
1457 void
1459 {
1460  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1461  /*
1462  * Whenever a node receives a Hello message from a neighbor, the node
1463  * SHOULD make sure that it has an active route to the neighbor, and
1464  * create one if necessary.
1465  */
1466  RoutingTableEntry toNeighbor;
1467  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1468  {
1469  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1470  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1471  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1472  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime (),
1473  /*channel=*/rrepHeader.GetRXChannel());
1474  m_routingTable.AddRoute (newEntry);
1475  }
1476  else
1477  {
1478  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1479  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1480  toNeighbor.SetValidSeqNo (true);
1481  toNeighbor.SetChannel (rrepHeader.GetRXChannel());
1482  toNeighbor.SetFlag (VALID);
1483  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1484  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1485  m_routingTable.Update (toNeighbor);
1486  }
1487  if (EnableHello)
1488  {
1489  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1490  }
1491 }
1492 
1493 void
1495 {
1496  NS_LOG_FUNCTION (this << " from " << src);
1497  RerrHeader rerrHeader;
1498  p->RemoveHeader (rerrHeader);
1499  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1500  std::map<Ipv4Address, uint32_t> unreachable;
1501  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1502  std::pair<Ipv4Address, uint32_t> un;
1503  while (rerrHeader.RemoveUnDestination (un))
1504  {
1505  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1506  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1507  {
1508  if (i->first == un.first)
1509  {
1510  unreachable.insert (un);
1511  }
1512  }
1513  }
1514 
1515  std::vector<Ipv4Address> precursors;
1516  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1517  i != unreachable.end ();)
1518  {
1519  if (!rerrHeader.AddUnDestination (i->first, i->second))
1520  {
1521  TypeHeader typeHeader (AODVTYPE_RERR);
1522  Ptr<Packet> packet = Create<Packet> ();
1524  packet->AddPacketTag(bt);
1525  packet->AddHeader (rerrHeader);
1526  packet->AddHeader (typeHeader);
1527  SendRerrMessage (packet, precursors);
1528  rerrHeader.Clear ();
1529  }
1530  else
1531  {
1532  RoutingTableEntry toDst;
1533  m_routingTable.LookupRoute (i->first, toDst);
1534  toDst.GetPrecursors (precursors);
1535  ++i;
1536  }
1537  }
1538  if (rerrHeader.GetDestCount () != 0)
1539  {
1540  TypeHeader typeHeader (AODVTYPE_RERR);
1541  Ptr<Packet> packet = Create<Packet> ();
1543  packet->AddPacketTag(bt);
1544  packet->AddHeader (rerrHeader);
1545  packet->AddHeader (typeHeader);
1546  SendRerrMessage (packet, precursors);
1547  }
1549 }
1550 
1551 void
1553 {
1554  NS_LOG_LOGIC (this);
1555  RoutingTableEntry toDst;
1556  if (m_routingTable.LookupValidRoute (dst, toDst))
1557  {
1558  SendPacketFromQueue (dst, toDst.GetRoute (), toDst.GetChannel());
1559  NS_LOG_LOGIC ("route to " << dst << " found");
1560  return;
1561  }
1562  /*
1563  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1564  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1565  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1566  */
1567  if (toDst.GetRreqCnt () == RreqRetries)
1568  {
1569  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1570  m_addressReqTimer.erase (dst);
1572  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1573  m_queue.DropPacketWithDst (dst);
1574  return;
1575  }
1576 
1577  if (toDst.GetFlag () == IN_SEARCH)
1578  {
1579  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1580  SendRequest (dst);
1581  }
1582  else
1583  {
1584  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1585  m_addressReqTimer.erase (dst);
1587  m_queue.DropPacketWithDst (dst);
1588  }
1589 }
1590 
1591 void
1593 {
1594  NS_LOG_FUNCTION (this);
1595  SendHello ();
1596  m_htimer.Cancel ();
1597  Time t = Time (0.01 * MilliSeconds (m_uniformRandomVariable->GetInteger (0, 100)));
1599 }
1600 
1601 void
1603 {
1604  NS_LOG_FUNCTION (this);
1605  m_rreqCount = 0;
1607 }
1608 
1609 void
1611 {
1612  NS_LOG_FUNCTION (this);
1613  m_rerrCount = 0;
1615 }
1616 
1617 void
1619 {
1620  NS_LOG_FUNCTION (this);
1621  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1622 }
1623 
1624 void
1626 {
1627  NS_LOG_FUNCTION (this);
1628  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1629  * Destination IP Address The node's IP address.
1630  * Destination Sequence Number The node's latest sequence number.
1631  * Hop Count 0
1632  * Lifetime AllowedHelloLoss * HelloInterval
1633  */
1634  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1635  {
1636  Ptr<Socket> socket = j->first;
1637  Ipv4InterfaceAddress iface = j->second;
1638  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1639  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval),
1640  m_crRepository->GetRxChannel(m_ipv4->GetObject <Node>()->GetId()));
1641  Ptr<Packet> packet = Create<Packet> ();
1642  packet->AddHeader (helloHeader);
1643  TypeHeader tHeader (AODVTYPE_RREP);
1644  packet->AddHeader (tHeader);
1646  packet->AddPacketTag(bt);
1647  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1648  Ipv4Address destination;
1649  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1650  {
1651  destination = Ipv4Address ("255.255.255.255");
1652  }
1653  else
1654  {
1655  destination = iface.GetBroadcast ();
1656  }
1657  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1658  }
1659 }
1660 
1661 void
1663 {
1664  NS_LOG_FUNCTION (this);
1665  QueueEntry queueEntry;
1666  while (m_queue.Dequeue (dst, queueEntry))
1667  {
1669  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1671  p->AddPacketTag(cpt);
1672  if (p->RemovePacketTag (tag) &&
1673  tag.GetInterface() != -1 &&
1674  tag.GetInterface() != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
1675  {
1676  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1677  return;
1678  }
1679  UnicastForwardCallback ucb = queueEntry.GetUnicastForwardCallback ();
1680  Ipv4Header header = queueEntry.GetIpv4Header ();
1681  header.SetSource (route->GetSource ());
1682  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1683  ucb (route, p, header);
1684  }
1685 }
1686 
1687 void
1689 {
1690  NS_LOG_FUNCTION (this << nextHop);
1691  RerrHeader rerrHeader;
1692  std::vector<Ipv4Address> precursors;
1693  std::map<Ipv4Address, uint32_t> unreachable;
1694 
1695  RoutingTableEntry toNextHop;
1696  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1697  return;
1698  toNextHop.GetPrecursors (precursors);
1699  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1700  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1701  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1702  != unreachable.end ();)
1703  {
1704  if (!rerrHeader.AddUnDestination (i->first, i->second))
1705  {
1706  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1707  TypeHeader typeHeader (AODVTYPE_RERR);
1708  Ptr<Packet> packet = Create<Packet> ();
1710  packet->AddPacketTag(bt);
1711  packet->AddHeader (rerrHeader);
1712  packet->AddHeader (typeHeader);
1713  SendRerrMessage (packet, precursors);
1714  rerrHeader.Clear ();
1715  }
1716  else
1717  {
1718  RoutingTableEntry toDst;
1719  m_routingTable.LookupRoute (i->first, toDst);
1720  toDst.GetPrecursors (precursors);
1721  ++i;
1722  }
1723  }
1724  if (rerrHeader.GetDestCount () != 0)
1725  {
1726  TypeHeader typeHeader (AODVTYPE_RERR);
1727  Ptr<Packet> packet = Create<Packet> ();
1729  packet->AddPacketTag(bt);
1730  packet->AddHeader (rerrHeader);
1731  packet->AddHeader (typeHeader);
1732  SendRerrMessage (packet, precursors);
1733  }
1734  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1736 }
1737 
1738 void
1740  uint32_t dstSeqNo, Ipv4Address origin)
1741 {
1742  NS_LOG_FUNCTION (this);
1743  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1744  if (m_rerrCount == RerrRateLimit)
1745  {
1746  // Just make sure that the RerrRateLimit timer is running and will expire
1748  // discard the packet and return
1749  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1751  << "; suppressing RERR");
1752  return;
1753  }
1754  RerrHeader rerrHeader;
1755  rerrHeader.AddUnDestination (dst, dstSeqNo);
1756  RoutingTableEntry toOrigin;
1757  Ptr<Packet> packet = Create<Packet> ();
1759  packet->AddPacketTag(bt);
1760  packet->AddHeader (rerrHeader);
1761  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1762  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1763  {
1765  toOrigin.GetInterface ());
1766  NS_ASSERT (socket);
1767  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1768  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1769  }
1770  else
1771  {
1772  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1773  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1774  {
1775  Ptr<Socket> socket = i->first;
1776  Ipv4InterfaceAddress iface = i->second;
1777  NS_ASSERT (socket);
1778  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1779  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1780  Ipv4Address destination;
1781  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1782  {
1783  destination = Ipv4Address ("255.255.255.255");
1784  }
1785  else
1786  {
1787  destination = iface.GetBroadcast ();
1788  }
1789  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1790  }
1791  }
1792 }
1793 
1794 void
1795 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1796 {
1797  NS_LOG_FUNCTION (this);
1798 
1799  if (precursors.empty ())
1800  {
1801  NS_LOG_LOGIC ("No precursors");
1802  return;
1803  }
1804  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1805  if (m_rerrCount == RerrRateLimit)
1806  {
1807  // Just make sure that the RerrRateLimit timer is running and will expire
1809  // discard the packet and return
1810  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1812  << "; suppressing RERR");
1813  return;
1814  }
1815  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1816  if (precursors.size () == 1)
1817  {
1818  RoutingTableEntry toPrecursor;
1819  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1820  {
1821  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1822  NS_ASSERT (socket);
1823  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1824  socket->SendTo (packet, 0, InetSocketAddress (precursors.front (), AODV_PORT));
1825  m_rerrCount++;
1826  }
1827  return;
1828  }
1829 
1830  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1831  std::vector<Ipv4InterfaceAddress> ifaces;
1832  RoutingTableEntry toPrecursor;
1833  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1834  {
1835  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1836  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1837  {
1838  ifaces.push_back (toPrecursor.GetInterface ());
1839  }
1840  }
1841 
1842  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1843  {
1845  NS_ASSERT (socket);
1846  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1847  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1848  Ipv4Address destination;
1849  if (i->GetMask () == Ipv4Mask::GetOnes ())
1850  {
1851  destination = Ipv4Address ("255.255.255.255");
1852  }
1853  else
1854  {
1855  destination = i->GetBroadcast ();
1856  }
1857  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1858  m_rerrCount++;
1859  }
1860 }
1861 
1864 {
1865  NS_LOG_FUNCTION (this << addr);
1866  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1867  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1868  {
1869  Ptr<Socket> socket = j->first;
1870  Ipv4InterfaceAddress iface = j->second;
1871  if (iface == addr)
1872  return socket;
1873  }
1874  Ptr<Socket> socket;
1875  return socket;
1876 }
1877 
1878 void
1880 {
1881  m_crRepository = repo;
1882 }
1883 
1884 }
1885 }
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:284
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
static Ipv4Mask GetOnes(void)
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Definition: aodv-rtable.cc:316
keep track of time unit.
Definition: nstime.h:149
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Definition: aodv-rtable.cc:422
an Inet address class
Ipv4Address GetIpv4(void) const
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
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
Callback template class.
Definition: callback.h:369
Time MaxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Definition: aodv-rtable.cc:201
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:241
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
hold variables of type string
Definition: string.h:19
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
Route Error (RERR) Message Format.
Definition: aodv-packet.h:295
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
Routing table entry.
Definition: aodv-rtable.h:59
Tag used by AODV implementation.
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:868
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:262
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
Ptr< Repository > m_crRepository
Pointer to cognitive radio repository.
uint64_t GetUid(void) const
Definition: packet.cc:412
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:136
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
bool Forwarding(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
If route exists and valid, forward packet.
#define NS_ASSERT(condition)
Definition: assert.h:64
void DelArpCache(Ptr< ArpCache >)
Don't use given ARP cache any more (interface is down)
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:271
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
int64_t AssignStreams(int64_t stream)
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
bool IsMulticast(void) const
virtual void DoDispose(void)
Definition: object.cc:335
Time NetTraversalTime
Estimate of the average net traversal time.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
Neighbors m_nb
Handle neighbors.
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Definition: aodv-rtable.cc:129
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:199
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
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
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)
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find socket with local interface address iface.
a polymophic address class
Definition: address.h:86
bool IsRunning(void) const
Definition: timer.cc:121
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:72
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
void RecvAodv(Ptr< Socket > socket)
Receive and process control packet.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
void Clear()
Clear header.
Definition: aodv-packet.cc:611
bool InsertPrecursor(Ipv4Address id)
Definition: aodv-rtable.cc:67
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Definition: nstime.h:262
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:440
bool DestinationOnly
Indicates only the destination may respond to this RREQ.
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:881
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 DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet and send route request.
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.
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:336
void HelloTimerExpire()
Schedule next send of hello message.
hold objects of type ns3::Time
Definition: nstime.h:700
void Schedule(void)
Definition: timer.cc:152
uint8_t GetDestCount() const
Return number of unreachable destinations in RERR message.
Definition: aodv-packet.h:329
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Definition: aodv-packet.cc:589
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:254
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Hold an unsigned integer type.
Definition: uinteger.h:46
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:170
bool IsBroadcast(void) const
uint16_t RreqRateLimit
Maximum number of RREQ per second.
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.This class holds together ns3::WifiChannel, ns3::WifiPhy, ns3::WifiMac, and, ns3::WifiRemoteStationManager.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
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)
Definition: socket.cc:70
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
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.
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)
Definition: log.h:334
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:183
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:299
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
AODV Queue Entry.
Definition: aodv-rqueue.h:43
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
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.
void SetArguments(T1 a1)
Definition: timer.h:269
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route, uint16_t channel)
Forward packet from route request queue.
Implement the Ipv4 layer.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
static InetSocketAddress ConvertFrom(const Address &address)
Time ActiveRouteTimeout
Period of time during which the route is considered to be valid.
bool RemoveUnDestination(std::pair< Ipv4Address, uint32_t > &un)
Definition: aodv-packet.cc:600
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw socket per each IP interface, map socket -> iface address (IP + mask)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
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)
Definition: simulator.cc:179
void SetOutputDevice(Ptr< NetDevice > outputDevice)
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)
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:253
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)
Definition: assert.h:86
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.
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.
read and write tag data
Definition: tag-buffer.h:51
virtual void NotifyInterfaceDown(uint32_t interface)
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
void SetRepository(Ptr< Repository > repo)
Set cognitive radio repository.
Time MyRouteTimeout
Value of lifetime field in RREP generating by this node.
uint32_t GetId(void) const
Definition: node.cc:105
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Definition: log.h:246
bool AddRoute(RoutingTableEntry &r)
Definition: aodv-rtable.cc:250
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
A network Node.
Definition: node.h:56
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Cancel(void)
Definition: timer.cc:103
uint32_t AllowedHelloLoss
Number of hello messages which may be loss for valid link.
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:258
void Print(std::ostream &os) const
void SendReply(RreqHeader const &rreqHeader, RoutingTableEntry const &toOrigin)
Send RREP.
Abstract base class for IPv4 routing protocols.
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.
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
bool GratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery...
#define NS_LOG_ERROR(msg)
Definition: log.h:237
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:264
uint16_t RerrRateLimit
Maximum number of REER per second.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
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.
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:223
Time GetDelayLeft(void) const
Definition: timer.cc:81
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
bool DeleteRoute(Ipv4Address dst)
Definition: aodv-rtable.cc:236
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:356
a unique identifier for an interface.
Definition: type-id.h:44
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
uint32_t m_requestId
Broadcast ID.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
MessageType Get() const
Return type.
Definition: aodv-packet.h:70
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.
static Time GetMaximumSimulationTime(void)
Definition: simulator.cc:292
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
Definition: nstime.h:615
std::ostream * GetStream(void)
void AddHeader(const Header &header)
Definition: packet.cc:270
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void ScheduleTimer()
Schedule m_ntimer.
static const uint32_t AODV_PORT
UDP Port for AODV control traffic.
bool EnableHello
Indicates whether a hello messages enable.