A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
aodv-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Based on
19  * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
20  * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
21  *
22  * AODV-UU implementation by Erik Nordström of Uppsala University
23  * http://core.it.uu.se/core/index.php/AODV-UU
24  *
25  * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
26  * Pavel Boyko <boyko@iitp.ru>
27  */
28 #define NS_LOG_APPEND_CONTEXT \
29  if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
30 
31 #include "aodv-routing-protocol.h"
32 #include "ns3/log.h"
33 #include "ns3/boolean.h"
34 #include "ns3/random-variable-stream.h"
35 #include "ns3/inet-socket-address.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/wifi-net-device.h"
39 #include "ns3/adhoc-wifi-mac.h"
40 #include "ns3/string.h"
41 #include "ns3/pointer.h"
42 #include <algorithm>
43 #include <limits>
44 
45 NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
46 
47 namespace ns3
48 {
49 namespace aodv
50 {
51 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
52 
54 const uint32_t RoutingProtocol::AODV_PORT = 654;
55 
56 //-----------------------------------------------------------------------------
58 
60 {
61 
62 public:
63  DeferredRouteOutputTag (int32_t o = -1) : Tag (), m_oif (o) {}
64 
65  static TypeId GetTypeId ()
66  {
67  static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag").SetParent<Tag> ()
68  .SetParent<Tag> ()
69  .AddConstructor<DeferredRouteOutputTag> ()
70  ;
71  return tid;
72  }
73 
75  {
76  return GetTypeId ();
77  }
78 
79  int32_t GetInterface() const
80  {
81  return m_oif;
82  }
83 
84  void SetInterface(int32_t oif)
85  {
86  m_oif = oif;
87  }
88 
89  uint32_t GetSerializedSize () const
90  {
91  return sizeof(int32_t);
92  }
93 
94  void Serialize (TagBuffer i) const
95  {
96  i.WriteU32 (m_oif);
97  }
98 
100  {
101  m_oif = i.ReadU32 ();
102  }
103 
104  void Print (std::ostream &os) const
105  {
106  os << "DeferredRouteOutputTag: output interface = " << m_oif;
107  }
108 
109 private:
111  int32_t m_oif;
112 };
113 
115 
116 
117 //-----------------------------------------------------------------------------
119  RreqRetries (2),
120  RreqRateLimit (10),
121  RerrRateLimit (10),
122  ActiveRouteTimeout (Seconds (3)),
123  NetDiameter (35),
124  NodeTraversalTime (MilliSeconds (40)),
125  NetTraversalTime (Time ((2 * NetDiameter) * NodeTraversalTime)),
126  PathDiscoveryTime ( Time (2 * NetTraversalTime)),
127  MyRouteTimeout (Time (2 * std::max (PathDiscoveryTime, ActiveRouteTimeout))),
128  HelloInterval (Seconds (1)),
129  AllowedHelloLoss (2),
130  DeletePeriod (Time (5 * std::max (ActiveRouteTimeout, HelloInterval))),
131  NextHopWait (NodeTraversalTime + MilliSeconds (10)),
132  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
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,
228  MakeUintegerChecker<uint32_t> ())
229  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
230  TimeValue (Seconds (30)),
231  MakeTimeAccessor (&RoutingProtocol::SetMaxQueueTime,
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,
242  MakeBooleanChecker ())
243  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
244  BooleanValue (false),
245  MakeBooleanAccessor (&RoutingProtocol::SetDesinationOnlyFlag,
247  MakeBooleanChecker ())
248  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
249  BooleanValue (true),
250  MakeBooleanAccessor (&RoutingProtocol::SetHelloEnable,
252  MakeBooleanChecker ())
253  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
254  BooleanValue (true),
255  MakeBooleanAccessor (&RoutingProtocol::SetBroadcastEnable,
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
269 {
270  MaxQueueLen = len;
271  m_queue.SetMaxQueueLen (len);
272 }
273 void
275 {
276  MaxQueueTime = t;
278 }
279 
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  return route;
364  }
365 
366  // Valid route not found, in this case we return loopback.
367  // Actual route request will be deferred until packet will be fully formed,
368  // routed to loopback, received from loopback and passed to RouteInput (see below)
369  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
370  DeferredRouteOutputTag tag (iif);
371  if (!p->PeekPacketTag (tag))
372  {
373  p->AddPacketTag (tag);
374  }
375  return LoopbackRoute (header, oif);
376 }
377 
378 void
381 {
382  NS_LOG_FUNCTION (this << p << header);
383  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
384 
385  QueueEntry newEntry (p, header, ucb, ecb);
386  bool result = m_queue.Enqueue (newEntry);
387  if (result)
388  {
389  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
391  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
392  if(!result || ((rt.GetFlag () != IN_SEARCH) && result))
393  {
394  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " <<header.GetDestination ());
395  SendRequest (header.GetDestination ());
396  }
397  }
398 }
399 
400 bool
404 {
405  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
406  if (m_socketAddresses.empty ())
407  {
408  NS_LOG_LOGIC ("No aodv interfaces");
409  return false;
410  }
411  NS_ASSERT (m_ipv4 != 0);
412  NS_ASSERT (p != 0);
413  // Check if input device supports IP
414  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
415  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
416 
417  Ipv4Address dst = header.GetDestination ();
418  Ipv4Address origin = header.GetSource ();
419 
420  // Deferred route request
421  if (idev == m_lo)
422  {
424  if (p->PeekPacketTag (tag))
425  {
426  DeferredRouteOutput (p, header, ucb, ecb);
427  return true;
428  }
429  }
430 
431  // Duplicate of own packet
432  if (IsMyOwnAddress (origin))
433  return true;
434 
435  // AODV is not a multicast routing protocol
436  if (dst.IsMulticast ())
437  {
438  return false;
439  }
440 
441  // Broadcast local delivery/forwarding
442  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
443  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
444  {
445  Ipv4InterfaceAddress iface = j->second;
446  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
447  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
448  {
449  if (m_dpd.IsDuplicate (p, header))
450  {
451  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
452  return true;
453  }
455  Ptr<Packet> packet = p->Copy ();
456  if (lcb.IsNull () == false)
457  {
458  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
459  lcb (p, header, iif);
460  // Fall through to additional processing
461  }
462  else
463  {
464  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
465  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
466  }
467  if (!EnableBroadcast)
468  {
469  return true;
470  }
471  if (header.GetTtl () > 1)
472  {
473  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
474  RoutingTableEntry toBroadcast;
475  if (m_routingTable.LookupRoute (dst, toBroadcast))
476  {
477  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
478  ucb (route, packet, header);
479  }
480  else
481  {
482  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
483  }
484  }
485  else
486  {
487  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
488  }
489  return true;
490  }
491  }
492 
493  // Unicast local delivery
494  if (m_ipv4->IsDestinationAddress (dst, iif))
495  {
497  RoutingTableEntry toOrigin;
498  if (m_routingTable.LookupValidRoute (origin, toOrigin))
499  {
501  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
502  }
503  if (lcb.IsNull () == false)
504  {
505  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
506  lcb (p, header, iif);
507  }
508  else
509  {
510  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
511  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
512  }
513  return true;
514  }
515 
516  // Forwarding
517  return Forwarding (p, header, ucb, ecb);
518 }
519 
520 bool
523 {
524  NS_LOG_FUNCTION (this);
525  Ipv4Address dst = header.GetDestination ();
526  Ipv4Address origin = header.GetSource ();
528  RoutingTableEntry toDst;
529  if (m_routingTable.LookupRoute (dst, toDst))
530  {
531  if (toDst.GetFlag () == VALID)
532  {
533  Ptr<Ipv4Route> route = toDst.GetRoute ();
534  NS_LOG_LOGIC (route->GetSource ()<<" forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
535 
536  /*
537  * Each time a route is used to forward a data packet, its Active Route
538  * Lifetime field of the source, destination and the next hop on the
539  * path to the destination is updated to be no less than the current
540  * time plus ActiveRouteTimeout.
541  */
545  /*
546  * Since the route between each originator and destination pair is expected to be symmetric, the
547  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
548  * to be no less than the current time plus ActiveRouteTimeout
549  */
550  RoutingTableEntry toOrigin;
551  m_routingTable.LookupRoute (origin, toOrigin);
552  UpdateRouteLifeTime (toOrigin.GetNextHop (), ActiveRouteTimeout);
553 
555  m_nb.Update (toOrigin.GetNextHop (), ActiveRouteTimeout);
556 
557  ucb (route, p, header);
558  return true;
559  }
560  else
561  {
562  if (toDst.GetValidSeqNo ())
563  {
564  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
565  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
566  return false;
567  }
568  }
569  }
570  NS_LOG_LOGIC ("route not found to "<< dst << ". Send RERR message.");
571  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
572  SendRerrWhenNoRouteToForward (dst, 0, origin);
573  return false;
574 }
575 
576 void
578 {
579  NS_ASSERT (ipv4 != 0);
580  NS_ASSERT (m_ipv4 == 0);
581 
582  if (EnableHello)
583  {
586  }
587 
588  m_ipv4 = ipv4;
589 
590  // Create lo route. It is asserted that the only one interface up for now is loopback
591  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
592  m_lo = m_ipv4->GetNetDevice (0);
593  NS_ASSERT (m_lo != 0);
594  // Remember lo route
595  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
596  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
597  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
598  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
600 
602 }
603 
604 void
606 {
607  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
609  if (l3->GetNAddresses (i) > 1)
610  {
611  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
612  }
613  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
614  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
615  return;
616 
617  // Create a socket to listen only on this interface
618  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
620  NS_ASSERT (socket != 0);
622  socket->BindToNetDevice (l3->GetNetDevice (i));
624  socket->SetAllowBroadcast (true);
625  socket->SetAttribute ("IpTtl", UintegerValue (1));
626  m_socketAddresses.insert (std::make_pair (socket, iface));
627 
628  // Add local broadcast record to the routing table
630  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
631  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
633 
634  // Allow neighbor manager use this interface for layer 2 feedback if possible
636  if (wifi == 0)
637  return;
638  Ptr<WifiMac> mac = wifi->GetMac ();
639  if (mac == 0)
640  return;
641 
642  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
643  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
644 }
645 
646 void
648 {
649  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
650 
651  // Disable layer 2 link state monitoring (if possible)
653  Ptr<NetDevice> dev = l3->GetNetDevice (i);
654  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
655  if (wifi != 0)
656  {
657  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
658  if (mac != 0)
659  {
660  mac->TraceDisconnectWithoutContext ("TxErrHeader",
662  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
663  }
664  }
665 
666  // Close socket
668  NS_ASSERT (socket);
669  socket->Close ();
670  m_socketAddresses.erase (socket);
671  if (m_socketAddresses.empty ())
672  {
673  NS_LOG_LOGIC ("No aodv interfaces");
674  m_htimer.Cancel ();
675  m_nb.Clear ();
677  return;
678  }
680 }
681 
682 void
684 {
685  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
687  if (!l3->IsUp (i))
688  return;
689  if (l3->GetNAddresses (i) == 1)
690  {
691  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
693  if (!socket)
694  {
695  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
696  return;
697  // Create a socket to listen only on this interface
698  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
700  NS_ASSERT (socket != 0);
702  socket->BindToNetDevice (l3->GetNetDevice (i));
703  // Bind to any IP address so that broadcasts can be received
705  socket->SetAllowBroadcast (true);
706  m_socketAddresses.insert (std::make_pair (socket, iface));
707 
708  // Add local broadcast record to the routing table
711  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
712  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
713  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
715  }
716  }
717  else
718  {
719  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
720  }
721 }
722 
723 void
725 {
726  NS_LOG_FUNCTION (this);
727  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
728  if (socket)
729  {
731  m_socketAddresses.erase (socket);
733  if (l3->GetNAddresses (i))
734  {
735  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
736  // Create a socket to listen only on this interface
737  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
739  NS_ASSERT (socket != 0);
741  // Bind to any IP address so that broadcasts can be received
743  socket->SetAllowBroadcast (true);
744  m_socketAddresses.insert (std::make_pair (socket, iface));
745 
746  // Add local broadcast record to the routing table
748  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
749  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
751  }
752  if (m_socketAddresses.empty ())
753  {
754  NS_LOG_LOGIC ("No aodv interfaces");
755  m_htimer.Cancel ();
756  m_nb.Clear ();
758  return;
759  }
760  }
761  else
762  {
763  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
764  }
765 }
766 
767 bool
769 {
770  NS_LOG_FUNCTION (this << src);
771  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
772  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
773  {
774  Ipv4InterfaceAddress iface = j->second;
775  if (src == iface.GetLocal ())
776  {
777  return true;
778  }
779  }
780  return false;
781 }
782 
785 {
786  NS_LOG_FUNCTION (this << hdr);
787  NS_ASSERT (m_lo != 0);
788  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
789  rt->SetDestination (hdr.GetDestination ());
790  //
791  // Source address selection here is tricky. The loopback route is
792  // returned when AODV does not have a route; this causes the packet
793  // to be looped back and handled (cached) in RouteInput() method
794  // while a route is found. However, connection-oriented protocols
795  // like TCP need to create an endpoint four-tuple (src, src port,
796  // dst, dst port) and create a pseudo-header for checksumming. So,
797  // AODV needs to guess correctly what the eventual source address
798  // will be.
799  //
800  // For single interface, single address nodes, this is not a problem.
801  // When there are possibly multiple outgoing interfaces, the policy
802  // implemented here is to pick the first available AODV interface.
803  // If RouteOutput() caller specified an outgoing interface, that
804  // further constrains the selection of source address
805  //
806  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
807  if (oif)
808  {
809  // Iterate to find an address on the oif device
810  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
811  {
812  Ipv4Address addr = j->second.GetLocal ();
813  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
814  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
815  {
816  rt->SetSource (addr);
817  break;
818  }
819  }
820  }
821  else
822  {
823  rt->SetSource (j->second.GetLocal ());
824  }
825  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
826  rt->SetGateway (Ipv4Address ("127.0.0.1"));
827  rt->SetOutputDevice (m_lo);
828  return rt;
829 }
830 
831 void
833 {
834  NS_LOG_FUNCTION ( this << dst);
835  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
836  if (m_rreqCount == RreqRateLimit)
837  {
839  &RoutingProtocol::SendRequest, this, dst);
840  return;
841  }
842  else
843  m_rreqCount++;
844  // Create RREQ header
845  RreqHeader rreqHeader;
846  rreqHeader.SetDst (dst);
847 
849  if (m_routingTable.LookupRoute (dst, rt))
850  {
851  rreqHeader.SetHopCount (rt.GetHop ());
852  if (rt.GetValidSeqNo ())
853  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
854  else
855  rreqHeader.SetUnknownSeqno (true);
856  rt.SetFlag (IN_SEARCH);
857  m_routingTable.Update (rt);
858  }
859  else
860  {
861  rreqHeader.SetUnknownSeqno (true);
862  Ptr<NetDevice> dev = 0;
863  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
864  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ 0,
865  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ Seconds (0));
866  newEntry.SetFlag (IN_SEARCH);
867  m_routingTable.AddRoute (newEntry);
868  }
869 
870  if (GratuitousReply)
871  rreqHeader.SetGratiousRrep (true);
872  if (DestinationOnly)
873  rreqHeader.SetDestinationOnly (true);
874 
875  m_seqNo++;
876  rreqHeader.SetOriginSeqno (m_seqNo);
877  m_requestId++;
878  rreqHeader.SetId (m_requestId);
879  rreqHeader.SetHopCount (0);
880 
881  // Send RREQ as subnet directed broadcast from each interface used by aodv
882  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
883  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
884  {
885  Ptr<Socket> socket = j->first;
886  Ipv4InterfaceAddress iface = j->second;
887 
888  rreqHeader.SetOrigin (iface.GetLocal ());
890 
891  Ptr<Packet> packet = Create<Packet> ();
892  packet->AddHeader (rreqHeader);
893  TypeHeader tHeader (AODVTYPE_RREQ);
894  packet->AddHeader (tHeader);
895  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
896  Ipv4Address destination;
897  if (iface.GetMask () == Ipv4Mask::GetOnes ())
898  {
899  destination = Ipv4Address ("255.255.255.255");
900  }
901  else
902  {
903  destination = iface.GetBroadcast ();
904  }
905  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
906  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
907  }
908  ScheduleRreqRetry (dst);
909  if (EnableHello)
910  {
911  if (!m_htimer.IsRunning ())
912  {
913  m_htimer.Cancel ();
915  }
916  }
917 }
918 
919 void
921 {
922  NS_LOG_FUNCTION (this << dst);
923  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
924  {
926  m_addressReqTimer[dst] = timer;
927  }
929  m_addressReqTimer[dst].Remove ();
930  m_addressReqTimer[dst].SetArguments (dst);
932  m_routingTable.LookupRoute (dst, rt);
933  rt.IncrementRreqCnt ();
934  m_routingTable.Update (rt);
935  m_addressReqTimer[dst].Schedule (Time (rt.GetRreqCnt () * NetTraversalTime));
936  NS_LOG_LOGIC ("Scheduled RREQ retry in " << Time (rt.GetRreqCnt () * NetTraversalTime).GetSeconds () << " seconds");
937 }
938 
939 void
941 {
942  NS_LOG_FUNCTION (this << socket);
943  Address sourceAddress;
944  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
945  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
946  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
947  Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
948  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
949 
950  UpdateRouteToNeighbor (sender, receiver);
951  TypeHeader tHeader (AODVTYPE_RREQ);
952  packet->RemoveHeader (tHeader);
953  if (!tHeader.IsValid ())
954  {
955  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
956  return; // drop
957  }
958  switch (tHeader.Get ())
959  {
960  case AODVTYPE_RREQ:
961  {
962  RecvRequest (packet, receiver, sender);
963  break;
964  }
965  case AODVTYPE_RREP:
966  {
967  RecvReply (packet, receiver, sender);
968  break;
969  }
970  case AODVTYPE_RERR:
971  {
972  RecvError (packet, sender);
973  break;
974  }
975  case AODVTYPE_RREP_ACK:
976  {
977  RecvReplyAck (sender);
978  break;
979  }
980  }
981 }
982 
983 bool
985 {
986  NS_LOG_FUNCTION (this << addr << lifetime);
988  if (m_routingTable.LookupRoute (addr, rt))
989  {
990  if (rt.GetFlag () == VALID)
991  {
992  NS_LOG_DEBUG ("Updating VALID route");
993  rt.SetRreqCnt (0);
994  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
995  m_routingTable.Update (rt);
996  return true;
997  }
998  }
999  return false;
1000 }
1001 
1002 void
1004 {
1005  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1006  RoutingTableEntry toNeighbor;
1007  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1008  {
1010  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1011  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1012  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ ActiveRouteTimeout);
1013  m_routingTable.AddRoute (newEntry);
1014  }
1015  else
1016  {
1018  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1019  {
1020  toNeighbor.SetLifeTime (std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1021  }
1022  else
1023  {
1024  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1025  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1026  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (ActiveRouteTimeout, toNeighbor.GetLifeTime ()));
1027  m_routingTable.Update (newEntry);
1028  }
1029  }
1030 
1031 }
1032 
1033 void
1035 {
1036  NS_LOG_FUNCTION (this);
1037  RreqHeader rreqHeader;
1038  p->RemoveHeader (rreqHeader);
1039 
1040  // A node ignores all RREQs received from any node in its blacklist
1041  RoutingTableEntry toPrev;
1042  if (m_routingTable.LookupRoute (src, toPrev))
1043  {
1044  if (toPrev.IsUnidirectional ())
1045  {
1046  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1047  return;
1048  }
1049  }
1050 
1051  uint32_t id = rreqHeader.GetId ();
1052  Ipv4Address origin = rreqHeader.GetOrigin ();
1053 
1054  /*
1055  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1056  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1057  */
1058  if (m_rreqIdCache.IsDuplicate (origin, id))
1059  {
1060  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1061  return;
1062  }
1063 
1064  // Increment RREQ hop count
1065  uint8_t hop = rreqHeader.GetHopCount () + 1;
1066  rreqHeader.SetHopCount (hop);
1067 
1068  /*
1069  * When the reverse route is created or updated, the following actions on the route are also carried out:
1070  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1071  * in the route table entry and copied if greater than the existing value there
1072  * 2. the valid sequence number field is set to true;
1073  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1074  * 4. the hop count is copied from the Hop Count in the RREQ message;
1075  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1076  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1077  */
1078  RoutingTableEntry toOrigin;
1079  if (!m_routingTable.LookupRoute (origin, toOrigin))
1080  {
1082  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1083  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1084  /*nextHop*/ src, /*timeLife=*/ Time ((2 * NetTraversalTime - 2 * hop * NodeTraversalTime)));
1085  m_routingTable.AddRoute (newEntry);
1086  }
1087  else
1088  {
1089  if (toOrigin.GetValidSeqNo ())
1090  {
1091  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1092  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1093  }
1094  else
1095  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1096  toOrigin.SetValidSeqNo (true);
1097  toOrigin.SetNextHop (src);
1099  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1100  toOrigin.SetHop (hop);
1101  toOrigin.SetLifeTime (std::max (Time (2 * NetTraversalTime - 2 * hop * NodeTraversalTime),
1102  toOrigin.GetLifeTime ()));
1103  m_routingTable.Update (toOrigin);
1104  }
1105  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t>(rreqHeader.GetHopCount ())
1106  << " ID " << rreqHeader.GetId ()
1107  << " to destination " << rreqHeader.GetDst ());
1108 
1109  // A node generates a RREP if either:
1110  // (i) it is itself the destination,
1111  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1112  {
1113  m_routingTable.LookupRoute (origin, toOrigin);
1114  NS_LOG_DEBUG ("Send reply since I am the destination");
1115  SendReply (rreqHeader, toOrigin);
1116  return;
1117  }
1118  /*
1119  * (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
1120  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1121  */
1122  RoutingTableEntry toDst;
1123  Ipv4Address dst = rreqHeader.GetDst ();
1124  if (m_routingTable.LookupRoute (dst, toDst))
1125  {
1126  /*
1127  * Drop RREQ, This node RREP wil make a loop.
1128  */
1129  if (toDst.GetNextHop () == src)
1130  {
1131  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1132  return;
1133  }
1134  /*
1135  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1136  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1137  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1138  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1139  */
1140  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1141  && toDst.GetValidSeqNo () )
1142  {
1143  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1144  {
1145  m_routingTable.LookupRoute (origin, toOrigin);
1146  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep ());
1147  return;
1148  }
1149  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1150  rreqHeader.SetUnknownSeqno (false);
1151  }
1152  }
1153 
1154  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1155  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1156  {
1157  Ptr<Socket> socket = j->first;
1158  Ipv4InterfaceAddress iface = j->second;
1159  Ptr<Packet> packet = Create<Packet> ();
1160  packet->AddHeader (rreqHeader);
1161  TypeHeader tHeader (AODVTYPE_RREQ);
1162  packet->AddHeader (tHeader);
1163  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1164  Ipv4Address destination;
1165  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1166  {
1167  destination = Ipv4Address ("255.255.255.255");
1168  }
1169  else
1170  {
1171  destination = iface.GetBroadcast ();
1172  }
1173  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1174  }
1175 
1176  if (EnableHello)
1177  {
1178  if (!m_htimer.IsRunning ())
1179  {
1180  m_htimer.Cancel ();
1182  }
1183  }
1184 }
1185 
1186 void
1187 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1188 {
1189  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1190  /*
1191  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1192  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1193  */
1194  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1195  m_seqNo++;
1196  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1197  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ MyRouteTimeout);
1198  Ptr<Packet> packet = Create<Packet> ();
1199  packet->AddHeader (rrepHeader);
1200  TypeHeader tHeader (AODVTYPE_RREP);
1201  packet->AddHeader (tHeader);
1203  NS_ASSERT (socket);
1204  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1205 }
1206 
1207 void
1209 {
1210  NS_LOG_FUNCTION (this);
1211  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1212  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1213  /* If the node we received a RREQ for is a neighbor we are
1214  * probably facing a unidirectional link... Better request a RREP-ack
1215  */
1216  if (toDst.GetHop () == 1)
1217  {
1218  rrepHeader.SetAckRequired (true);
1219  RoutingTableEntry toNextHop;
1220  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1222  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), BlackListTimeout);
1223  toNextHop.m_ackTimer.SetDelay (NextHopWait);
1224  }
1225  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1226  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1227  m_routingTable.Update (toDst);
1228  m_routingTable.Update (toOrigin);
1229 
1230  Ptr<Packet> packet = Create<Packet> ();
1231  packet->AddHeader (rrepHeader);
1232  TypeHeader tHeader (AODVTYPE_RREP);
1233  packet->AddHeader (tHeader);
1235  NS_ASSERT (socket);
1236  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1237 
1238  // Generating gratuitous RREPs
1239  if (gratRep)
1240  {
1241  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1242  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1243  /*lifetime=*/ toOrigin.GetLifeTime ());
1244  Ptr<Packet> packetToDst = Create<Packet> ();
1245  packetToDst->AddHeader (gratRepHeader);
1246  TypeHeader type (AODVTYPE_RREP);
1247  packetToDst->AddHeader (type);
1249  NS_ASSERT (socket);
1250  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1251  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1252  }
1253 }
1254 
1255 void
1257 {
1258  NS_LOG_FUNCTION (this << " to " << neighbor);
1259  RrepAckHeader h;
1260  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1261  Ptr<Packet> packet = Create<Packet> ();
1262  packet->AddHeader (h);
1263  packet->AddHeader (typeHeader);
1264  RoutingTableEntry toNeighbor;
1265  m_routingTable.LookupRoute (neighbor, toNeighbor);
1266  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1267  NS_ASSERT (socket);
1268  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1269 }
1270 
1271 void
1273 {
1274  NS_LOG_FUNCTION (this << " src " << sender);
1275  RrepHeader rrepHeader;
1276  p->RemoveHeader (rrepHeader);
1277  Ipv4Address dst = rrepHeader.GetDst ();
1278  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1279 
1280  uint8_t hop = rrepHeader.GetHopCount () + 1;
1281  rrepHeader.SetHopCount (hop);
1282 
1283  // If RREP is Hello message
1284  if (dst == rrepHeader.GetOrigin ())
1285  {
1286  ProcessHello (rrepHeader, receiver);
1287  return;
1288  }
1289 
1290  /*
1291  * If the route table entry to the destination is created or updated, then the following actions occur:
1292  * - the route is marked as active,
1293  * - the destination sequence number is marked as valid,
1294  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1295  * which is indicated by the source IP address field in the IP header,
1296  * - the hop count is set to the value of the hop count from RREP message + 1
1297  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1298  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1299  */
1301  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1302  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1303  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1304  RoutingTableEntry toDst;
1305  if (m_routingTable.LookupRoute (dst, toDst))
1306  {
1307  /*
1308  * The existing entry is updated only in the following circumstances:
1309  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1310  */
1311  if (!toDst.GetValidSeqNo ())
1312  {
1313  m_routingTable.Update (newEntry);
1314  }
1315  // (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,
1316  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1317  {
1318  m_routingTable.Update (newEntry);
1319  }
1320  else
1321  {
1322  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1323  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1324  {
1325  m_routingTable.Update (newEntry);
1326  }
1327  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1328  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1329  {
1330  m_routingTable.Update (newEntry);
1331  }
1332  }
1333  }
1334  else
1335  {
1336  // The forward route for this destination is created if it does not already exist.
1337  NS_LOG_LOGIC ("add new route");
1338  m_routingTable.AddRoute (newEntry);
1339  }
1340  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1341  if (rrepHeader.GetAckRequired ())
1342  {
1343  SendReplyAck (sender);
1344  rrepHeader.SetAckRequired (false);
1345  }
1346  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1347  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1348  {
1349  if (toDst.GetFlag () == IN_SEARCH)
1350  {
1351  m_routingTable.Update (newEntry);
1352  m_addressReqTimer[dst].Remove ();
1353  m_addressReqTimer.erase (dst);
1354  }
1355  m_routingTable.LookupRoute (dst, toDst);
1356  SendPacketFromQueue (dst, toDst.GetRoute ());
1357  return;
1358  }
1359 
1360  RoutingTableEntry toOrigin;
1361  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1362  {
1363  return; // Impossible! drop.
1364  }
1365  toOrigin.SetLifeTime (std::max (ActiveRouteTimeout, toOrigin.GetLifeTime ()));
1366  m_routingTable.Update (toOrigin);
1367 
1368  // Update information about precursors
1369  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1370  {
1371  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1372  m_routingTable.Update (toDst);
1373 
1374  RoutingTableEntry toNextHopToDst;
1375  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1376  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1377  m_routingTable.Update (toNextHopToDst);
1378 
1379  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1380  m_routingTable.Update (toOrigin);
1381 
1382  RoutingTableEntry toNextHopToOrigin;
1383  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1384  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1385  m_routingTable.Update (toNextHopToOrigin);
1386  }
1387 
1388  Ptr<Packet> packet = Create<Packet> ();
1389  packet->AddHeader (rrepHeader);
1390  TypeHeader tHeader (AODVTYPE_RREP);
1391  packet->AddHeader (tHeader);
1393  NS_ASSERT (socket);
1394  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1395 }
1396 
1397 void
1399 {
1400  NS_LOG_FUNCTION (this);
1401  RoutingTableEntry rt;
1402  if(m_routingTable.LookupRoute (neighbor, rt))
1403  {
1404  rt.m_ackTimer.Cancel ();
1405  rt.SetFlag (VALID);
1406  m_routingTable.Update (rt);
1407  }
1408 }
1409 
1410 void
1412 {
1413  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1414  /*
1415  * Whenever a node receives a Hello message from a neighbor, the node
1416  * SHOULD make sure that it has an active route to the neighbor, and
1417  * create one if necessary.
1418  */
1419  RoutingTableEntry toNeighbor;
1420  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1421  {
1423  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1424  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1425  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1426  m_routingTable.AddRoute (newEntry);
1427  }
1428  else
1429  {
1430  toNeighbor.SetLifeTime (std::max (Time (AllowedHelloLoss * HelloInterval), toNeighbor.GetLifeTime ()));
1431  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1432  toNeighbor.SetValidSeqNo (true);
1433  toNeighbor.SetFlag (VALID);
1434  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1435  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1436  m_routingTable.Update (toNeighbor);
1437  }
1438  if (EnableHello)
1439  {
1440  m_nb.Update (rrepHeader.GetDst (), Time (AllowedHelloLoss * HelloInterval));
1441  }
1442 }
1443 
1444 void
1446 {
1447  NS_LOG_FUNCTION (this << " from " << src);
1448  RerrHeader rerrHeader;
1449  p->RemoveHeader (rerrHeader);
1450  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1451  std::map<Ipv4Address, uint32_t> unreachable;
1452  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1453  std::pair<Ipv4Address, uint32_t> un;
1454  while (rerrHeader.RemoveUnDestination (un))
1455  {
1456  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1457  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1458  {
1459  if (i->first == un.first)
1460  {
1461  unreachable.insert (un);
1462  }
1463  }
1464  }
1465 
1466  std::vector<Ipv4Address> precursors;
1467  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1468  i != unreachable.end ();)
1469  {
1470  if (!rerrHeader.AddUnDestination (i->first, i->second))
1471  {
1472  TypeHeader typeHeader (AODVTYPE_RERR);
1473  Ptr<Packet> packet = Create<Packet> ();
1474  packet->AddHeader (rerrHeader);
1475  packet->AddHeader (typeHeader);
1476  SendRerrMessage (packet, precursors);
1477  rerrHeader.Clear ();
1478  }
1479  else
1480  {
1481  RoutingTableEntry toDst;
1482  m_routingTable.LookupRoute (i->first, toDst);
1483  toDst.GetPrecursors (precursors);
1484  ++i;
1485  }
1486  }
1487  if (rerrHeader.GetDestCount () != 0)
1488  {
1489  TypeHeader typeHeader (AODVTYPE_RERR);
1490  Ptr<Packet> packet = Create<Packet> ();
1491  packet->AddHeader (rerrHeader);
1492  packet->AddHeader (typeHeader);
1493  SendRerrMessage (packet, precursors);
1494  }
1496 }
1497 
1498 void
1500 {
1501  NS_LOG_LOGIC (this);
1502  RoutingTableEntry toDst;
1503  if (m_routingTable.LookupValidRoute (dst, toDst))
1504  {
1505  SendPacketFromQueue (dst, toDst.GetRoute ());
1506  NS_LOG_LOGIC ("route to " << dst << " found");
1507  return;
1508  }
1509  /*
1510  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1511  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1512  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1513  */
1514  if (toDst.GetRreqCnt () == RreqRetries)
1515  {
1516  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << RreqRetries << ") times");
1517  m_addressReqTimer.erase (dst);
1519  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1520  m_queue.DropPacketWithDst (dst);
1521  return;
1522  }
1523 
1524  if (toDst.GetFlag () == IN_SEARCH)
1525  {
1526  NS_LOG_LOGIC ("Resend RREQ to " << dst << " ttl " << NetDiameter);
1527  SendRequest (dst);
1528  }
1529  else
1530  {
1531  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1532  m_addressReqTimer.erase (dst);
1534  m_queue.DropPacketWithDst (dst);
1535  }
1536 }
1537 
1538 void
1540 {
1541  NS_LOG_FUNCTION (this);
1542  SendHello ();
1543  m_htimer.Cancel ();
1544  Time t = Time (0.01 * MilliSeconds (m_uniformRandomVariable->GetInteger (0, 100)));
1546 }
1547 
1548 void
1550 {
1551  NS_LOG_FUNCTION (this);
1552  m_rreqCount = 0;
1554 }
1555 
1556 void
1558 {
1559  NS_LOG_FUNCTION (this);
1560  m_rerrCount = 0;
1562 }
1563 
1564 void
1566 {
1567  NS_LOG_FUNCTION (this);
1568  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1569 }
1570 
1571 void
1573 {
1574  NS_LOG_FUNCTION (this);
1575  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1576  * Destination IP Address The node's IP address.
1577  * Destination Sequence Number The node's latest sequence number.
1578  * Hop Count 0
1579  * Lifetime AllowedHelloLoss * HelloInterval
1580  */
1581  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1582  {
1583  Ptr<Socket> socket = j->first;
1584  Ipv4InterfaceAddress iface = j->second;
1585  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1586  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (AllowedHelloLoss * HelloInterval));
1587  Ptr<Packet> packet = Create<Packet> ();
1588  packet->AddHeader (helloHeader);
1589  TypeHeader tHeader (AODVTYPE_RREP);
1590  packet->AddHeader (tHeader);
1591  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1592  Ipv4Address destination;
1593  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1594  {
1595  destination = Ipv4Address ("255.255.255.255");
1596  }
1597  else
1598  {
1599  destination = iface.GetBroadcast ();
1600  }
1601  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1602  }
1603 }
1604 
1605 void
1607 {
1608  NS_LOG_FUNCTION (this);
1609  QueueEntry queueEntry;
1610  while (m_queue.Dequeue (dst, queueEntry))
1611  {
1613  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
1614  if (p->RemovePacketTag (tag) &&
1615  tag.GetInterface() != -1 &&
1617  {
1618  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
1619  return;
1620  }
1622  Ipv4Header header = queueEntry.GetIpv4Header ();
1623  header.SetSource (route->GetSource ());
1624  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
1625  ucb (route, p, header);
1626  }
1627 }
1628 
1629 void
1631 {
1632  NS_LOG_FUNCTION (this << nextHop);
1633  RerrHeader rerrHeader;
1634  std::vector<Ipv4Address> precursors;
1635  std::map<Ipv4Address, uint32_t> unreachable;
1636 
1637  RoutingTableEntry toNextHop;
1638  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
1639  return;
1640  toNextHop.GetPrecursors (precursors);
1641  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
1642  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
1643  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
1644  != unreachable.end ();)
1645  {
1646  if (!rerrHeader.AddUnDestination (i->first, i->second))
1647  {
1648  NS_LOG_LOGIC ("Send RERR message with maximum size.");
1649  TypeHeader typeHeader (AODVTYPE_RERR);
1650  Ptr<Packet> packet = Create<Packet> ();
1651  packet->AddHeader (rerrHeader);
1652  packet->AddHeader (typeHeader);
1653  SendRerrMessage (packet, precursors);
1654  rerrHeader.Clear ();
1655  }
1656  else
1657  {
1658  RoutingTableEntry toDst;
1659  m_routingTable.LookupRoute (i->first, toDst);
1660  toDst.GetPrecursors (precursors);
1661  ++i;
1662  }
1663  }
1664  if (rerrHeader.GetDestCount () != 0)
1665  {
1666  TypeHeader typeHeader (AODVTYPE_RERR);
1667  Ptr<Packet> packet = Create<Packet> ();
1668  packet->AddHeader (rerrHeader);
1669  packet->AddHeader (typeHeader);
1670  SendRerrMessage (packet, precursors);
1671  }
1672  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
1674 }
1675 
1676 void
1678  uint32_t dstSeqNo, Ipv4Address origin)
1679 {
1680  NS_LOG_FUNCTION (this);
1681  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1682  if (m_rerrCount == RerrRateLimit)
1683  {
1684  // Just make sure that the RerrRateLimit timer is running and will expire
1686  // discard the packet and return
1687  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1689  << "; suppressing RERR");
1690  return;
1691  }
1692  RerrHeader rerrHeader;
1693  rerrHeader.AddUnDestination (dst, dstSeqNo);
1694  RoutingTableEntry toOrigin;
1695  Ptr<Packet> packet = Create<Packet> ();
1696  packet->AddHeader (rerrHeader);
1697  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
1698  if (m_routingTable.LookupValidRoute (origin, toOrigin))
1699  {
1701  toOrigin.GetInterface ());
1702  NS_ASSERT (socket);
1703  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
1704  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1705  }
1706  else
1707  {
1708  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1709  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
1710  {
1711  Ptr<Socket> socket = i->first;
1712  Ipv4InterfaceAddress iface = i->second;
1713  NS_ASSERT (socket);
1714  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
1715  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1716  Ipv4Address destination;
1717  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1718  {
1719  destination = Ipv4Address ("255.255.255.255");
1720  }
1721  else
1722  {
1723  destination = iface.GetBroadcast ();
1724  }
1725  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1726  }
1727  }
1728 }
1729 
1730 void
1731 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
1732 {
1733  NS_LOG_FUNCTION (this);
1734 
1735  if (precursors.empty ())
1736  {
1737  NS_LOG_LOGIC ("No precursors");
1738  return;
1739  }
1740  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
1741  if (m_rerrCount == RerrRateLimit)
1742  {
1743  // Just make sure that the RerrRateLimit timer is running and will expire
1745  // discard the packet and return
1746  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
1748  << "; suppressing RERR");
1749  return;
1750  }
1751  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
1752  if (precursors.size () == 1)
1753  {
1754  RoutingTableEntry toPrecursor;
1755  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
1756  {
1757  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
1758  NS_ASSERT (socket);
1759  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
1760  socket->SendTo (packet, 0, InetSocketAddress (precursors.front (), AODV_PORT));
1761  m_rerrCount++;
1762  }
1763  return;
1764  }
1765 
1766  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
1767  std::vector<Ipv4InterfaceAddress> ifaces;
1768  RoutingTableEntry toPrecursor;
1769  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
1770  {
1771  if (m_routingTable.LookupValidRoute (*i, toPrecursor) &&
1772  std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
1773  {
1774  ifaces.push_back (toPrecursor.GetInterface ());
1775  }
1776  }
1777 
1778  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
1779  {
1781  NS_ASSERT (socket);
1782  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
1783  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1784  Ipv4Address destination;
1785  if (i->GetMask () == Ipv4Mask::GetOnes ())
1786  {
1787  destination = Ipv4Address ("255.255.255.255");
1788  }
1789  else
1790  {
1791  destination = i->GetBroadcast ();
1792  }
1793  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1794  m_rerrCount++;
1795  }
1796 }
1797 
1800 {
1801  NS_LOG_FUNCTION (this << addr);
1802  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1803  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1804  {
1805  Ptr<Socket> socket = j->first;
1806  Ipv4InterfaceAddress iface = j->second;
1807  if (iface == addr)
1808  return socket;
1809  }
1810  Ptr<Socket> socket;
1811  return socket;
1812 }
1813 
1814 }
1815 }