A Discrete-Event Network Simulator
API
aodv-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Based on
19  * NS-2 AODV model developed by the CMU/MONARCH group and optimized and
20  * tuned by Samir Das and Mahesh Marina, University of Cincinnati;
21  *
22  * AODV-UU implementation by Erik Nordström of Uppsala University
23  * http://core.it.uu.se/core/index.php/AODV-UU
24  *
25  * Authors: Elena Buchatskaia <borovkovaes@iitp.ru>
26  * Pavel Boyko <boyko@iitp.ru>
27  */
28 #define NS_LOG_APPEND_CONTEXT \
29  if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
30 
31 #include "aodv-routing-protocol.h"
32 #include "ns3/log.h"
33 #include "ns3/boolean.h"
34 #include "ns3/random-variable-stream.h"
35 #include "ns3/inet-socket-address.h"
36 #include "ns3/trace-source-accessor.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/udp-l4-protocol.h"
39 #include "ns3/udp-header.h"
40 #include "ns3/wifi-net-device.h"
41 #include "ns3/adhoc-wifi-mac.h"
42 #include "ns3/string.h"
43 #include "ns3/pointer.h"
44 #include <algorithm>
45 #include <limits>
46 #include "ns3/qkd-manager.h"
47 #include "ns3/qkd-internal-tag.h"
48 
49 namespace ns3 {
50 
51 NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
52 
53 namespace aodv {
54 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
55 
57 const uint32_t RoutingProtocol::AODV_PORT = 654;
58 
64 {
65 
66 public:
71  DeferredRouteOutputTag (int32_t o = -1) : Tag (),
72  m_oif (o)
73  {
74  }
75 
80  static TypeId GetTypeId ()
81  {
82  static TypeId tid = TypeId ("ns3::aodv::DeferredRouteOutputTag")
83  .SetParent<Tag> ()
84  .SetGroupName ("Aodv")
85  .AddConstructor<DeferredRouteOutputTag> ()
86  ;
87  return tid;
88  }
89 
91  {
92  return GetTypeId ();
93  }
94 
99  int32_t GetInterface () const
100  {
101  return m_oif;
102  }
103 
108  void SetInterface (int32_t oif)
109  {
110  m_oif = oif;
111  }
112 
113  uint32_t GetSerializedSize () const
114  {
115  return sizeof(int32_t);
116  }
117 
118  void Serialize (TagBuffer i) const
119  {
120  i.WriteU32 (m_oif);
121  }
122 
124  {
125  m_oif = i.ReadU32 ();
126  }
127 
128  void Print (std::ostream &os) const
129  {
130  os << "DeferredRouteOutputTag: output interface = " << m_oif;
131  }
132 
133 private:
135  int32_t m_oif;
136 };
137 
139 
140 
141 //-----------------------------------------------------------------------------
143  : m_rreqRetries (2),
144  m_ttlStart (1),
145  m_ttlIncrement (2),
146  m_ttlThreshold (7),
147  m_timeoutBuffer (2),
148  m_rreqRateLimit (10),
149  m_rerrRateLimit (10),
150  m_activeRouteTimeout (Seconds (3)),
151  m_netDiameter (35),
152  m_nodeTraversalTime (MilliSeconds (40)),
153  m_netTraversalTime (Time ((2 * m_netDiameter) * m_nodeTraversalTime)),
154  m_pathDiscoveryTime ( Time (2 * m_netTraversalTime)),
155  m_myRouteTimeout (Time (2 * std::max (m_pathDiscoveryTime, m_activeRouteTimeout))),
156  m_helloInterval (Seconds (1)),
157  m_allowedHelloLoss (2),
158  m_deletePeriod (Time (5 * std::max (m_activeRouteTimeout, m_helloInterval))),
159  m_nextHopWait (m_nodeTraversalTime + MilliSeconds (10)),
160  m_blackListTimeout (Time (m_rreqRetries * m_netTraversalTime)),
161  m_maxQueueLen (64),
162  m_maxQueueTime (Seconds (30)),
163  m_destinationOnly (false),
164  m_gratuitousReply (true),
165  m_enableHello (false),
166  m_routingTable (m_deletePeriod),
167  m_queue (m_maxQueueLen, m_maxQueueTime),
168  m_requestId (0),
169  m_seqNo (0),
170  m_rreqIdCache (m_pathDiscoveryTime),
171  m_dpd (m_pathDiscoveryTime),
172  m_nb (m_helloInterval),
173  m_rreqCount (0),
174  m_rerrCount (0),
175  m_htimer (Timer::CANCEL_ON_DESTROY),
176  m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
177  m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY),
178  m_lastBcastTime (Seconds (0))
179 {
181 }
182 
183 TypeId
185 {
186  static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol")
188  .SetGroupName ("Aodv")
189  .AddConstructor<RoutingProtocol> ()
190  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
191  TimeValue (Seconds (1)),
193  MakeTimeChecker ())
194  .AddAttribute ("TtlStart", "Initial TTL value for RREQ.",
195  UintegerValue (1),
197  MakeUintegerChecker<uint16_t> ())
198  .AddAttribute ("TtlIncrement", "TTL increment for each attempt using the expanding ring search for RREQ dissemination.",
199  UintegerValue (2),
201  MakeUintegerChecker<uint16_t> ())
202  .AddAttribute ("TtlThreshold", "Maximum TTL value for expanding ring search, TTL = NetDiameter is used beyond this value.",
203  UintegerValue (7),
205  MakeUintegerChecker<uint16_t> ())
206  .AddAttribute ("TimeoutBuffer", "Provide a buffer for the timeout.",
207  UintegerValue (2),
209  MakeUintegerChecker<uint16_t> ())
210  .AddAttribute ("RreqRetries", "Maximum number of retransmissions of RREQ to discover a route",
211  UintegerValue (2),
213  MakeUintegerChecker<uint32_t> ())
214  .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.",
215  UintegerValue (10),
217  MakeUintegerChecker<uint32_t> ())
218  .AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
219  UintegerValue (10),
221  MakeUintegerChecker<uint32_t> ())
222  .AddAttribute ("NodeTraversalTime", "Conservative estimate of the average one hop traversal time for packets and should include "
223  "queuing delays, interrupt processing times and transfer times.",
224  TimeValue (MilliSeconds (40)),
226  MakeTimeChecker ())
227  .AddAttribute ("NextHopWait", "Period of our waiting for the neighbour's RREP_ACK = 10 ms + NodeTraversalTime",
228  TimeValue (MilliSeconds (50)),
230  MakeTimeChecker ())
231  .AddAttribute ("ActiveRouteTimeout", "Period of time during which the route is considered to be valid",
232  TimeValue (Seconds (3)),
234  MakeTimeChecker ())
235  .AddAttribute ("MyRouteTimeout", "Value of lifetime field in RREP generating by this node = 2 * max(ActiveRouteTimeout, PathDiscoveryTime)",
236  TimeValue (Seconds (11.2)),
238  MakeTimeChecker ())
239  .AddAttribute ("BlackListTimeout", "Time for which the node is put into the blacklist = RreqRetries * NetTraversalTime",
240  TimeValue (Seconds (5.6)),
242  MakeTimeChecker ())
243  .AddAttribute ("DeletePeriod", "DeletePeriod is intended to provide an upper bound on the time for which an upstream node A "
244  "can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D."
245  " = 5 * max (HelloInterval, ActiveRouteTimeout)",
246  TimeValue (Seconds (15)),
248  MakeTimeChecker ())
249  .AddAttribute ("NetDiameter", "Net diameter measures the maximum possible number of hops between two nodes in the network",
250  UintegerValue (35),
252  MakeUintegerChecker<uint32_t> ())
253  .AddAttribute ("NetTraversalTime", "Estimate of the average net traversal time = 2 * NodeTraversalTime * NetDiameter",
254  TimeValue (Seconds (2.8)),
256  MakeTimeChecker ())
257  .AddAttribute ("PathDiscoveryTime", "Estimate of maximum time needed to find route in network = 2 * NetTraversalTime",
258  TimeValue (Seconds (5.6)),
260  MakeTimeChecker ())
261  .AddAttribute ("MaxQueueLen", "Maximum number of packets that we allow a routing protocol to buffer.",
262  UintegerValue (64),
265  MakeUintegerChecker<uint32_t> ())
266  .AddAttribute ("MaxQueueTime", "Maximum time packets can be queued (in seconds)",
267  TimeValue (Seconds (30)),
270  MakeTimeChecker ())
271  .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.",
272  UintegerValue (2),
274  MakeUintegerChecker<uint16_t> ())
275  .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.",
276  BooleanValue (true),
280  .AddAttribute ("DestinationOnly", "Indicates only the destination may respond to this RREQ.",
281  BooleanValue (false),
285  .AddAttribute ("EnableHello", "Indicates whether a hello messages enable.",
286  BooleanValue (true),
290  .AddAttribute ("EnableBroadcast", "Indicates whether a broadcast data packets forwarding enable.",
291  BooleanValue (true),
295  .AddAttribute ("UniformRv",
296  "Access to the underlying UniformRandomVariable",
297  StringValue ("ns3::UniformRandomVariable"),
299  MakePointerChecker<UniformRandomVariable> ())
300  ;
301  return tid;
302 }
303 
304 void
306 {
307  m_maxQueueLen = len;
308  m_queue.SetMaxQueueLen (len);
309 }
310 void
312 {
313  m_maxQueueTime = t;
315 }
316 
318 {
319 }
320 
321 void
323 {
324  m_ipv4 = 0;
325  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
326  m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++)
327  {
328  iter->first->Close ();
329  }
330  m_socketAddresses.clear ();
331  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
333  {
334  iter->first->Close ();
335  }
338 }
339 
340 void
342 {
343  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
344  << "; Time: " << Now ().As (unit)
345  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (unit)
346  << ", AODV Routing table" << std::endl;
347 
348  m_routingTable.Print (stream);
349  *stream->GetStream () << std::endl;
350 }
351 
352 
353 void
354 RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream, std::string additionalData) const
355 {
356  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
357  << "; Time: " << Now().As (Time::S)
358  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (Time::S)
359  << ", AODV Routing table"
360  << "s " << "\t" << additionalData << std::endl;
361 
362  m_routingTable.Print (stream);
363  *stream->GetStream () << std::endl;
364 }
365 
366 int64_t
368 {
369  NS_LOG_FUNCTION (this << stream);
371  return 1;
372 }
373 
374 void
376 {
377  NS_LOG_FUNCTION (this);
378  if (m_enableHello)
379  {
380  m_nb.ScheduleTimer ();
381  }
383  this);
385 
387  this);
389 
390 }
391 
394  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
395 {
396  NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
397  if (!p)
398  {
399  NS_LOG_DEBUG ("Packet is == 0");
400  return LoopbackRoute (header, oif); // later
401  }
402  if (m_socketAddresses.empty ())
403  {
404  sockerr = Socket::ERROR_NOROUTETOHOST;
405  NS_LOG_LOGIC ("No aodv interfaces");
406  Ptr<Ipv4Route> route;
407  return route;
408  }
409  sockerr = Socket::ERROR_NOTERROR;
410  Ptr<Ipv4Route> route;
411  Ipv4Address dst = header.GetDestination ();
413  if (m_routingTable.LookupValidRoute (dst, rt))
414  {
415  route = rt.GetRoute ();
416  NS_ASSERT (route != 0);
417  NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
418  if (oif != 0 && route->GetOutputDevice () != oif)
419  {
420  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
421  sockerr = Socket::ERROR_NOROUTETOHOST;
422  return Ptr<Ipv4Route> ();
423  }
426  return route;
427  }
428 
429  // Valid route not found, in this case we return loopback.
430  // Actual route request will be deferred until packet will be fully formed,
431  // routed to loopback, received from loopback and passed to RouteInput (see below)
432  uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
433  DeferredRouteOutputTag tag (iif);
434  NS_LOG_DEBUG ("Valid Route not found");
435  if (!p->PeekPacketTag (tag))
436  {
437  p->AddPacketTag (tag);
438  }
439  return LoopbackRoute (header, oif);
440 }
441 
442 void
445 {
446  NS_LOG_FUNCTION (this << p << header);
447  NS_ASSERT (p != 0 && p != Ptr<Packet> ());
448 
449  QueueEntry newEntry (p, header, ucb, ecb);
450  bool result = m_queue.Enqueue (newEntry);
451  if (result)
452  {
453  NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " << (uint16_t) header.GetProtocol ());
455  bool result = m_routingTable.LookupRoute (header.GetDestination (), rt);
456  if (!result || ((rt.GetFlag () != IN_SEARCH) && result))
457  {
458  NS_LOG_LOGIC ("Send new RREQ for outbound packet to " << header.GetDestination ());
459  SendRequest (header.GetDestination ());
460  }
461  }
462 }
463 
464 bool
468 {
469  NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
470  if (m_socketAddresses.empty ())
471  {
472  NS_LOG_LOGIC ("No aodv interfaces");
473  return false;
474  }
475  NS_ASSERT (m_ipv4 != 0);
476  NS_ASSERT (p != 0);
477  // Check if input device supports IP
478  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
479  int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
480 
481  this->PrintRoutingTable (routingStream, "RouteInput");
482 
483  Ipv4Address dst = header.GetDestination ();
484  Ipv4Address origin = header.GetSource ();
485 
486  // Deferred route request
487  if (idev == m_lo)
488  {
490  if (p->PeekPacketTag (tag))
491  {
492  DeferredRouteOutput (p, header, ucb, ecb);
493  return true;
494  }
495  }
496 
497  // Duplicate of own packet
498  if (IsMyOwnAddress (origin))
499  {
500  return true;
501  }
502 
503  // AODV is not a multicast routing protocol
504  if (dst.IsMulticast ())
505  {
506  return false;
507  }
508 
509  // Broadcast local delivery/forwarding
510  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
511  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
512  {
513  Ipv4InterfaceAddress iface = j->second;
514  if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
515  {
516  if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
517  {
518  if (m_dpd.IsDuplicate (p, header))
519  {
520  NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
521  return true;
522  }
524  Ptr<Packet> packet = p->Copy ();
525  if (lcb.IsNull () == false)
526  {
527  NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
528  lcb (p, header, iif);
529  // Fall through to additional processing
530  }
531  else
532  {
533  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
534  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
535  }
536  if (!m_enableBroadcast)
537  {
538  return true;
539  }
540  if (header.GetProtocol () == UdpL4Protocol::PROT_NUMBER)
541  {
542  UdpHeader udpHeader;
543  p->PeekHeader (udpHeader);
544  if (udpHeader.GetDestinationPort () == AODV_PORT)
545  {
546  // AODV packets sent in broadcast are already managed
547  return true;
548  }
549  }
550  if (header.GetTtl () > 1)
551  {
552  NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
553  RoutingTableEntry toBroadcast;
554  if (m_routingTable.LookupRoute (dst, toBroadcast))
555  {
556  Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
557  ucb (route, packet, header);
558  }
559  else
560  {
561  NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
562  }
563  }
564  else
565  {
566  NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
567  }
568  return true;
569  }
570  }
571  }
572 
573  // Unicast local delivery
574  if (m_ipv4->IsDestinationAddress (dst, iif))
575  {
577  RoutingTableEntry toOrigin;
578  if (m_routingTable.LookupValidRoute (origin, toOrigin))
579  {
582  }
583  if (lcb.IsNull () == false)
584  {
585  NS_LOG_LOGIC ("Unicast local delivery to " << dst);
586  lcb (p, header, iif);
587  }
588  else
589  {
590  NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
591  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
592  }
593  return true;
594  }
595 
596  // Check if input device supports IP forwarding
597  if (m_ipv4->IsForwarding (iif) == false)
598  {
599  NS_LOG_LOGIC ("Forwarding disabled for this interface");
600  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
601  return true;
602  }
603 
604  // Forwarding
605  return Forwarding (p, header, ucb, ecb);
606 }
607 
608 bool
611 {
612  NS_LOG_FUNCTION (this);
613  Ipv4Address dst = header.GetDestination ();
614  Ipv4Address origin = header.GetSource ();
616  RoutingTableEntry toDst;
617  if (m_routingTable.LookupRoute (dst, toDst))
618  {
619  if (toDst.GetFlag () == VALID)
620  {
621  Ptr<Ipv4Route> route = toDst.GetRoute ();
622  NS_LOG_LOGIC (route->GetSource () << " forwarding to " << dst << " from " << origin << " packet " << p->GetUid ());
623 
624  /*
625  * Each time a route is used to forward a data packet, its Active Route
626  * Lifetime field of the source, destination and the next hop on the
627  * path to the destination is updated to be no less than the current
628  * time plus ActiveRouteTimeout.
629  */
633  /*
634  * Since the route between each originator and destination pair is expected to be symmetric, the
635  * Active Route Lifetime for the previous hop, along the reverse path back to the IP source, is also updated
636  * to be no less than the current time plus ActiveRouteTimeout
637  */
638  RoutingTableEntry toOrigin;
639  m_routingTable.LookupRoute (origin, toOrigin);
640  UpdateRouteLifeTime (toOrigin.GetNextHop (), m_activeRouteTimeout);
641 
643  m_nb.Update (toOrigin.GetNextHop (), m_activeRouteTimeout);
644 
645  ucb (route, p, header);
646  return true;
647  }
648  else
649  {
650  if (toDst.GetValidSeqNo ())
651  {
652  SendRerrWhenNoRouteToForward (dst, toDst.GetSeqNo (), origin);
653  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
654  return false;
655  }
656  }
657  }
658  NS_LOG_LOGIC ("route not found to " << dst << ". Send RERR message.");
659  NS_LOG_DEBUG ("Drop packet " << p->GetUid () << " because no route to forward it.");
660  SendRerrWhenNoRouteToForward (dst, 0, origin);
661  return false;
662 }
663 
664 void
666 {
667  NS_ASSERT (ipv4 != 0);
668  NS_ASSERT (m_ipv4 == 0);
669 
670  m_ipv4 = ipv4;
671 
672  // Create lo route. It is asserted that the only one interface up for now is loopback
673  NS_ASSERT (m_ipv4->GetNInterfaces () == 1 && m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address ("127.0.0.1"));
674  m_lo = m_ipv4->GetNetDevice (0);
675  NS_ASSERT (m_lo != 0);
676  // Remember lo route
677  RoutingTableEntry rt (/*device=*/ m_lo, /*dst=*/ Ipv4Address::GetLoopback (), /*know seqno=*/ true, /*seqno=*/ 0,
678  /*iface=*/ Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask ("255.0.0.0")),
679  /*hops=*/ 1, /*next hop=*/ Ipv4Address::GetLoopback (),
680  /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
682 
683  std::ostringstream temp;
684  temp << "aodv-routing-tables_" << m_ipv4->GetObject<Node>()->GetId() << ".txt";
685  routingStream = Create<OutputStreamWrapper>(temp.str(), std::ios::out);
686 
687 
689 }
690 
691 void
693 {
694  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
695  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
696  if (l3->GetNAddresses (i) > 1)
697  {
698  NS_LOG_WARN ("AODV does not work with more then one address per each interface.");
699  }
700  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
701  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
702  {
703  return;
704  }
705 
706  // Create a socket to listen only on this interface
707  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
709  NS_ASSERT (socket != 0);
711  socket->BindToNetDevice (l3->GetNetDevice (i));
712  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
713  socket->SetAllowBroadcast (true);
714  socket->SetIpRecvTtl (true);
715  m_socketAddresses.insert (std::make_pair (socket, iface));
716 
717  // create also a subnet broadcast socket
718  socket = Socket::CreateSocket (GetObject<Node> (),
720  NS_ASSERT (socket != 0);
722  socket->BindToNetDevice (l3->GetNetDevice (i));
723  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
724  socket->SetAllowBroadcast (true);
725  socket->SetIpRecvTtl (true);
726  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
727 
728  // Add local broadcast record to the routing table
729  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
730  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
731  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
733 
734  if (l3->GetInterface (i)->GetArpCache ())
735  {
736  m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
737  }
738 
739  // Allow neighbor manager use this interface for layer 2 feedback if possible
740  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
741  if (wifi == 0)
742  {
743  return;
744  }
745  Ptr<WifiMac> mac = wifi->GetMac ();
746  if (mac == 0)
747  {
748  return;
749  }
750 
751  mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
752 }
753 
754 void
756 {
757  NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
758 
759  // Disable layer 2 link state monitoring (if possible)
760  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
761  Ptr<NetDevice> dev = l3->GetNetDevice (i);
762  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
763  if (wifi != 0)
764  {
765  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
766  if (mac != 0)
767  {
768  mac->TraceDisconnectWithoutContext ("TxErrHeader",
770  m_nb.DelArpCache (l3->GetInterface (i)->GetArpCache ());
771  }
772  }
773 
774  // Close socket
775  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
776  NS_ASSERT (socket);
777  socket->Close ();
778  m_socketAddresses.erase (socket);
779 
780  // Close socket
781  socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
782  NS_ASSERT (socket);
783  socket->Close ();
784  m_socketSubnetBroadcastAddresses.erase (socket);
785 
786  if (m_socketAddresses.empty ())
787  {
788  NS_LOG_LOGIC ("No aodv interfaces");
789  m_htimer.Cancel ();
790  m_nb.Clear ();
792  return;
793  }
795 }
796 
797 void
799 {
800  NS_LOG_FUNCTION (this << " interface " << i << " address " << address);
801  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
802  if (!l3->IsUp (i))
803  {
804  return;
805  }
806  if (l3->GetNAddresses (i) == 1)
807  {
808  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
810  if (!socket)
811  {
812  if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
813  {
814  return;
815  }
816  // Create a socket to listen only on this interface
817  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
819  NS_ASSERT (socket != 0);
821  socket->BindToNetDevice (l3->GetNetDevice (i));
822  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
823  socket->SetAllowBroadcast (true);
824  m_socketAddresses.insert (std::make_pair (socket, iface));
825 
826  // create also a subnet directed broadcast socket
827  socket = Socket::CreateSocket (GetObject<Node> (),
829  NS_ASSERT (socket != 0);
831  socket->BindToNetDevice (l3->GetNetDevice (i));
832  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
833  socket->SetAllowBroadcast (true);
834  socket->SetIpRecvTtl (true);
835  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
836 
837  // Add local broadcast record to the routing table
838  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
839  m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
840  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true,
841  /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1,
842  /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
844  }
845  }
846  else
847  {
848  NS_LOG_LOGIC ("AODV does not work with more then one address per each interface. Ignore added address");
849  }
850 }
851 
852 void
854 {
855  NS_LOG_FUNCTION (this);
856  Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
857  if (socket)
858  {
860  socket->Close ();
861  m_socketAddresses.erase (socket);
862 
864  if (unicastSocket)
865  {
866  unicastSocket->Close ();
867  m_socketAddresses.erase (unicastSocket);
868  }
869 
870  Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
871  if (l3->GetNAddresses (i))
872  {
873  Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
874  // Create a socket to listen only on this interface
875  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
877  NS_ASSERT (socket != 0);
879  // Bind to any IP address so that broadcasts can be received
880  socket->BindToNetDevice (l3->GetNetDevice (i));
881  socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
882  socket->SetAllowBroadcast (true);
883  socket->SetIpRecvTtl (true);
884  m_socketAddresses.insert (std::make_pair (socket, iface));
885 
886  // create also a unicast socket
887  socket = Socket::CreateSocket (GetObject<Node> (),
889  NS_ASSERT (socket != 0);
891  socket->BindToNetDevice (l3->GetNetDevice (i));
892  socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
893  socket->SetAllowBroadcast (true);
894  socket->SetIpRecvTtl (true);
895  m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
896 
897  // Add local broadcast record to the routing table
898  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
899  RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
900  /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
902  }
903  if (m_socketAddresses.empty ())
904  {
905  NS_LOG_LOGIC ("No aodv interfaces");
906  m_htimer.Cancel ();
907  m_nb.Clear ();
909  return;
910  }
911  }
912  else
913  {
914  NS_LOG_LOGIC ("Remove address not participating in AODV operation");
915  }
916 }
917 
918 bool
920 {
921  NS_LOG_FUNCTION (this << src);
922  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
923  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
924  {
925  Ipv4InterfaceAddress iface = j->second;
926  if (src == iface.GetLocal ())
927  {
928  return true;
929  }
930  }
931  return false;
932 }
933 
936 {
937  NS_LOG_FUNCTION (this << hdr);
938  NS_ASSERT (m_lo != 0);
939  Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
940  rt->SetDestination (hdr.GetDestination ());
941  //
942  // Source address selection here is tricky. The loopback route is
943  // returned when AODV does not have a route; this causes the packet
944  // to be looped back and handled (cached) in RouteInput() method
945  // while a route is found. However, connection-oriented protocols
946  // like TCP need to create an endpoint four-tuple (src, src port,
947  // dst, dst port) and create a pseudo-header for checksumming. So,
948  // AODV needs to guess correctly what the eventual source address
949  // will be.
950  //
951  // For single interface, single address nodes, this is not a problem.
952  // When there are possibly multiple outgoing interfaces, the policy
953  // implemented here is to pick the first available AODV interface.
954  // If RouteOutput() caller specified an outgoing interface, that
955  // further constrains the selection of source address
956  //
957  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin ();
958  if (oif)
959  {
960  // Iterate to find an address on the oif device
961  for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
962  {
963  Ipv4Address addr = j->second.GetLocal ();
964  int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
965  if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
966  {
967  rt->SetSource (addr);
968  break;
969  }
970  }
971  }
972  else
973  {
974  rt->SetSource (j->second.GetLocal ());
975  }
976  NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid AODV source address not found");
977  rt->SetGateway (Ipv4Address ("127.0.0.1"));
978  rt->SetOutputDevice (m_lo);
979  return rt;
980 }
981 
982 void
984 {
985  NS_LOG_FUNCTION ( this << dst);
986  // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second.
988  {
990  &RoutingProtocol::SendRequest, this, dst);
991  return;
992  }
993  else
994  {
995  m_rreqCount++;
996  }
997  // Create RREQ header
998  RreqHeader rreqHeader;
999  rreqHeader.SetDst (dst);
1000 
1001  RoutingTableEntry rt;
1002  // Using the Hop field in Routing Table to manage the expanding ring search
1003  uint16_t ttl = m_ttlStart;
1004  if (m_routingTable.LookupRoute (dst, rt))
1005  {
1006  if (rt.GetFlag () != IN_SEARCH)
1007  {
1008  ttl = std::min<uint16_t> (rt.GetHop () + m_ttlIncrement, m_netDiameter);
1009  }
1010  else
1011  {
1012  ttl = rt.GetHop () + m_ttlIncrement;
1013  if (ttl > m_ttlThreshold)
1014  {
1015  ttl = m_netDiameter;
1016  }
1017  }
1018  if (ttl == m_netDiameter)
1019  {
1020  rt.IncrementRreqCnt ();
1021  }
1022  if (rt.GetValidSeqNo ())
1023  {
1024  rreqHeader.SetDstSeqno (rt.GetSeqNo ());
1025  }
1026  else
1027  {
1028  rreqHeader.SetUnknownSeqno (true);
1029  }
1030  rt.SetHop (ttl);
1031  rt.SetFlag (IN_SEARCH);
1033  m_routingTable.Update (rt);
1034  }
1035  else
1036  {
1037  rreqHeader.SetUnknownSeqno (true);
1038  Ptr<NetDevice> dev = 0;
1039  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ false, /*seqno=*/ 0,
1040  /*iface=*/ Ipv4InterfaceAddress (),/*hop=*/ ttl,
1041  /*nextHop=*/ Ipv4Address (), /*lifeTime=*/ m_pathDiscoveryTime);
1042  // Check if TtlStart == NetDiameter
1043  if (ttl == m_netDiameter)
1044  {
1045  newEntry.IncrementRreqCnt ();
1046  }
1047  newEntry.SetFlag (IN_SEARCH);
1048  m_routingTable.AddRoute (newEntry);
1049  }
1050 
1051  if (m_gratuitousReply)
1052  {
1053  rreqHeader.SetGratuitousRrep (true);
1054  }
1055  if (m_destinationOnly)
1056  {
1057  rreqHeader.SetDestinationOnly (true);
1058  }
1059 
1060  m_seqNo++;
1061  rreqHeader.SetOriginSeqno (m_seqNo);
1062  m_requestId++;
1063  rreqHeader.SetId (m_requestId);
1064 
1065  // Send RREQ as subnet directed broadcast from each interface used by aodv
1066  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1067  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1068  {
1069  Ptr<Socket> socket = j->first;
1070  Ipv4InterfaceAddress iface = j->second;
1071 
1072  rreqHeader.SetOrigin (iface.GetLocal ());
1074 
1075  Ptr<Packet> packet = Create<Packet> ();
1076  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1077 
1079  // ADD INTERNAL QKD COMMAND TAG
1081 
1082  QKDCommandTag qkdCommandTag;
1083  packet->RemovePacketTag(qkdCommandTag);
1084  qkdCommandTag.SetCommand ('R');
1086  packet->AddPacketTag (qkdCommandTag);
1088 
1089  SocketIpTtlTag tag;
1090  tag.SetTtl (ttl);
1091  packet->AddPacketTag (tag);
1092  packet->AddHeader (rreqHeader);
1093  TypeHeader tHeader (AODVTYPE_RREQ);
1094  packet->AddHeader (tHeader);
1095  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1096  Ipv4Address destination;
1097  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1098  {
1099  destination = Ipv4Address ("255.255.255.255");
1100  }
1101  else
1102  {
1103  destination = iface.GetBroadcast ();
1104  }
1105  NS_LOG_DEBUG ("Send RREQ with id " << rreqHeader.GetId () << " to socket");
1107  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1108  }
1109  ScheduleRreqRetry (dst);
1110 
1111  this->PrintRoutingTable (routingStream, "SendRequest");
1112 }
1113 
1114 void
1116 {
1117  socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
1118 
1119 }
1120 void
1122 {
1123  NS_LOG_FUNCTION (this << dst);
1124  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
1125  {
1127  m_addressReqTimer[dst] = timer;
1128  }
1130  m_addressReqTimer[dst].Remove ();
1131  m_addressReqTimer[dst].SetArguments (dst);
1132  RoutingTableEntry rt;
1133  m_routingTable.LookupRoute (dst, rt);
1134  Time retry;
1135  if (rt.GetHop () < m_netDiameter)
1136  {
1137  retry = 2 * m_nodeTraversalTime * (rt.GetHop () + m_timeoutBuffer);
1138  }
1139  else
1140  {
1141  NS_ABORT_MSG_UNLESS (rt.GetRreqCnt () > 0, "Unexpected value for GetRreqCount ()");
1142  uint16_t backoffFactor = rt.GetRreqCnt () - 1;
1143  NS_LOG_LOGIC ("Applying binary exponential backoff factor " << backoffFactor);
1144  retry = m_netTraversalTime * (1 << backoffFactor);
1145  }
1146  m_addressReqTimer[dst].Schedule (retry);
1147  NS_LOG_LOGIC ("Scheduled RREQ retry in " << retry.GetSeconds () << " seconds");
1148 }
1149 
1150 void
1152 {
1153  NS_LOG_FUNCTION (this << socket);
1154  Address sourceAddress;
1155  Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
1156  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
1157  Ipv4Address sender = inetSourceAddr.GetIpv4 ();
1158  Ipv4Address receiver;
1159 
1160  if (m_socketAddresses.find (socket) != m_socketAddresses.end ())
1161  {
1162  receiver = m_socketAddresses[socket].GetLocal ();
1163  }
1164  else if (m_socketSubnetBroadcastAddresses.find (socket) != m_socketSubnetBroadcastAddresses.end ())
1165  {
1166  receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal ();
1167  }
1168  else
1169  {
1170  NS_ASSERT_MSG (false, "Received a packet from an unknown socket");
1171  }
1172  NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
1173 
1174  UpdateRouteToNeighbor (sender, receiver);
1175  TypeHeader tHeader (AODVTYPE_RREQ);
1176  packet->RemoveHeader (tHeader);
1177  if (!tHeader.IsValid ())
1178  {
1179  NS_LOG_DEBUG ("AODV message " << packet->GetUid () << " with unknown type received: " << tHeader.Get () << ". Drop");
1180  return; // drop
1181  }
1182  switch (tHeader.Get ())
1183  {
1184  case AODVTYPE_RREQ:
1185  {
1186  RecvRequest (packet, receiver, sender);
1187  break;
1188  }
1189  case AODVTYPE_RREP:
1190  {
1191  RecvReply (packet, receiver, sender);
1192  break;
1193  }
1194  case AODVTYPE_RERR:
1195  {
1196  RecvError (packet, sender);
1197  break;
1198  }
1199  case AODVTYPE_RREP_ACK:
1200  {
1201  RecvReplyAck (sender);
1202  break;
1203  }
1204  }
1205  this->PrintRoutingTable (routingStream, "RecvAodv");
1206 }
1207 
1208 bool
1210 {
1211  NS_LOG_FUNCTION (this << addr << lifetime);
1212  RoutingTableEntry rt;
1213  if (m_routingTable.LookupRoute (addr, rt))
1214  {
1215  if (rt.GetFlag () == VALID)
1216  {
1217  NS_LOG_DEBUG ("Updating VALID route");
1218  rt.SetRreqCnt (0);
1219  rt.SetLifeTime (std::max (lifetime, rt.GetLifeTime ()));
1220  m_routingTable.Update (rt);
1221  return true;
1222  }
1223  }
1224  return false;
1225 }
1226 
1227 void
1229 {
1230  NS_LOG_FUNCTION (this << "sender " << sender << " receiver " << receiver);
1231  RoutingTableEntry toNeighbor;
1232  if (!m_routingTable.LookupRoute (sender, toNeighbor))
1233  {
1234  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1235  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1236  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1237  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ m_activeRouteTimeout);
1238  m_routingTable.AddRoute (newEntry);
1239  }
1240  else
1241  {
1242  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1243  if (toNeighbor.GetValidSeqNo () && (toNeighbor.GetHop () == 1) && (toNeighbor.GetOutputDevice () == dev))
1244  {
1245  toNeighbor.SetLifeTime (std::max (m_activeRouteTimeout, toNeighbor.GetLifeTime ()));
1246  }
1247  else
1248  {
1249  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ sender, /*know seqno=*/ false, /*seqno=*/ 0,
1250  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1251  /*hops=*/ 1, /*next hop=*/ sender, /*lifetime=*/ std::max (m_activeRouteTimeout, toNeighbor.GetLifeTime ()));
1252  m_routingTable.Update (newEntry);
1253  }
1254  }
1255 
1256 }
1257 
1258 void
1260 {
1261  NS_LOG_FUNCTION (this);
1262  RreqHeader rreqHeader;
1263  p->RemoveHeader (rreqHeader);
1264 
1265  // A node ignores all RREQs received from any node in its blacklist
1266  RoutingTableEntry toPrev;
1267  if (m_routingTable.LookupRoute (src, toPrev))
1268  {
1269  if (toPrev.IsUnidirectional ())
1270  {
1271  NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
1272  return;
1273  }
1274  }
1275 
1276  uint32_t id = rreqHeader.GetId ();
1277  Ipv4Address origin = rreqHeader.GetOrigin ();
1278 
1279  /*
1280  * Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
1281  * If such a RREQ has been received, the node silently discards the newly received RREQ.
1282  */
1283  if (m_rreqIdCache.IsDuplicate (origin, id))
1284  {
1285  NS_LOG_DEBUG ("Ignoring RREQ due to duplicate");
1286  return;
1287  }
1288 
1289  // Increment RREQ hop count
1290  uint8_t hop = rreqHeader.GetHopCount () + 1;
1291  rreqHeader.SetHopCount (hop);
1292 
1293  /*
1294  * When the reverse route is created or updated, the following actions on the route are also carried out:
1295  * 1. the Originator Sequence Number from the RREQ is compared to the corresponding destination sequence number
1296  * in the route table entry and copied if greater than the existing value there
1297  * 2. the valid sequence number field is set to true;
1298  * 3. the next hop in the routing table becomes the node from which the RREQ was received
1299  * 4. the hop count is copied from the Hop Count in the RREQ message;
1300  * 5. the Lifetime is set to be the maximum of (ExistingLifetime, MinimalLifetime), where
1301  * MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
1302  */
1303  RoutingTableEntry toOrigin;
1304  if (!m_routingTable.LookupRoute (origin, toOrigin))
1305  {
1306  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1307  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ origin, /*validSeno=*/ true, /*seqNo=*/ rreqHeader.GetOriginSeqno (),
1308  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0), /*hops=*/ hop,
1309  /*nextHop*/ src, /*timeLife=*/ Time ((2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime)));
1310  m_routingTable.AddRoute (newEntry);
1311  }
1312  else
1313  {
1314  if (toOrigin.GetValidSeqNo ())
1315  {
1316  if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0)
1317  {
1318  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1319  }
1320  }
1321  else
1322  {
1323  toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ());
1324  }
1325  toOrigin.SetValidSeqNo (true);
1326  toOrigin.SetNextHop (src);
1327  toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1328  toOrigin.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1329  toOrigin.SetHop (hop);
1330  toOrigin.SetLifeTime (std::max (Time (2 * m_netTraversalTime - 2 * hop * m_nodeTraversalTime),
1331  toOrigin.GetLifeTime ()));
1332  m_routingTable.Update (toOrigin);
1333  //m_nb.Update (src, Time (AllowedHelloLoss * HelloInterval));
1334  }
1335 
1336 
1337  RoutingTableEntry toNeighbor;
1338  if (!m_routingTable.LookupRoute (src, toNeighbor))
1339  {
1340  NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
1341  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1342  RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (),
1343  m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1344  1, src, m_activeRouteTimeout);
1345  m_routingTable.AddRoute (newEntry);
1346  }
1347  else
1348  {
1349  toNeighbor.SetLifeTime (m_activeRouteTimeout);
1350  toNeighbor.SetValidSeqNo (false);
1351  toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
1352  toNeighbor.SetFlag (VALID);
1353  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1354  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1355  toNeighbor.SetHop (1);
1356  toNeighbor.SetNextHop (src);
1357  m_routingTable.Update (toNeighbor);
1358  }
1360 
1361  NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast<uint32_t> (rreqHeader.GetHopCount ())
1362  << " ID " << rreqHeader.GetId ()
1363  << " to destination " << rreqHeader.GetDst ());
1364 
1365  // A node generates a RREP if either:
1366  // (i) it is itself the destination,
1367  if (IsMyOwnAddress (rreqHeader.GetDst ()))
1368  {
1369  m_routingTable.LookupRoute (origin, toOrigin);
1370  NS_LOG_DEBUG ("Send reply since I am the destination");
1371  SendReply (rreqHeader, toOrigin);
1372  return;
1373  }
1374  /*
1375  * (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
1376  * is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
1377  */
1378  RoutingTableEntry toDst;
1379  Ipv4Address dst = rreqHeader.GetDst ();
1380  if (m_routingTable.LookupRoute (dst, toDst))
1381  {
1382  /*
1383  * Drop RREQ, This node RREP will make a loop.
1384  */
1385  if (toDst.GetNextHop () == src)
1386  {
1387  NS_LOG_DEBUG ("Drop RREQ from " << src << ", dest next hop " << toDst.GetNextHop ());
1388  return;
1389  }
1390  /*
1391  * The Destination Sequence number for the requested destination is set to the maximum of the corresponding value
1392  * received in the RREQ message, and the destination sequence value currently maintained by the node for the requested destination.
1393  * However, the forwarding node MUST NOT modify its maintained value for the destination sequence number, even if the value
1394  * received in the incoming RREQ is larger than the value currently maintained by the forwarding node.
1395  */
1396  if ((rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) >= 0))
1397  && toDst.GetValidSeqNo () )
1398  {
1399  if (!rreqHeader.GetDestinationOnly () && toDst.GetFlag () == VALID)
1400  {
1401  m_routingTable.LookupRoute (origin, toOrigin);
1402  SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratuitousRrep ());
1403  return;
1404  }
1405  rreqHeader.SetDstSeqno (toDst.GetSeqNo ());
1406  rreqHeader.SetUnknownSeqno (false);
1407  }
1408  }
1409 
1410  SocketIpTtlTag tag;
1411  p->RemovePacketTag (tag);
1412  if (tag.GetTtl () < 2)
1413  {
1414  NS_LOG_DEBUG ("TTL exceeded. Drop RREQ origin " << src << " destination " << dst );
1415  return;
1416  }
1417 
1418  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
1419  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1420  {
1421  Ptr<Socket> socket = j->first;
1422  Ipv4InterfaceAddress iface = j->second;
1423  Ptr<Packet> packet = Create<Packet> ();
1424  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1425 
1427  // ADD INTERNAL QKD COMMAND TAG
1429 
1430  QKDCommandTag qkdCommandTag;
1431  packet->RemovePacketTag(qkdCommandTag);
1432  qkdCommandTag.SetCommand ('R');
1434  packet->AddPacketTag (qkdCommandTag);
1436 
1437  SocketIpTtlTag ttl;
1438  ttl.SetTtl (tag.GetTtl () - 1);
1439  packet->AddPacketTag (ttl);
1440  packet->AddHeader (rreqHeader);
1441  TypeHeader tHeader (AODVTYPE_RREQ);
1442  packet->AddHeader (tHeader);
1443  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
1444  Ipv4Address destination;
1445  if (iface.GetMask () == Ipv4Mask::GetOnes ())
1446  {
1447  destination = Ipv4Address ("255.255.255.255");
1448  }
1449  else
1450  {
1451  destination = iface.GetBroadcast ();
1452  }
1454  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
1455 
1456  }
1457 }
1458 
1459 void
1460 RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin)
1461 {
1462  NS_LOG_FUNCTION (this << toOrigin.GetDestination ());
1463  /*
1464  * Destination node MUST increment its own sequence number by one if the sequence number in the RREQ packet is equal to that
1465  * incremented value. Otherwise, the destination does not change its sequence number before generating the RREP message.
1466  */
1467  if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1))
1468  {
1469  m_seqNo++;
1470  }
1471  RrepHeader rrepHeader ( /*prefixSize=*/ 0, /*hops=*/ 0, /*dst=*/ rreqHeader.GetDst (),
1472  /*dstSeqNo=*/ m_seqNo, /*origin=*/ toOrigin.GetDestination (), /*lifeTime=*/ m_myRouteTimeout);
1473  Ptr<Packet> packet = Create<Packet> ();
1474  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1475 
1477  // ADD INTERNAL QKD COMMAND TAG
1479 
1480  QKDCommandTag qkdCommandTag;
1481  packet->RemovePacketTag(qkdCommandTag);
1482  qkdCommandTag.SetCommand ('R');
1484  packet->AddPacketTag (qkdCommandTag);
1486 
1487  SocketIpTtlTag tag;
1488  tag.SetTtl (toOrigin.GetHop ());
1489  packet->AddPacketTag (tag);
1490  packet->AddHeader (rrepHeader);
1491  TypeHeader tHeader (AODVTYPE_RREP);
1492  packet->AddHeader (tHeader);
1494  NS_ASSERT (socket);
1495  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1496 }
1497 
1498 void
1500 {
1501  NS_LOG_FUNCTION (this);
1502  RrepHeader rrepHeader (/*prefix size=*/ 0, /*hops=*/ toDst.GetHop (), /*dst=*/ toDst.GetDestination (), /*dst seqno=*/ toDst.GetSeqNo (),
1503  /*origin=*/ toOrigin.GetDestination (), /*lifetime=*/ toDst.GetLifeTime ());
1504  /* If the node we received a RREQ for is a neighbor we are
1505  * probably facing a unidirectional link... Better request a RREP-ack
1506  */
1507  if (toDst.GetHop () == 1)
1508  {
1509  rrepHeader.SetAckRequired (true);
1510  RoutingTableEntry toNextHop;
1511  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHop);
1513  toNextHop.m_ackTimer.SetArguments (toNextHop.GetDestination (), m_blackListTimeout);
1514  toNextHop.m_ackTimer.SetDelay (m_nextHopWait);
1515  }
1516  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1517  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1518  m_routingTable.Update (toDst);
1519  m_routingTable.Update (toOrigin);
1520 
1521  Ptr<Packet> packet = Create<Packet> ();
1522  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1523 
1525  // ADD INTERNAL QKD COMMAND TAG
1527 
1528  QKDCommandTag qkdCommandTag;
1529  packet->RemovePacketTag(qkdCommandTag);
1530  qkdCommandTag.SetCommand ('R');
1532  packet->AddPacketTag (qkdCommandTag);
1534 
1535  SocketIpTtlTag tag;
1536  tag.SetTtl (toOrigin.GetHop ());
1537  packet->AddPacketTag (tag);
1538  packet->AddHeader (rrepHeader);
1539  TypeHeader tHeader (AODVTYPE_RREP);
1540  packet->AddHeader (tHeader);
1542  NS_ASSERT (socket);
1543  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1544 
1545  // Generating gratuitous RREPs
1546  if (gratRep)
1547  {
1548  RrepHeader gratRepHeader (/*prefix size=*/ 0, /*hops=*/ toOrigin.GetHop (), /*dst=*/ toOrigin.GetDestination (),
1549  /*dst seqno=*/ toOrigin.GetSeqNo (), /*origin=*/ toDst.GetDestination (),
1550  /*lifetime=*/ toOrigin.GetLifeTime ());
1551  Ptr<Packet> packetToDst = Create<Packet> ();
1552  packetToDst = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packetToDst);
1553 
1555  // ADD INTERNAL QKD COMMAND TAG
1557 
1558  QKDCommandTag qkdCommandTag;
1559  packetToDst->RemovePacketTag(qkdCommandTag);
1560  qkdCommandTag.SetCommand ('R');
1562  packetToDst->AddPacketTag (qkdCommandTag);
1564 
1565  SocketIpTtlTag gratTag;
1566  gratTag.SetTtl (toDst.GetHop ());
1567  packetToDst->AddPacketTag (gratTag);
1568  packetToDst->AddHeader (gratRepHeader);
1569  TypeHeader type (AODVTYPE_RREP);
1570  packetToDst->AddHeader (type);
1572  NS_ASSERT (socket);
1573  NS_LOG_LOGIC ("Send gratuitous RREP " << packet->GetUid ());
1574  socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetNextHop (), AODV_PORT));
1575  }
1576 }
1577 
1578 void
1580 {
1581  NS_LOG_FUNCTION (this << " to " << neighbor);
1582  RrepAckHeader h;
1583  TypeHeader typeHeader (AODVTYPE_RREP_ACK);
1584  Ptr<Packet> packet = Create<Packet> ();
1585  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1586 
1588  // ADD INTERNAL QKD COMMAND TAG
1590 
1591  QKDCommandTag qkdCommandTag;
1592  packet->RemovePacketTag(qkdCommandTag);
1593  qkdCommandTag.SetCommand ('R');
1595  packet->AddPacketTag (qkdCommandTag);
1597 
1598  SocketIpTtlTag tag;
1599  tag.SetTtl (1);
1600  packet->AddPacketTag (tag);
1601  packet->AddHeader (h);
1602  packet->AddHeader (typeHeader);
1603  RoutingTableEntry toNeighbor;
1604  m_routingTable.LookupRoute (neighbor, toNeighbor);
1605  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toNeighbor.GetInterface ());
1606  NS_ASSERT (socket);
1607  socket->SendTo (packet, 0, InetSocketAddress (neighbor, AODV_PORT));
1608 }
1609 
1610 void
1612 {
1613  NS_LOG_FUNCTION (this << " src " << sender);
1614  RrepHeader rrepHeader;
1615  p->RemoveHeader (rrepHeader);
1616  Ipv4Address dst = rrepHeader.GetDst ();
1617  NS_LOG_LOGIC ("RREP destination " << dst << " RREP origin " << rrepHeader.GetOrigin ());
1618 
1619  uint8_t hop = rrepHeader.GetHopCount () + 1;
1620  rrepHeader.SetHopCount (hop);
1621 
1622  // If RREP is Hello message
1623  if (dst == rrepHeader.GetOrigin ())
1624  {
1625  ProcessHello (rrepHeader, receiver);
1626  return;
1627  }
1628 
1629  /*
1630  * If the route table entry to the destination is created or updated, then the following actions occur:
1631  * - the route is marked as active,
1632  * - the destination sequence number is marked as valid,
1633  * - the next hop in the route entry is assigned to be the node from which the RREP is received,
1634  * which is indicated by the source IP address field in the IP header,
1635  * - the hop count is set to the value of the hop count from RREP message + 1
1636  * - the expiry time is set to the current time plus the value of the Lifetime in the RREP message,
1637  * - and the destination sequence number is the Destination Sequence Number in the RREP message.
1638  */
1639  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1640  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ dst, /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1641  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),/*hop=*/ hop,
1642  /*nextHop=*/ sender, /*lifeTime=*/ rrepHeader.GetLifeTime ());
1643  RoutingTableEntry toDst;
1644  if (m_routingTable.LookupRoute (dst, toDst))
1645  {
1646  /*
1647  * The existing entry is updated only in the following circumstances:
1648  * (i) the sequence number in the routing table is marked as invalid in route table entry.
1649  */
1650  if (!toDst.GetValidSeqNo ())
1651  {
1652  m_routingTable.Update (newEntry);
1653  }
1654  // (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,
1655  else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0)
1656  {
1657  m_routingTable.Update (newEntry);
1658  }
1659  else
1660  {
1661  // (iii) the sequence numbers are the same, but the route is marked as inactive.
1662  if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != VALID))
1663  {
1664  m_routingTable.Update (newEntry);
1665  }
1666  // (iv) the sequence numbers are the same, and the New Hop Count is smaller than the hop count in route table entry.
1667  else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ()))
1668  {
1669  m_routingTable.Update (newEntry);
1670  }
1671  }
1672  }
1673  else
1674  {
1675  // The forward route for this destination is created if it does not already exist.
1676  NS_LOG_LOGIC ("add new route");
1677  m_routingTable.AddRoute (newEntry);
1678  }
1679  // Acknowledge receipt of the RREP by sending a RREP-ACK message back
1680  if (rrepHeader.GetAckRequired ())
1681  {
1682  SendReplyAck (sender);
1683  rrepHeader.SetAckRequired (false);
1684  }
1685  NS_LOG_LOGIC ("receiver " << receiver << " origin " << rrepHeader.GetOrigin ());
1686  if (IsMyOwnAddress (rrepHeader.GetOrigin ()))
1687  {
1688  if (toDst.GetFlag () == IN_SEARCH)
1689  {
1690  m_routingTable.Update (newEntry);
1691  m_addressReqTimer[dst].Remove ();
1692  m_addressReqTimer.erase (dst);
1693  }
1694  m_routingTable.LookupRoute (dst, toDst);
1695  SendPacketFromQueue (dst, toDst.GetRoute ());
1696  return;
1697  }
1698 
1699  RoutingTableEntry toOrigin;
1700  if (!m_routingTable.LookupRoute (rrepHeader.GetOrigin (), toOrigin) || toOrigin.GetFlag () == IN_SEARCH)
1701  {
1702  return; // Impossible! drop.
1703  }
1704  toOrigin.SetLifeTime (std::max (m_activeRouteTimeout, toOrigin.GetLifeTime ()));
1705  m_routingTable.Update (toOrigin);
1706 
1707  // Update information about precursors
1708  if (m_routingTable.LookupValidRoute (rrepHeader.GetDst (), toDst))
1709  {
1710  toDst.InsertPrecursor (toOrigin.GetNextHop ());
1711  m_routingTable.Update (toDst);
1712 
1713  RoutingTableEntry toNextHopToDst;
1714  m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
1715  toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
1716  m_routingTable.Update (toNextHopToDst);
1717 
1718  toOrigin.InsertPrecursor (toDst.GetNextHop ());
1719  m_routingTable.Update (toOrigin);
1720 
1721  RoutingTableEntry toNextHopToOrigin;
1722  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
1723  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
1724  m_routingTable.Update (toNextHopToOrigin);
1725  }
1726  SocketIpTtlTag tag;
1727  p->RemovePacketTag (tag);
1728  if (tag.GetTtl () < 2)
1729  {
1730  NS_LOG_DEBUG ("TTL exceeded. Drop RREP destination " << dst << " origin " << rrepHeader.GetOrigin ());
1731  return;
1732  }
1733 
1734  Ptr<Packet> packet = Create<Packet> ();
1735  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1736 
1738  // ADD INTERNAL QKD COMMAND TAG
1740 
1741  QKDCommandTag qkdCommandTag;
1742  packet->RemovePacketTag(qkdCommandTag);
1743  qkdCommandTag.SetCommand ('R');
1745  packet->AddPacketTag (qkdCommandTag);
1747 
1748  SocketIpTtlTag ttl;
1749  ttl.SetTtl (tag.GetTtl () - 1);
1750  packet->AddPacketTag (ttl);
1751  packet->AddHeader (rrepHeader);
1752  TypeHeader tHeader (AODVTYPE_RREP);
1753  packet->AddHeader (tHeader);
1755  NS_ASSERT (socket);
1756  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
1757 }
1758 
1759 void
1761 {
1762  NS_LOG_FUNCTION (this);
1763  RoutingTableEntry rt;
1764  if (m_routingTable.LookupRoute (neighbor, rt))
1765  {
1766  rt.m_ackTimer.Cancel ();
1767  rt.SetFlag (VALID);
1768  m_routingTable.Update (rt);
1769  }
1770 }
1771 
1772 void
1774 {
1775  NS_LOG_FUNCTION (this << "from " << rrepHeader.GetDst ());
1776  /*
1777  * Whenever a node receives a Hello message from a neighbor, the node
1778  * SHOULD make sure that it has an active route to the neighbor, and
1779  * create one if necessary.
1780  */
1781  RoutingTableEntry toNeighbor;
1782  if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor))
1783  {
1784  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
1785  RoutingTableEntry newEntry (/*device=*/ dev, /*dst=*/ rrepHeader.GetDst (), /*validSeqNo=*/ true, /*seqno=*/ rrepHeader.GetDstSeqno (),
1786  /*iface=*/ m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1787  /*hop=*/ 1, /*nextHop=*/ rrepHeader.GetDst (), /*lifeTime=*/ rrepHeader.GetLifeTime ());
1788  m_routingTable.AddRoute (newEntry);
1789  }
1790  else
1791  {
1792  toNeighbor.SetLifeTime (std::max (Time (m_allowedHelloLoss * m_helloInterval), toNeighbor.GetLifeTime ()));
1793  toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ());
1794  toNeighbor.SetValidSeqNo (true);
1795  toNeighbor.SetFlag (VALID);
1796  toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
1797  toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
1798  toNeighbor.SetHop (1);
1799  toNeighbor.SetNextHop (rrepHeader.GetDst ());
1800  m_routingTable.Update (toNeighbor);
1801  }
1802  if (m_enableHello)
1803  {
1805  }
1806 }
1807 
1808 void
1810 {
1811  NS_LOG_FUNCTION (this << " from " << src);
1812  RerrHeader rerrHeader;
1813  p->RemoveHeader (rerrHeader);
1814  std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
1815  std::map<Ipv4Address, uint32_t> unreachable;
1816  m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
1817  std::pair<Ipv4Address, uint32_t> un;
1818  while (rerrHeader.RemoveUnDestination (un))
1819  {
1820  for (std::map<Ipv4Address, uint32_t>::const_iterator i =
1821  dstWithNextHopSrc.begin (); i != dstWithNextHopSrc.end (); ++i)
1822  {
1823  if (i->first == un.first)
1824  {
1825  unreachable.insert (un);
1826  }
1827  }
1828  }
1829 
1830  std::vector<Ipv4Address> precursors;
1831  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin ();
1832  i != unreachable.end (); )
1833  {
1834  if (!rerrHeader.AddUnDestination (i->first, i->second))
1835  {
1836  TypeHeader typeHeader (AODVTYPE_RERR);
1837  Ptr<Packet> packet = Create<Packet> ();
1838  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1839 
1841  // ADD INTERNAL QKD COMMAND TAG
1843 
1844  QKDCommandTag qkdCommandTag;
1845  packet->RemovePacketTag(qkdCommandTag);
1846  qkdCommandTag.SetCommand ('R');
1848  packet->AddPacketTag (qkdCommandTag);
1850 
1851  SocketIpTtlTag tag;
1852  tag.SetTtl (1);
1853  packet->AddPacketTag (tag);
1854  packet->AddHeader (rerrHeader);
1855  packet->AddHeader (typeHeader);
1856  SendRerrMessage (packet, precursors);
1857  rerrHeader.Clear ();
1858  }
1859  else
1860  {
1861  RoutingTableEntry toDst;
1862  m_routingTable.LookupRoute (i->first, toDst);
1863  toDst.GetPrecursors (precursors);
1864  ++i;
1865  }
1866  }
1867  if (rerrHeader.GetDestCount () != 0)
1868  {
1869  TypeHeader typeHeader (AODVTYPE_RERR);
1870  Ptr<Packet> packet = Create<Packet> ();
1871  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1872 
1874  // ADD INTERNAL QKD COMMAND TAG
1876 
1877  QKDCommandTag qkdCommandTag;
1878  packet->RemovePacketTag(qkdCommandTag);
1879  qkdCommandTag.SetCommand ('R');
1881  packet->AddPacketTag (qkdCommandTag);
1883 
1884  SocketIpTtlTag tag;
1885  tag.SetTtl (1);
1886  packet->AddPacketTag (tag);
1887  packet->AddHeader (rerrHeader);
1888  packet->AddHeader (typeHeader);
1889  SendRerrMessage (packet, precursors);
1890  }
1892 }
1893 
1894 void
1896 {
1897  NS_LOG_LOGIC (this);
1898  RoutingTableEntry toDst;
1899  if (m_routingTable.LookupValidRoute (dst, toDst))
1900  {
1901  SendPacketFromQueue (dst, toDst.GetRoute ());
1902  NS_LOG_LOGIC ("route to " << dst << " found");
1903  return;
1904  }
1905  /*
1906  * If a route discovery has been attempted RreqRetries times at the maximum TTL without
1907  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
1908  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
1909  */
1910  if (toDst.GetRreqCnt () == m_rreqRetries)
1911  {
1912  NS_LOG_LOGIC ("route discovery to " << dst << " has been attempted RreqRetries (" << m_rreqRetries << ") times with ttl " << m_netDiameter);
1913  m_addressReqTimer.erase (dst);
1915  NS_LOG_DEBUG ("Route not found. Drop all packets with dst " << dst);
1916  m_queue.DropPacketWithDst (dst);
1917  return;
1918  }
1919 
1920  if (toDst.GetFlag () == IN_SEARCH)
1921  {
1922  NS_LOG_LOGIC ("Resend RREQ to " << dst << " previous ttl " << toDst.GetHop ());
1923  SendRequest (dst);
1924  }
1925  else
1926  {
1927  NS_LOG_DEBUG ("Route down. Stop search. Drop packet with destination " << dst);
1928  m_addressReqTimer.erase (dst);
1930  m_queue.DropPacketWithDst (dst);
1931  }
1932 }
1933 
1934 void
1936 {
1937  NS_LOG_FUNCTION (this);
1938  Time offset = Time (Seconds (0));
1939  if (m_lastBcastTime > Time (Seconds (0)))
1940  {
1941  offset = Simulator::Now () - m_lastBcastTime;
1942  NS_LOG_DEBUG ("Hello deferred due to last bcast at:" << m_lastBcastTime);
1943  }
1944  else
1945  {
1946  SendHello ();
1947  }
1948  m_htimer.Cancel ();
1949  Time diff = m_helloInterval - offset;
1950  m_htimer.Schedule (std::max (Time (Seconds (0)), diff));
1951  m_lastBcastTime = Time (Seconds (0));
1952 }
1953 
1954 void
1956 {
1957  NS_LOG_FUNCTION (this);
1958  m_rreqCount = 0;
1960 }
1961 
1962 void
1964 {
1965  NS_LOG_FUNCTION (this);
1966  m_rerrCount = 0;
1968 }
1969 
1970 void
1972 {
1973  NS_LOG_FUNCTION (this);
1974  m_routingTable.MarkLinkAsUnidirectional (neighbor, blacklistTimeout);
1975 }
1976 
1977 void
1979 {
1980  NS_LOG_FUNCTION (this);
1981  /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows:
1982  * Destination IP Address The node's IP address.
1983  * Destination Sequence Number The node's latest sequence number.
1984  * Hop Count 0
1985  * Lifetime AllowedHelloLoss * HelloInterval
1986  */
1987  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
1988  {
1989  Ptr<Socket> socket = j->first;
1990  Ipv4InterfaceAddress iface = j->second;
1991  RrepHeader helloHeader (/*prefix size=*/ 0, /*hops=*/ 0, /*dst=*/ iface.GetLocal (), /*dst seqno=*/ m_seqNo,
1992  /*origin=*/ iface.GetLocal (),/*lifetime=*/ Time (m_allowedHelloLoss * m_helloInterval));
1993  Ptr<Packet> packet = Create<Packet> ();
1994  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
1995 
1997  // ADD INTERNAL QKD COMMAND TAG
1999 
2000  QKDCommandTag qkdCommandTag;
2001  packet->RemovePacketTag(qkdCommandTag);
2002  qkdCommandTag.SetCommand ('R');
2004  packet->AddPacketTag (qkdCommandTag);
2006 
2007  SocketIpTtlTag tag;
2008  tag.SetTtl (1);
2009  packet->AddPacketTag (tag);
2010  packet->AddHeader (helloHeader);
2011  TypeHeader tHeader (AODVTYPE_RREP);
2012  packet->AddHeader (tHeader);
2013  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2014  Ipv4Address destination;
2015  if (iface.GetMask () == Ipv4Mask::GetOnes ())
2016  {
2017  destination = Ipv4Address ("255.255.255.255");
2018  }
2019  else
2020  {
2021  destination = iface.GetBroadcast ();
2022  }
2024  Simulator::Schedule (jitter, &RoutingProtocol::SendTo, this, socket, packet, destination);
2025  }
2026 }
2027 
2028 void
2030 {
2031  NS_LOG_FUNCTION (this);
2032  QueueEntry queueEntry;
2033  while (m_queue.Dequeue (dst, queueEntry))
2034  {
2036  Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
2037  if (p->RemovePacketTag (tag)
2038  && tag.GetInterface () != -1
2039  && tag.GetInterface () != m_ipv4->GetInterfaceForDevice (route->GetOutputDevice ()))
2040  {
2041  NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
2042  return;
2043  }
2045  Ipv4Header header = queueEntry.GetIpv4Header ();
2046  header.SetSource (route->GetSource ());
2047  header.SetTtl (header.GetTtl () + 1); // compensate extra TTL decrement by fake loopback routing
2048  ucb (route, p, header);
2049  }
2050 }
2051 
2052 void
2054 {
2055  NS_LOG_FUNCTION (this << nextHop);
2056  RerrHeader rerrHeader;
2057  std::vector<Ipv4Address> precursors;
2058  std::map<Ipv4Address, uint32_t> unreachable;
2059 
2060  RoutingTableEntry toNextHop;
2061  if (!m_routingTable.LookupRoute (nextHop, toNextHop))
2062  {
2063  return;
2064  }
2065  toNextHop.GetPrecursors (precursors);
2066  rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
2067  m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
2068  for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i
2069  != unreachable.end (); )
2070  {
2071  if (!rerrHeader.AddUnDestination (i->first, i->second))
2072  {
2073  NS_LOG_LOGIC ("Send RERR message with maximum size.");
2074  TypeHeader typeHeader (AODVTYPE_RERR);
2075  Ptr<Packet> packet = Create<Packet> ();
2076  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
2077 
2079  // ADD INTERNAL QKD COMMAND TAG
2081 
2082  QKDCommandTag qkdCommandTag;
2083  packet->RemovePacketTag(qkdCommandTag);
2084  qkdCommandTag.SetCommand ('R');
2086  packet->AddPacketTag (qkdCommandTag);
2088 
2089  SocketIpTtlTag tag;
2090  tag.SetTtl (1);
2091  packet->AddPacketTag (tag);
2092  packet->AddHeader (rerrHeader);
2093  packet->AddHeader (typeHeader);
2094  SendRerrMessage (packet, precursors);
2095  rerrHeader.Clear ();
2096  }
2097  else
2098  {
2099  RoutingTableEntry toDst;
2100  m_routingTable.LookupRoute (i->first, toDst);
2101  toDst.GetPrecursors (precursors);
2102  ++i;
2103  }
2104  }
2105  if (rerrHeader.GetDestCount () != 0)
2106  {
2107  TypeHeader typeHeader (AODVTYPE_RERR);
2108  Ptr<Packet> packet = Create<Packet> ();
2109  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
2110 
2112  // ADD INTERNAL QKD COMMAND TAG
2114 
2115  QKDCommandTag qkdCommandTag;
2116  packet->RemovePacketTag(qkdCommandTag);
2117  qkdCommandTag.SetCommand ('R');
2119  packet->AddPacketTag (qkdCommandTag);
2121 
2122  SocketIpTtlTag tag;
2123  tag.SetTtl (1);
2124  packet->AddPacketTag (tag);
2125  packet->AddHeader (rerrHeader);
2126  packet->AddHeader (typeHeader);
2127  SendRerrMessage (packet, precursors);
2128  }
2129  unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
2131 }
2132 
2133 void
2135  uint32_t dstSeqNo, Ipv4Address origin)
2136 {
2137  NS_LOG_FUNCTION (this);
2138  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2140  {
2141  // Just make sure that the RerrRateLimit timer is running and will expire
2143  // discard the packet and return
2144  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
2146  << "; suppressing RERR");
2147  return;
2148  }
2149  RerrHeader rerrHeader;
2150  rerrHeader.AddUnDestination (dst, dstSeqNo);
2151  RoutingTableEntry toOrigin;
2152  Ptr<Packet> packet = Create<Packet> ();
2153  packet = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (packet);
2154 
2156  // ADD INTERNAL QKD COMMAND TAG
2158 
2159  QKDCommandTag qkdCommandTag;
2160  packet->RemovePacketTag(qkdCommandTag);
2161  qkdCommandTag.SetCommand ('R');
2163  packet->AddPacketTag (qkdCommandTag);
2165 
2166  SocketIpTtlTag tag;
2167  tag.SetTtl (1);
2168  packet->AddPacketTag (tag);
2169  packet->AddHeader (rerrHeader);
2170  packet->AddHeader (TypeHeader (AODVTYPE_RERR));
2171  if (m_routingTable.LookupValidRoute (origin, toOrigin))
2172  {
2174  toOrigin.GetInterface ());
2175  NS_ASSERT (socket);
2176  NS_LOG_LOGIC ("Unicast RERR to the source of the data transmission");
2177  socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT));
2178  }
2179  else
2180  {
2181  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
2182  m_socketAddresses.begin (); i != m_socketAddresses.end (); ++i)
2183  {
2184  Ptr<Socket> socket = i->first;
2185  Ipv4InterfaceAddress iface = i->second;
2186  NS_ASSERT (socket);
2187  NS_LOG_LOGIC ("Broadcast RERR message from interface " << iface.GetLocal ());
2188  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2189  Ipv4Address destination;
2190  if (iface.GetMask () == Ipv4Mask::GetOnes ())
2191  {
2192  destination = Ipv4Address ("255.255.255.255");
2193  }
2194  else
2195  {
2196  destination = iface.GetBroadcast ();
2197  }
2198  socket->SendTo (packet->Copy (), 0, InetSocketAddress (destination, AODV_PORT));
2199  }
2200  }
2201 }
2202 
2203 void
2204 RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors)
2205 {
2206  NS_LOG_FUNCTION (this);
2207 
2208  if (precursors.empty ())
2209  {
2210  NS_LOG_LOGIC ("No precursors");
2211  return;
2212  }
2213  // A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
2215  {
2216  // Just make sure that the RerrRateLimit timer is running and will expire
2218  // discard the packet and return
2219  NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
2221  << "; suppressing RERR");
2222  return;
2223  }
2224  // If there is only one precursor, RERR SHOULD be unicast toward that precursor
2225  if (precursors.size () == 1)
2226  {
2227  RoutingTableEntry toPrecursor;
2228  if (m_routingTable.LookupValidRoute (precursors.front (), toPrecursor))
2229  {
2230  Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
2231  NS_ASSERT (socket);
2232  NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination () << " from " << toPrecursor.GetInterface ().GetLocal ());
2233  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, precursors.front ());
2234  m_rerrCount++;
2235  }
2236  return;
2237  }
2238 
2239  // Should only transmit RERR on those interfaces which have precursor nodes for the broken route
2240  std::vector<Ipv4InterfaceAddress> ifaces;
2241  RoutingTableEntry toPrecursor;
2242  for (std::vector<Ipv4Address>::const_iterator i = precursors.begin (); i != precursors.end (); ++i)
2243  {
2244  if (m_routingTable.LookupValidRoute (*i, toPrecursor)
2245  && std::find (ifaces.begin (), ifaces.end (), toPrecursor.GetInterface ()) == ifaces.end ())
2246  {
2247  ifaces.push_back (toPrecursor.GetInterface ());
2248  }
2249  }
2250 
2251  for (std::vector<Ipv4InterfaceAddress>::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i)
2252  {
2254  NS_ASSERT (socket);
2255  NS_LOG_LOGIC ("Broadcast RERR message from interface " << i->GetLocal ());
2256  // std::cout << "Broadcast RERR message from interface " << i->GetLocal () << std::endl;
2257  // Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
2258  Ptr<Packet> p = packet->Copy ();
2259  p = m_ipv4->GetObject<Node> ()->GetObject<QKDManager> ()->MarkEncrypt (p);
2260 
2262  // ADD INTERNAL QKD COMMAND TAG
2264 
2265  QKDCommandTag qkdCommandTag;
2266  p->RemovePacketTag(qkdCommandTag);
2267  qkdCommandTag.SetCommand ('R');
2269  p->AddPacketTag (qkdCommandTag);
2271 
2272  Ipv4Address destination;
2273  if (i->GetMask () == Ipv4Mask::GetOnes ())
2274  {
2275  destination = Ipv4Address ("255.255.255.255");
2276  }
2277  else
2278  {
2279  destination = i->GetBroadcast ();
2280  }
2281  Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, p, destination);
2282  }
2283 }
2284 
2287 {
2288  NS_LOG_FUNCTION (this << addr);
2289  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
2290  m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
2291  {
2292  Ptr<Socket> socket = j->first;
2293  Ipv4InterfaceAddress iface = j->second;
2294  if (iface == addr)
2295  {
2296  return socket;
2297  }
2298  }
2299  Ptr<Socket> socket;
2300  return socket;
2301 }
2302 
2305 {
2306  NS_LOG_FUNCTION (this << addr);
2307  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
2309  {
2310  Ptr<Socket> socket = j->first;
2311  Ipv4InterfaceAddress iface = j->second;
2312  if (iface == addr)
2313  {
2314  return socket;
2315  }
2316  }
2317  Ptr<Socket> socket;
2318  return socket;
2319 }
2320 
2321 void
2323 {
2324  NS_LOG_FUNCTION (this);
2325  uint32_t startTime;
2326  if (m_enableHello)
2327  {
2329  startTime = m_uniformRandomVariable->GetInteger (0, 100);
2330  NS_LOG_DEBUG ("Starting at time " << startTime << "ms");
2331  m_htimer.Schedule (MilliSeconds (startTime));
2332  }
2334 }
2335 
2336 } //namespace aodv
2337 } //namespace ns3
Time m_activeRouteTimeout
Period of time during which the route is considered to be valid.
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
UnicastForwardCallback GetUnicastForwardCallback() const
Get unicast forward callback.
Definition: aodv-rqueue.h:85
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
static TypeId GetTypeId(void)
Get the type ID.
void SendReplyAck(Ipv4Address neighbor)
Send RREP_ACK.
Time m_netTraversalTime
Estimate of the average net traversal time.
static Ipv4Mask GetOnes(void)
void InvalidateRoutesWithDst(std::map< Ipv4Address, uint32_t > const &unreachable)
Update routing entries with this destination as follows:
Definition: aodv-rtable.cc:331
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
bool MarkLinkAsUnidirectional(Ipv4Address neighbor, Time blacklistTimeout)
Mark entry as unidirectional (e.g.
Definition: aodv-rtable.cc:449
an Inet address class
Ipv4Address GetIpv4(void) const
void SetOutputDevice(Ptr< NetDevice > dev)
Set output device.
Definition: aodv-rtable.h:165
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
uint16_t m_rreqCount
Number of RREQs used for RREQ rate control.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Ipv4Mask GetMask(void) const
Get the network mask.
Callback template class.
Definition: callback.h:1176
bool m_enableBroadcast
Indicates whether a a broadcast data packets forwarding enable.
bool GetUnknownSeqno() const
Get the unknown sequence number flag.
Definition: aodv-packet.cc:281
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: aodv-rtable.cc:214
void Clear()
Delete all entries from routing table.
Definition: aodv-rtable.h:468
void SendTo(Ptr< Socket > socket, Ptr< Packet > packet, Ipv4Address destination)
Send packet to destination scoket.
RoutingTable m_routingTable
Routing table.
A simple Timer class.
Definition: timer.h:73
Ipv4Header GetIpv4Header() const
Get IPv4 header.
Definition: aodv-rqueue.h:133
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void SetId(uint32_t id)
Set the request ID.
Definition: aodv-packet.h:188
bool GetAckRequired() const
get the ack required flag
Definition: aodv-packet.cc:405
Ipv4Address GetLocal(void) const
Get the local address.
bool GetBroadcastEnable() const
Get broadcast enable flag.
Hold variables of type string.
Definition: string.h:41
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
Route Error (RERR) Message Format.
Definition: aodv-packet.h:562
Time m_nodeTraversalTime
NodeTraversalTime is a conservative estimate of the average one hop traversal time for packets and sh...
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
void SetRoutingProtocolNumber(uint32_t value)
Time m_deletePeriod
DeletePeriod is intended to provide an upper bound on the time for which an upstream node A can have ...
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
Routing table entry.
Definition: aodv-rtable.h:59
Tag used by AODV implementation.
void SetCommand(char value)
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:852
Ptr< Ipv4 > m_ipv4
IP protocol.
bool Update(RoutingTableEntry &rt)
Update routing table.
Definition: aodv-rtable.cc:277
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
Timer m_ackTimer
RREP_ACK timer.
Definition: aodv-rtable.h:329
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
uint32_t m_maxQueueLen
The maximum number of packets that we allow a routing protocol to buffer.
void IncrementRreqCnt()
Increment the RREQ count.
Definition: aodv-rtable.h:292
bool Forwarding(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
If route exists and is valid, forward packet.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
Time m_helloInterval
Every HelloInterval the node checks whether it has sent a broadcast within the last HelloInterval...
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
Definition: aodv-rqueue.h:238
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void SetDst(Ipv4Address a)
Set the destination address.
Definition: aodv-packet.h:204
Time m_maxQueueTime
The maximum period of time that a routing protocol is allowed to buffer a packet for.
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
uint32_t GetDstSeqno() const
Get the destination sequence number.
Definition: aodv-packet.h:412
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1015
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual void DoDispose()
Destructor implementation.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
void SetMaxQueueLen(uint32_t len)
Set the maximum queue length.
Timer m_rreqRateLimitTimer
RREQ rate limit timer.
bool IsMulticast(void) const
uint16_t m_rreqRateLimit
Maximum number of RREQ per second.
uint16_t m_ttlThreshold
Maximum TTL value for expanding ring search, TTL = NetDiameter is used beyond this value...
Ptr< NetDevice > GetOutputDevice() const
Get output device.
Definition: aodv-rtable.h:173
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Neighbors m_nb
Handle neighbors.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:733
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
void GetPrecursors(std::vector< Ipv4Address > &prec) const
Inserts precursors in output parameter prec if they do not yet exist in vector.
Definition: aodv-rtable.cc:134
#define AODV_RERR_HEADER_PROTOCOL_NUMBER
Definition: aodv-packet.h:45
void SetGratuitousReplyFlag(bool f)
Set gratuitous reply flag.
TAG_BUFFER_INLINE uint32_t ReadU32(void)
Definition: tag-buffer.h:215
Time m_nextHopWait
Period of our waiting for the neighbour&#39;s RREP_ACK.
Ptr< OutputStreamWrapper > routingStream
void SetLifeTime(Time lt)
Set the lifetime.
Definition: aodv-rtable.h:245
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:1111
STL namespace.
uint16_t m_rerrRateLimit
Maximum number of REER per second.
Route Request (RREQ) Message Format.
Definition: aodv-packet.h:136
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Time m_lastBcastTime
Keep track of the last bcast time.
bool m_destinationOnly
Indicates only the destination may respond to this RREQ.
uint32_t m_rreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
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:48
uint32_t m_seqNo
Request sequence number.
void SetInterface(int32_t oif)
Set the output interface.
void ScheduleRreqRetry(Ipv4Address dst)
Repeated attempts by a source node at route discovery for a single destination use the expanding ring...
Ptr< Socket > FindSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find unicast socket with local interface address iface.
a polymophic address class
Definition: address.h:90
bool IsRunning(void) const
Definition: timer.cc:127
bool m_gratuitousReply
Indicates whether a gratuitous RREP should be unicast to the node originated route discovery...
Ptr< Ipv4Route > LoopbackRoute(const Ipv4Header &header, Ptr< NetDevice > oif) const
Create loopback route for given header.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
bool IsValid() const
Check that type if valid.
Definition: aodv-packet.h:93
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:645
void DelArpCache(Ptr< ArpCache > a)
Don&#39;t use given ARP cache any more (interface is down)
bool InsertPrecursor(Ipv4Address id)
Insert precursor in precursor list if it doesn&#39;t yet exist in the list.
Definition: aodv-rtable.cc:70
Packet header for IPv4.
Definition: ipv4-header.h:33
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
void Print(Ptr< OutputStreamWrapper > stream) const
Print routing table.
Definition: aodv-rtable.cc:467
Time GetLifeTime() const
Get the lifetime.
Definition: aodv-rtable.h:253
void SetRreqCnt(uint8_t n)
Set the RREQ count.
Definition: aodv-rtable.h:277
void RecvReplyAck(Ipv4Address neighbor)
Receive RREP_ACK.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:874
bool IsDuplicate(Ptr< const Packet > p, const Ipv4Header &header)
Check if the packet is a duplicate.
Definition: aodv-dpd.cc:29
void SendPacketFromQueue(Ipv4Address dst, Ptr< Ipv4Route > route)
Forward packet from route request queue.
void DeferredRouteOutput(Ptr< const Packet > p, const Ipv4Header &header, UnicastForwardCallback ucb, ErrorCallback ecb)
Queue packet and send route request.
void SetHopCount(uint8_t count)
Set the hop count.
Definition: aodv-packet.h:372
bool IsMyOwnAddress(Ipv4Address src)
Test whether the provided address is assigned to an interface on this node.
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
NS_ASSERT_MSG(false,"Ipv4AddressGenerator::MaskToIndex(): Impossible")
uint16_t m_ttlIncrement
TTL increment for each attempt using the expanding ring search for RREQ dissemination.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:220
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1381
void RecvReply(Ptr< Packet > p, Ipv4Address my, Ipv4Address src)
Receive RREP.
#define max(a, b)
Definition: 80211b.c:43
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: aodv-rtable.cc:351
void HelloTimerExpire()
Schedule next send of hello message.
uint32_t m_allowedHelloLoss
Number of hello messages which may be loss for valid link.
void SetTtl(uint8_t ttl)
Set the tag&#39;s TTL.
Definition: socket.cc:610
AttributeValue implementation for Time.
Definition: nstime.h:1069
Introspection did not find any typical Config paths.
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
uint8_t GetDestCount() const
Definition: aodv-packet.h:609
Ipv4Address GetNextHop() const
Get next hop address.
Definition: aodv-rtable.h:157
bool AddUnDestination(Ipv4Address dst, uint32_t seqNo)
Add unreachable node address and its sequence number in RERR header.
Definition: aodv-packet.cc:619
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
void SetFunction(FN fn)
Definition: timer.h:309
bool UpdateRouteLifeTime(Ipv4Address addr, Time lt)
Set lifetime field in routing table entry to the maximum of existing lifetime and lt...
Hold an unsigned integer type.
Definition: uinteger.h:44
void UpdateRouteToNeighbor(Ipv4Address sender, Ipv4Address receiver)
Update neighbor record.
Ipv4Address GetDst() const
Get the destination address.
Definition: aodv-packet.h:212
double startTime
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:186
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:108
AODV routing protocol.
bool IsBroadcast(void) const
mac
Definition: third.py:92
void SetSeqNo(uint32_t sn)
Set the sequence number.
Definition: aodv-rtable.h:213
AODVTYPE_RERR.
Definition: aodv-packet.h:54
void SetValidSeqNo(bool s)
Set the valid sequence number.
Definition: aodv-rtable.h:197
void SetOriginSeqno(uint32_t s)
Set the origin sequence number.
Definition: aodv-packet.h:252
int32_t m_oif
Positive if output device is fixed in RouteOutput.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
Hold together all Wifi-related objects.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
static TypeId GetTypeId(void)
Get the type ID.
uint8_t GetHopCount() const
Get the hop count.
Definition: aodv-packet.h:180
void SetDestinationOnly(bool f)
Set the Destination only flag.
Definition: aodv-packet.cc:249
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual void DoInitialize(void)
Initialize() implementation.
Time GetMaxQueueTime() const
Get maximum queue time.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
void SendReplyByIntermediateNode(RoutingTableEntry &toDst, RoutingTableEntry &toOrigin, bool gratRep)
Send RREP by intermediate node.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
Ptr< const Packet > GetPacket() const
Get packet from entry.
Definition: aodv-rqueue.h:117
Ipv4InterfaceAddress GetInterface() const
Get the Ipv4InterfaceAddress.
Definition: aodv-rtable.h:181
Callback< void, WifiMacHeader const & > GetTxErrorCallback() const
Get callback to ProcessTxError.
void SetDelay(const Time &delay)
Definition: timer.cc:75
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
Definition: aodv-rqueue.cc:72
uint16_t m_rerrCount
Number of RERRs used for RERR rate control.
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
static Ipv4Address GetBroadcast(void)
void SetMaxQueueTime(Time t)
Set the maximum queue time.
void SetDstSeqno(uint32_t s)
Set the destination sequence number.
Definition: aodv-packet.h:220
Route Reply (RREP) Message Format.
Definition: aodv-packet.h:340
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:314
bool GetHelloEnable() const
Get hello enable flag.
void SetInterface(Ipv4InterfaceAddress iface)
Set the Ipv4InterfaceAddress.
Definition: aodv-rtable.h:189
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
AODV Queue Entry.
Definition: aodv-rqueue.h:43
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
void SendRerrWhenNoRouteToForward(Ipv4Address dst, uint32_t dstSeqNo, Ipv4Address origin)
Send RERR message when no route to forward input packet.
This policy cancels the event from the destructor of the Timer to verify that the event has already e...
Definition: timer.h:86
tag a set of bytes in a packet
Definition: tag.h:36
void Clear()
Remove all entries.
void SendRerrWhenBreaksLinkToNextHop(Ipv4Address nextHop)
Initiate RERR.
void SetArguments(T1 a1)
Definition: timer.h:324
Implement the IPv4 layer.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses
Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP + mask) ...
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
void SetFlag(RouteFlags flag)
Set the route flags.
Definition: aodv-rtable.h:261
address
Definition: first.py:37
bool GetGratuitousReplyFlag() const
Get gratuitous reply flag.
Ipv4Address GetOrigin() const
Get the origin address.
Definition: aodv-packet.h:428
uint16_t GetHop() const
Get the number of hops.
Definition: aodv-rtable.h:237
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
bool RemoveUnDestination(std::pair< Ipv4Address, uint32_t > &un)
Delete pair (address + sequence number) from REER header, if the number of unreachable destinations >...
Definition: aodv-packet.cc:632
Ptr< Socket > FindSubnetBroadcastSocketWithInterfaceAddress(Ipv4InterfaceAddress iface) const
Find subnet directed broadcast socket with local interface address iface.
Packet header for UDP packets.
Definition: udp-header.h:39
void RecvRequest(Ptr< Packet > p, Ipv4Address receiver, Ipv4Address src)
Receive RREQ.
uint32_t m_netDiameter
Net diameter measures the maximum possible number of hops between two nodes in the network...
void SetOrigin(Ipv4Address a)
Set the origin address.
Definition: aodv-packet.h:236
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_socketAddresses
Raw unicast socket per each IP interface, map socket -> iface address (IP + mask) ...
uint16_t m_ttlStart
Initial TTL value for RREQ.
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1570
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1070
void Update(Ipv4Address addr, Time expire)
Update expire time for entry with address addr, if it exists, else add new entry. ...
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
void ProcessHello(RrepHeader const &rrepHeader, Ipv4Address receiverIfaceAddr)
Process hello message.
static Ipv4Address GetLoopback(void)
virtual void NotifyInterfaceUp(uint32_t interface)
Time GetLifeTime() const
Get the lifetime.
Definition: aodv-packet.cc:385
bool m_enableHello
Indicates whether a hello messages enable.
Ipv4Address GetDst() const
Get the destination address.
Definition: aodv-packet.h:396
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
DuplicatePacketDetection m_dpd
Handle duplicated broadcast/multicast packets.
int32_t GetInterface() const
Get the output interface.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
Route Reply Acknowledgment (RREP-ACK) Message Format.
Definition: aodv-packet.h:508
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.
void SetDestinationOnlyFlag(bool f)
Set destination only flag.
Time m_myRouteTimeout
Value of lifetime field in RREP generating by this node.
uint32_t GetDstSeqno() const
Get the destination sequence number.
Definition: aodv-packet.h:228
Ipv4Address GetDestination(void) const
Definition: ipv4-route.cc:42
wifi
Definition: third.py:89
void SetHop(uint16_t hop)
Set the number of hops.
Definition: aodv-rtable.h:229
Time m_pathDiscoveryTime
Estimate of maximum time needed to find route in network.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
read and write tag data
Definition: tag-buffer.h:51
Ipv4Address GetBroadcast(void) const
Get the broadcast address.
virtual void NotifyInterfaceDown(uint32_t interface)
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
void SetGratuitousRrep(bool f)
Set the gratuitous RREP flag.
Definition: aodv-packet.cc:230
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:262
uint32_t GetSeqNo() const
Get the sequence number.
Definition: aodv-rtable.h:221
void SetQueueTimeout(Time t)
Set queue timeout.
Definition: aodv-rqueue.h:254
bool GetGratuitousRrep() const
Get the gratuitous RREP flag.
Definition: aodv-packet.cc:243
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn&#39;t yet exist in routing table.
Definition: aodv-rtable.cc:263
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:859
A network Node.
Definition: node.h:56
bool GetDestinationOnlyFlag() const
Get destination only flag.
AODVTYPE_RREP.
Definition: aodv-packet.h:53
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
#define AODV_RREQ_HEADER_PROTOCOL_NUMBER
Definition: aodv-packet.h:42
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
AODVTYPE_RREP_ACK.
Definition: aodv-packet.h:55
Ipv4Address GetOrigin() const
Get the origin address.
Definition: aodv-packet.h:244
Time m_blackListTimeout
Time for which the node is put into the blacklist.
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.
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
void SetIpRecvTtl(bool ipv4RecvTtl)
Tells a socket to pass information about IP_TTL up the stack.
Definition: socket.cc:532
void SetCallback(Callback< void, Ipv4Address > cb)
Set link failure callback.
void SetAckRequired(bool f)
Set the ack required flag.
Definition: aodv-packet.cc:392
void Print(std::ostream &os) const
void SendReply(RreqHeader const &rreqHeader, RoutingTableEntry const &toOrigin)
Send RREP.
uint32_t GetOriginSeqno() const
Get the origin sequence number.
Definition: aodv-packet.h:260
Abstract base class for IPv4 routing protocols.
void SetNextHop(Ipv4Address nextHop)
Set next hop address.
Definition: aodv-rtable.h:149
AODVTYPE_RREQ.
Definition: aodv-packet.h:52
bool GetDestinationOnly() const
Get the Destination only flag.
Definition: aodv-packet.cc:262
Timer m_rerrRateLimitTimer
RERR rate limit timer.
#define AODV_RREP_HEADER_PROTOCOL_NUMBER
Definition: aodv-packet.h:43
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.
#define AODV_RREP_ACK_HEADER_PROTOCOL_NUMBER
Definition: aodv-packet.h:44
Ptr< Ipv4Route > GetRoute() const
Get route function.
Definition: aodv-rtable.h:133
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1023
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
second
Definition: nstime.h:114
uint16_t m_timeoutBuffer
Provide a buffer for the timeout.
void SendRequest(Ipv4Address dst)
Send RREQ.
bool Dequeue(Ipv4Address dst, QueueEntry &entry)
Return first found (the earliest) entry for given destination.
Definition: aodv-rqueue.cc:89
void RerrRateLimitTimerExpire()
Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
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.
uint8_t GetTtl(void) const
Get the tag&#39;s TTL.
Definition: socket.cc:617
DeferredRouteOutputTag(int32_t o=-1)
Constructor.
IdCache m_rreqIdCache
Handle duplicated RREQ.
void RouteRequestTimerExpire(Ipv4Address dst)
Handle route discovery process.
TypeId GetInstanceTypeId() const
Get the most derived TypeId for this Object.
void Start()
Start protocol operation.
void SetHelloEnable(bool f)
Set hello enable.
void AddArpCache(Ptr< ArpCache > a)
Add ARP cache to be used to allow layer 2 notifications processing.
virtual int Close(void)=0
Close a socket.
uint16_t GetDestinationPort(void) const
Definition: udp-header.cc:70
bool LookupValidRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup route in VALID state.
Definition: aodv-rtable.cc:236
Time GetDelayLeft(void) const
Definition: timer.cc:87
static TypeId GetTypeId()
Get the type ID.
bool IsUnidirectional() const
Get the unidirectional flag.
Definition: aodv-rtable.h:308
void SetBroadcastEnable(bool f)
Set broadcast enable flag.
uint32_t GetId() const
Get the request ID.
Definition: aodv-packet.h:196
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: aodv-rtable.cc:249
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
void Purge()
Delete all outdated entries and invalidate valid entry if Lifetime is expired.
Definition: aodv-rtable.cc:375
a unique identifier for an interface.
Definition: type-id.h:58
static const uint8_t PROT_NUMBER
protocol number (0x11)
Ptr< NetDevice > m_lo
Loopback device used to defer RREQ until packet will be fully formed.
RouteFlags GetFlag() const
Get the route flags.
Definition: aodv-rtable.h:269
uint32_t m_requestId
Broadcast ID.
Ipv4Address GetDestination() const
Get destination address function.
Definition: aodv-rtable.h:125
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
MessageType Get() const
Definition: aodv-packet.h:85
uint8_t GetHopCount() const
Get the hop count.
Definition: aodv-packet.h:380
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
uint8_t GetRreqCnt() const
Get the RREQ count.
Definition: aodv-rtable.h:285
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:371
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void SetUnknownSeqno(bool f)
Set the unknown sequence number flag.
Definition: aodv-packet.cc:268
virtual Address GetAddress(void) const =0
uint32_t GetMaxQueueLen() const
Get the maximum queue length.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void ScheduleTimer()
Schedule m_ntimer.
bool GetValidSeqNo() const
Get the valid sequence number.
Definition: aodv-rtable.h:205
static const uint32_t AODV_PORT
UDP Port for AODV control traffic.
void SetHopCount(uint8_t count)
Set the hop count.
Definition: aodv-packet.h:172
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.