A Discrete-Event Network Simulator
API
dsr-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Yufei Cheng
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  * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
19  *
20  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
21  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
22  * Information and Telecommunication Technology Center (ITTC)
23  * and Department of Electrical Engineering and Computer Science
24  * The University of Kansas Lawrence, KS USA.
25  *
26  * Work supported in part by NSF FIND (Future Internet Design) Program
27  * under grant CNS-0626918 (Postmodern Internet Architecture),
28  * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
29  * US Department of Defense (DoD), and ITTC at The University of Kansas.
30  */
31 
32 #define NS_LOG_APPEND_CONTEXT \
33  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
34 
35 #include <list>
36 #include <ctime>
37 #include <map>
38 #include <limits>
39 #include <algorithm>
40 #include <iostream>
41 
42 #include "ns3/config.h"
43 #include "ns3/enum.h"
44 #include "ns3/string.h"
45 #include "ns3/ptr.h"
46 #include "ns3/log.h"
47 #include "ns3/assert.h"
48 #include "ns3/uinteger.h"
49 #include "ns3/net-device.h"
50 #include "ns3/packet.h"
51 #include "ns3/boolean.h"
52 #include "ns3/node-list.h"
53 #include "ns3/double.h"
54 #include "ns3/pointer.h"
55 #include "ns3/timer.h"
56 #include "ns3/object-vector.h"
57 #include "ns3/ipv4-address.h"
58 #include "ns3/ipv4-header.h"
59 #include "ns3/ipv4-l3-protocol.h"
60 #include "ns3/ipv4-route.h"
61 #include "ns3/trace-source-accessor.h"
62 #include "ns3/icmpv4-l4-protocol.h"
63 #include "ns3/adhoc-wifi-mac.h"
64 #include "ns3/wifi-net-device.h"
65 #include "ns3/inet-socket-address.h"
66 #include "ns3/udp-l4-protocol.h"
67 #include "ns3/udp-socket-factory.h"
68 #include "ns3/tcp-socket-factory.h"
69 #include "ns3/llc-snap-header.h"
70 #include "ns3/arp-header.h"
71 #include "ns3/ipv6-interface.h"
72 
73 #include "dsr-rreq-table.h"
74 #include "dsr-rcache.h"
75 #include "dsr-routing.h"
76 #include "dsr-fs-header.h"
77 #include "dsr-options.h"
78 
79 namespace ns3 {
80 
81 NS_LOG_COMPONENT_DEFINE ("DsrRouting");
82 
83 namespace dsr {
84 
85 NS_OBJECT_ENSURE_REGISTERED (DsrRouting);
86 
87 /* see http://www.iana.org/assignments/protocol-numbers */
88 const uint8_t DsrRouting::PROT_NUMBER = 48;
89 /*
90  * The extension header is the fixed size dsr header, it is response for recognizing DSR option types
91  * and demux to right options to process the packet.
92  *
93  * The header format with neighboring layers is as follows:
94  *
95  +-+-+-+-+-+-+-+-+-+-+-
96  | Application Header |
97  +-+-+-+-+-+-+-+-+-+-+-+
98  | Transport Header |
99  +-+-+-+-+-+-+-+-+-+-+-+
100  | Fixed DSR Header |
101  +---------------------+
102  | DSR Options |
103  +-+-+-+-+-+-+-+-+-+-+-+
104  | IP Header |
105  +-+-+-+-+-+-+-+-+-+-+-+
106  */
107 
109 {
110  static TypeId tid = TypeId ("ns3::dsr::DsrRouting")
112  .SetGroupName ("Dsr")
113  .AddConstructor<DsrRouting> ()
114  .AddAttribute ("RouteCache",
115  "The route cache for saving routes from "
116  "route discovery process.",
117  PointerValue (0),
120  MakePointerChecker<DsrRouteCache> ())
121  .AddAttribute ("RreqTable",
122  "The request table to manage route requests.",
123  PointerValue (0),
126  MakePointerChecker<DsrRreqTable> ())
127  .AddAttribute ("PassiveBuffer",
128  "The passive buffer to manage "
129  "promisucously received passive ack.",
130  PointerValue (0),
133  MakePointerChecker<DsrPassiveBuffer> ())
134  .AddAttribute ("MaxSendBuffLen",
135  "Maximum number of packets that can be stored "
136  "in send buffer.",
137  UintegerValue (64),
139  MakeUintegerChecker<uint32_t> ())
140  .AddAttribute ("MaxSendBuffTime",
141  "Maximum time packets can be queued in the send buffer .",
142  TimeValue (Seconds (30)),
144  MakeTimeChecker ())
145  .AddAttribute ("MaxMaintLen",
146  "Maximum number of packets that can be stored "
147  "in maintenance buffer.",
148  UintegerValue (50),
150  MakeUintegerChecker<uint32_t> ())
151  .AddAttribute ("MaxMaintTime",
152  "Maximum time packets can be queued in maintenance buffer.",
153  TimeValue (Seconds (30)),
155  MakeTimeChecker ())
156  .AddAttribute ("MaxCacheLen",
157  "Maximum number of route entries that can be stored "
158  "in route cache.",
159  UintegerValue (64),
161  MakeUintegerChecker<uint32_t> ())
162  .AddAttribute ("RouteCacheTimeout",
163  "Maximum time the route cache can be queued in "
164  "route cache.",
165  TimeValue (Seconds (300)),
167  MakeTimeChecker ())
168  .AddAttribute ("MaxEntriesEachDst",
169  "Maximum number of route entries for a "
170  "single destination to respond.",
171  UintegerValue (20),
173  MakeUintegerChecker<uint32_t> ())
174  .AddAttribute ("SendBuffInterval",
175  "How often to check send buffer for packet with route.",
176  TimeValue (Seconds (500)),
178  MakeTimeChecker ())
179  .AddAttribute ("NodeTraversalTime",
180  "The time it takes to traverse two neighboring nodes.",
181  TimeValue (MilliSeconds (40)),
183  MakeTimeChecker ())
184  .AddAttribute ("RreqRetries",
185  "Maximum number of retransmissions for "
186  "request discovery of a route.",
187  UintegerValue (16),
189  MakeUintegerChecker<uint32_t> ())
190  .AddAttribute ("MaintenanceRetries",
191  "Maximum number of retransmissions for "
192  "data packets from maintenance buffer.",
193  UintegerValue (2),
195  MakeUintegerChecker<uint32_t> ())
196  .AddAttribute ("RequestTableSize",
197  "Maximum number of request entries in the request table, "
198  "set this as the number of nodes in the simulation.",
199  UintegerValue (64),
201  MakeUintegerChecker<uint32_t> ())
202  .AddAttribute ("RequestIdSize",
203  "Maximum number of request source Ids in "
204  "the request table.",
205  UintegerValue (16),
207  MakeUintegerChecker<uint32_t> ())
208  .AddAttribute ("UniqueRequestIdSize",
209  "Maximum number of request Ids in "
210  "the request table for a single destination.",
211  UintegerValue (256),
213  MakeUintegerChecker<uint32_t> ())
214  .AddAttribute ("NonPropRequestTimeout",
215  "The timeout value for non-propagation request.",
216  TimeValue (MilliSeconds (30)),
218  MakeTimeChecker ())
219  .AddAttribute ("DiscoveryHopLimit",
220  "The max discovery hop limit for route requests.",
221  UintegerValue (255),
223  MakeUintegerChecker<uint32_t> ())
224  .AddAttribute ("MaxSalvageCount",
225  "The max salvage count for a single data packet.",
226  UintegerValue (15),
228  MakeUintegerChecker<uint8_t> ())
229  .AddAttribute ("BlacklistTimeout",
230  "The time for a neighbor to stay in blacklist.",
231  TimeValue (Seconds (3)),
233  MakeTimeChecker ())
234  .AddAttribute ("GratReplyHoldoff",
235  "The time for gratuitous reply entry to expire.",
236  TimeValue (Seconds (1)),
238  MakeTimeChecker ())
239  .AddAttribute ("BroadcastJitter",
240  "The jitter time to avoid collision for broadcast packets.",
241  UintegerValue (10),
243  MakeUintegerChecker<uint32_t> ())
244  .AddAttribute ("LinkAckTimeout",
245  "The time a packet in maintenance buffer wait for "
246  "link acknowledgment.",
247  TimeValue (MilliSeconds (100)),
249  MakeTimeChecker ())
250  .AddAttribute ("TryLinkAcks",
251  "The number of link acknowledgment to use.",
252  UintegerValue (1),
254  MakeUintegerChecker<uint32_t> ())
255  .AddAttribute ("PassiveAckTimeout",
256  "The time a packet in maintenance buffer wait for "
257  "passive acknowledgment.",
258  TimeValue (MilliSeconds (100)),
260  MakeTimeChecker ())
261  .AddAttribute ("TryPassiveAcks",
262  "The number of passive acknowledgment to use.",
263  UintegerValue (1),
265  MakeUintegerChecker<uint32_t> ())
266  .AddAttribute ("RequestPeriod",
267  "The base time interval between route requests.",
268  TimeValue (MilliSeconds (500)),
270  MakeTimeChecker ())
271  .AddAttribute ("MaxRequestPeriod",
272  "The max time interval between route requests.",
273  TimeValue (Seconds (10)),
275  MakeTimeChecker ())
276  .AddAttribute ("GraReplyTableSize",
277  "The gratuitous reply table size.",
278  UintegerValue (64),
280  MakeUintegerChecker<uint32_t> ())
281  .AddAttribute ("CacheType",
282  "Use Link Cache or use Path Cache",
283  StringValue ("LinkCache"),
286  .AddAttribute ("StabilityDecrFactor",
287  "The stability decrease factor for link cache",
288  UintegerValue (2),
290  MakeUintegerChecker<uint32_t> ())
291  .AddAttribute ("StabilityIncrFactor",
292  "The stability increase factor for link cache",
293  UintegerValue (4),
295  MakeUintegerChecker<uint32_t> ())
296  .AddAttribute ("InitStability",
297  "The initial stability factor for link cache",
298  TimeValue (Seconds (25)),
300  MakeTimeChecker ())
301  .AddAttribute ("MinLifeTime",
302  "The minimal life time for link cache",
303  TimeValue (Seconds (1)),
305  MakeTimeChecker ())
306  .AddAttribute ("UseExtends",
307  "The extension time for link cache",
308  TimeValue (Seconds (120)),
310  MakeTimeChecker ())
311  .AddAttribute ("EnableSubRoute",
312  "Enables saving of sub route when receiving "
313  "route error messages, only available when "
314  "using path route cache",
315  BooleanValue (true),
318  .AddAttribute ("RetransIncr",
319  "The increase time for retransmission timer "
320  "when facing network congestion",
321  TimeValue (MilliSeconds (20)),
323  MakeTimeChecker ())
324  .AddAttribute ("MaxNetworkQueueSize",
325  "The max number of packet to save in the network queue.",
326  UintegerValue (400),
328  MakeUintegerChecker<uint32_t> ())
329  .AddAttribute ("MaxNetworkQueueDelay",
330  "The max time for a packet to stay in the network queue.",
331  TimeValue (Seconds (30.0)),
333  MakeTimeChecker ())
334  .AddAttribute ("NumPriorityQueues",
335  "The max number of packet to save in the network queue.",
336  UintegerValue (2),
338  MakeUintegerChecker<uint32_t> ())
339  .AddAttribute ("LinkAcknowledgment",
340  "Enable Link layer acknowledgment mechanism",
341  BooleanValue (true),
344  .AddTraceSource ("Tx",
345  "Send DSR packet.",
347  "ns3::dsr::DsrOptionSRHeader::TracedCallback")
348  .AddTraceSource ("Drop",
349  "Drop DSR packet",
351  "ns3::Packet::TracedCallback")
352  ;
353  return tid;
354 }
355 
357 {
359 
360  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
361 
362  /*
363  * The following Ptr statements created objects for all the options header for DSR, and each of them have
364  * distinct option number assigned, when DSR Routing received a packet from higher layer, it will find
365  * the following options based on the option number, and pass the packet to the appropriate option to
366  * process it. After the option processing, it will pass the packet back to DSR Routing to send down layer.
367  */
368  Ptr<dsr::DsrOptionPad1> pad1Option = CreateObject<dsr::DsrOptionPad1> ();
369  Ptr<dsr::DsrOptionPadn> padnOption = CreateObject<dsr::DsrOptionPadn> ();
370  Ptr<dsr::DsrOptionRreq> rreqOption = CreateObject<dsr::DsrOptionRreq> ();
371  Ptr<dsr::DsrOptionRrep> rrepOption = CreateObject<dsr::DsrOptionRrep> ();
372  Ptr<dsr::DsrOptionSR> srOption = CreateObject<dsr::DsrOptionSR> ();
373  Ptr<dsr::DsrOptionRerr> rerrOption = CreateObject<dsr::DsrOptionRerr> ();
374  Ptr<dsr::DsrOptionAckReq> ackReq = CreateObject<dsr::DsrOptionAckReq> ();
375  Ptr<dsr::DsrOptionAck> ack = CreateObject<dsr::DsrOptionAck> ();
376 
377  Insert (pad1Option);
378  Insert (padnOption);
379  Insert (rreqOption);
380  Insert (rrepOption);
381  Insert (srOption);
382  Insert (rerrOption);
383  Insert (ackReq);
384  Insert (ack);
385 
386  // Check the send buffer for sending packets
389 }
390 
392 {
394 }
395 
396 void
398 {
399  NS_LOG_FUNCTION (this << "NotifyNewAggregate");
400  if (m_node == 0)
401  {
402  Ptr<Node> node = this->GetObject<Node> ();
403  if (node != 0)
404  {
405  m_ipv4 = this->GetObject<Ipv4L3Protocol> ();
406  if (m_ipv4 != 0)
407  {
408  this->SetNode (node);
409  m_ipv4->Insert (this);
411  }
412 
413  m_ip = node->GetObject<Ipv4> ();
414  if (m_ip != 0)
415  {
416  NS_LOG_DEBUG ("Ipv4 started");
417  }
418  }
419  }
422 }
423 
425 {
426  NS_LOG_FUNCTION (this << "Start DSR Routing protocol");
427 
428  NS_LOG_INFO ("The number of network queues " << m_numPriorityQueues);
429  for (uint32_t i = 0; i < m_numPriorityQueues; i++)
430  {
431  // Set the network queue max size and the delay
432  NS_LOG_INFO ("The network queue size " << m_maxNetworkSize << " and the queue delay " << m_maxNetworkDelay.As (Time::S));
433  Ptr<dsr::DsrNetworkQueue> queue_i = CreateObject<dsr::DsrNetworkQueue> (m_maxNetworkSize,m_maxNetworkDelay);
434  std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator, bool> result_i = m_priorityQueue.insert (std::make_pair (i, queue_i));
435  NS_ASSERT_MSG (result_i.second, "Error in creating queues");
436  }
437  Ptr<dsr::DsrRreqTable> rreqTable = CreateObject<dsr::DsrRreqTable> ();
438  // Set the initial hop limit
439  rreqTable->SetInitHopLimit (m_discoveryHopLimit);
440  // Configure the request table parameters
441  rreqTable->SetRreqTableSize (m_requestTableSize);
442  rreqTable->SetRreqIdSize (m_requestTableIds);
443  rreqTable->SetUniqueRreqIdSize (m_maxRreqId);
444  SetRequestTable (rreqTable);
445  // Set the passive buffer parameters using just the send buffer parameters
446  Ptr<dsr::DsrPassiveBuffer> passiveBuffer = CreateObject<dsr::DsrPassiveBuffer> ();
447  passiveBuffer->SetMaxQueueLen (m_maxSendBuffLen);
448  passiveBuffer->SetPassiveBufferTimeout (m_sendBufferTimeout);
449  SetPassiveBuffer (passiveBuffer);
450 
451  // Set the send buffer parameters
454  // Set the error buffer parameters using just the send buffer parameters
457  // Set the maintenance buffer parameters
460  // Set the gratuitous reply table size
462 
463  if (m_mainAddress == Ipv4Address ())
464  {
465  Ipv4Address loopback ("127.0.0.1");
466  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
467  {
468  // Use primary address, if multiple
469  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
470  m_broadcast = m_ipv4->GetAddress (i, 0).GetBroadcast ();
471  if (addr != loopback)
472  {
473  /*
474  * Set dsr route cache
475  */
476  Ptr<dsr::DsrRouteCache> routeCache = CreateObject<dsr::DsrRouteCache> ();
477  // Configure the path cache parameters
478  routeCache->SetCacheType (m_cacheType);
479  routeCache->SetSubRoute (m_subRoute);
480  routeCache->SetMaxCacheLen (m_maxCacheLen);
481  routeCache->SetCacheTimeout (m_maxCacheTime);
482  routeCache->SetMaxEntriesEachDst (m_maxEntriesEachDst);
483  // Parameters for link cache
484  routeCache->SetStabilityDecrFactor (m_stabilityDecrFactor);
485  routeCache->SetStabilityIncrFactor (m_stabilityIncrFactor);
486  routeCache->SetInitStability (m_initStability);
487  routeCache->SetMinLifeTime (m_minLifeTime);
488  routeCache->SetUseExtends (m_useExtends);
489  routeCache->ScheduleTimer ();
490  // The call back to handle link error and send error message to appropriate nodes
492  // routeCache->SetCallback (MakeCallback (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
493  SetRouteCache (routeCache);
494  // Set the main address as the current ip address
495  m_mainAddress = addr;
496 
497  m_ipv4->GetNetDevice (1)->SetPromiscReceiveCallback (MakeCallback (&DsrRouting::PromiscReceive, this));
498 
499  // Allow neighbor manager use this interface for layer 2 feedback if possible
500  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (addr));
502  if (wifi == 0)
503  {
504  break;
505  }
506  Ptr<WifiMac> mac = wifi->GetMac ();
507  if (mac == 0)
508  {
509  break;
510  }
511 
512  routeCache->AddArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
513  NS_LOG_LOGIC ("Starting DSR on node " << m_mainAddress);
514  break;
515  }
516  }
518  }
519 }
520 
523 {
524  // Use "NodeList/*/DeviceList/*/ as reference
525  // where element [1] is the Node Id
526  // element [2] is the NetDevice Id
527  std::vector <std::string> elements = GetElementsFromContext (context);
528  Ptr<Node> n = NodeList::GetNode (atoi (elements[1].c_str ()));
529  NS_ASSERT (n);
530  return n->GetDevice (atoi (elements[3].c_str ()));
531 }
532 
533 std::vector<std::string>
535 {
536  std::vector <std::string> elements;
537  size_t pos1 = 0, pos2;
538  while (pos1 != context.npos)
539  {
540  pos1 = context.find ("/",pos1);
541  pos2 = context.find ("/",pos1 + 1);
542  elements.push_back (context.substr (pos1 + 1,pos2 - (pos1 + 1)));
543  pos1 = pos2;
544  }
545  return elements;
546 }
547 
548 void
550 {
552  m_node = 0;
553  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
554  {
555  // Disable layer 2 link state monitoring (if possible)
556  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (i);
558  if (wifi != 0)
559  {
560  Ptr<WifiMac> mac = wifi->GetMac ();
561  if (mac != 0)
562  {
563  Ptr<AdhocWifiMac> adhoc = mac->GetObject<AdhocWifiMac> ();
564  if (adhoc)
565  {
566  adhoc->TraceDisconnectWithoutContext ("TxErrHeader",
567  m_routeCache->GetTxErrorCallback ());
568  m_routeCache->DelArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
569  }
570  }
571  }
572  }
574 }
575 
576 void
578 {
579  m_node = node;
580 }
581 
582 Ptr<Node>
584 {
586  return m_node;
587 }
588 
590 {
591  // / Set the route cache to use
592  m_routeCache = r;
593 }
594 
597 {
598  // / Get the route cache to use
599  return m_routeCache;
600 }
601 
603 {
604  // / Set the request table to use
605  m_rreqTable = q;
606 }
607 
610 {
611  // / Get the request table to use
612  return m_rreqTable;
613 }
614 
616 {
617  // / Set the request table to use
618  m_passiveBuffer = p;
619 }
620 
623 {
624  // / Get the request table to use
625  return m_passiveBuffer;
626 }
627 
628 Ptr<Node>
630 {
631  NS_LOG_FUNCTION (this << ipv4Address);
632  int32_t nNodes = NodeList::GetNNodes ();
633  for (int32_t i = 0; i < nNodes; ++i)
634  {
635  Ptr<Node> node = NodeList::GetNode (i);
636  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
637  int32_t ifIndex = ipv4->GetInterfaceForAddress (ipv4Address);
638  if (ifIndex != -1)
639  {
640  return node;
641  }
642  }
643  return 0;
644 }
645 
647 {
648  return m_routeCache->IsLinkCache ();
649 }
650 
652 {
653  m_routeCache->UseExtends (rt);
654 }
655 
657 {
658  return m_routeCache->LookupRoute (id, rt);
659 }
660 
662 {
663  Ipv4Address nextHop = SearchNextHop (source, nodelist);
664  m_errorBuffer.DropPacketForErrLink (source, nextHop);
665  return m_routeCache->AddRoute_Link (nodelist, source);
666 }
667 
669 {
670  std::vector<Ipv4Address> nodelist = rt.GetVector ();
671  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodelist);
673  return m_routeCache->AddRoute (rt);
674 }
675 
677 {
678  m_routeCache->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, node);
679 }
680 
682 {
683  return m_routeCache->UpdateRouteEntry (dst);
684 }
685 
687 {
688  return m_rreqTable->FindSourceEntry (src, dst, id);
689 }
690 
693 {
694  NS_LOG_FUNCTION (this << address);
695  int32_t nNodes = NodeList::GetNNodes ();
696  for (int32_t i = 0; i < nNodes; ++i)
697  {
698  Ptr<Node> node = NodeList::GetNode (i);
699  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
700  Ptr<NetDevice> netDevice = ipv4->GetNetDevice (1);
701 
702  if (netDevice->GetAddress () == address)
703  {
704  return ipv4->GetAddress (1, 0).GetLocal ();
705  }
706  }
707  return 0;
708 }
709 
710 void DsrRouting::PrintVector (std::vector<Ipv4Address>& vec)
711 {
712  NS_LOG_FUNCTION (this);
713  /*
714  * Check elements in a route vector
715  */
716  if (!vec.size ())
717  {
718  NS_LOG_DEBUG ("The vector is empty");
719  }
720  else
721  {
722  NS_LOG_DEBUG ("Print all the elements in a vector");
723  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
724  {
725  NS_LOG_DEBUG ("The ip address " << *i);
726  }
727  }
728 }
729 
730 Ipv4Address DsrRouting::SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
731 {
732  NS_LOG_FUNCTION (this << ipv4Address);
733  Ipv4Address nextHop;
734  NS_LOG_DEBUG ("the vector size " << vec.size ());
735  if (vec.size () == 2)
736  {
737  NS_LOG_DEBUG ("The two nodes are neighbors");
738  nextHop = vec[1];
739  return nextHop;
740  }
741  else
742  {
743  if (ipv4Address == vec.back ())
744  {
745  NS_LOG_DEBUG ("We have reached to the final destination " << ipv4Address << " " << vec.back ());
746  return ipv4Address;
747  }
748  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
749  {
750  if (ipv4Address == (*i))
751  {
752  nextHop = *(++i);
753  return nextHop;
754  }
755  }
756  }
757  NS_LOG_DEBUG ("Next hop address not found");
758  Ipv4Address none = "0.0.0.0";
759  return none;
760 }
761 
764 {
765  NS_LOG_FUNCTION (this << nextHop << srcAddress);
766  m_ipv4Route = Create<Ipv4Route> ();
767  m_ipv4Route->SetDestination (nextHop);
768  m_ipv4Route->SetGateway (nextHop);
769  m_ipv4Route->SetSource (srcAddress);
770  return m_ipv4Route;
771 }
772 
773 int
775 {
776  // / This is the protocol number for DSR which is 48
777  return PROT_NUMBER;
778 }
779 
780 uint16_t
782 {
783  int32_t nNodes = NodeList::GetNNodes ();
784  for (int32_t i = 0; i < nNodes; ++i)
785  {
786  Ptr<Node> node = NodeList::GetNode (i);
787  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
788  if (ipv4->GetAddress (1, 0).GetLocal () == address)
789  {
790  return uint16_t (i);
791  }
792  }
793  return 256;
794 }
795 
798 {
799  if (id >= 256)
800  {
801  NS_LOG_DEBUG ("Exceed the node range");
802  return "0.0.0.0";
803  }
804  else
805  {
806  Ptr<Node> node = NodeList::GetNode (uint32_t (id));
807  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
808  return ipv4->GetAddress (1, 0).GetLocal ();
809  }
810 }
811 
812 uint32_t
814 {
815  if (messageType == DSR_CONTROL_PACKET)
816  {
817  return 0;
818  }
819  else
820  {
821  return 1;
822  }
823 }
824 
826 {
827  if (m_sendBuffTimer.IsRunning ())
828  {
830  }
832  CheckSendBuffer ();
833 }
834 
836 {
838  << " Checking send buffer at " << m_mainAddress << " with size " << m_sendBuffer.GetSize ());
839 
840  for (std::vector<DsrSendBuffEntry>::iterator i = m_sendBuffer.GetBuffer ().begin (); i != m_sendBuffer.GetBuffer ().end (); )
841  {
842  NS_LOG_DEBUG ("Here we try to find the data packet in the send buffer");
843  Ipv4Address destination = i->GetDestination ();
844  DsrRouteCacheEntry toDst;
845  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
846  if (findRoute)
847  {
848  NS_LOG_INFO ("We have found a route for the packet");
849  Ptr<const Packet> packet = i->GetPacket ();
850  Ptr<Packet> cleanP = packet->Copy ();
851  uint8_t protocol = i->GetProtocol ();
852 
853  i = m_sendBuffer.GetBuffer ().erase (i);
854 
855  DsrRoutingHeader dsrRoutingHeader;
856  Ptr<Packet> copyP = packet->Copy ();
857  Ptr<Packet> dsrPacket = packet->Copy ();
858  dsrPacket->RemoveHeader (dsrRoutingHeader);
859  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
860  copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
861  // The packet to get ipv4 header
862  Ptr<Packet> ipv4P = copyP->Copy ();
863  /*
864  * Peek data to get the option type as well as length and segmentsLeft field
865  */
866  uint32_t size = copyP->GetSize ();
867  uint8_t *data = new uint8_t[size];
868  copyP->CopyData (data, size);
869 
870  uint8_t optionType = 0;
871  optionType = *(data);
872 
873  if (optionType == 3)
874  {
875  Ptr<dsr::DsrOptions> dsrOption;
876  DsrOptionHeader dsrOptionHeader;
877  uint8_t errorType = *(data + 2);
878 
879  if (errorType == 1) // This is the Route Error Option
880  {
882  copyP->RemoveHeader (rerr);
883  NS_ASSERT (copyP->GetSize () == 0);
884 
885  DsrOptionRerrUnreachHeader newUnreach;
886  newUnreach.SetErrorType (1);
887  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
888  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
889  newUnreach.SetErrorDst (rerr.GetErrorDst ());
890  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
891 
892  DsrOptionSRHeader sourceRoute;
893  std::vector<Ipv4Address> errorRoute = toDst.GetVector ();
894  sourceRoute.SetNodesAddress (errorRoute);
896  if (m_routeCache->IsLinkCache ())
897  {
898  m_routeCache->UseExtends (errorRoute);
899  }
900  sourceRoute.SetSegmentsLeft ((errorRoute.size () - 2));
901  uint8_t salvage = 0;
902  sourceRoute.SetSalvage (salvage);
903  Ipv4Address nextHop = SearchNextHop (m_mainAddress, errorRoute); // Get the next hop address
904 
905  if (nextHop == "0.0.0.0")
906  {
907  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
908  return;
909  }
910 
911  SetRoute (nextHop, m_mainAddress);
912  uint8_t length = (sourceRoute.GetLength () + newUnreach.GetLength ());
913  dsrRoutingHeader.SetNextHeader (protocol);
914  dsrRoutingHeader.SetMessageType (1);
915  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
916  dsrRoutingHeader.SetDestId (255);
917  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
918  dsrRoutingHeader.AddDsrOption (newUnreach);
919  dsrRoutingHeader.AddDsrOption (sourceRoute);
920 
921  Ptr<Packet> newPacket = Create<Packet> ();
922  newPacket->AddHeader (dsrRoutingHeader); // Add the routing header with rerr and sourceRoute attached to it
923  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
924  m_ipv4Route->SetOutputDevice (dev);
925 
926  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
927  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
928  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
929  NS_LOG_LOGIC ("Will be inserting into priority queue number: " << priority);
930 
931  //m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
932 
934  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
935 
936  if (dsrNetworkQueue->Enqueue (newEntry))
937  {
938  Scheduler (priority);
939  }
940  else
941  {
942  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
943  }
944  }
945  }
946  else
947  {
948  dsrRoutingHeader.SetNextHeader (protocol);
949  dsrRoutingHeader.SetMessageType (2);
950  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
951  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
952 
953  DsrOptionSRHeader sourceRoute;
954  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
955  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
956  if (nextHop == "0.0.0.0")
957  {
958  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
959  return;
960  }
961  uint8_t salvage = 0;
962  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
963  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
964  sourceRoute.SetSalvage (salvage);
966  if (m_routeCache->IsLinkCache ())
967  {
968  m_routeCache->UseExtends (nodeList);
969  }
970  uint8_t length = sourceRoute.GetLength ();
971  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
972  dsrRoutingHeader.AddDsrOption (sourceRoute);
973  cleanP->AddHeader (dsrRoutingHeader);
974  Ptr<const Packet> mtP = cleanP->Copy ();
975  // Put the data packet in the maintenance queue for data packet retransmission
976  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
977  /*source=*/ m_mainAddress, /*destination=*/ destination, /*ackId=*/ 0,
978  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
979  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
980  if (result)
981  {
982  NetworkKey networkKey;
983  networkKey.m_ackId = newEntry.GetAckId ();
984  networkKey.m_ourAdd = newEntry.GetOurAdd ();
985  networkKey.m_nextHop = newEntry.GetNextHop ();
986  networkKey.m_source = newEntry.GetSrc ();
987  networkKey.m_destination = newEntry.GetDst ();
988 
989  PassiveKey passiveKey;
990  passiveKey.m_ackId = 0;
991  passiveKey.m_source = newEntry.GetSrc ();
992  passiveKey.m_destination = newEntry.GetDst ();
993  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
994 
995  LinkKey linkKey;
996  linkKey.m_source = newEntry.GetSrc ();
997  linkKey.m_destination = newEntry.GetDst ();
998  linkKey.m_ourAdd = newEntry.GetOurAdd ();
999  linkKey.m_nextHop = newEntry.GetNextHop ();
1000 
1001  m_addressForwardCnt[networkKey] = 0;
1002  m_passiveCnt[passiveKey] = 0;
1003  m_linkCnt[linkKey] = 0;
1004 
1005  if (m_linkAck)
1006  {
1007  ScheduleLinkPacketRetry (newEntry, protocol);
1008  }
1009  else
1010  {
1011  NS_LOG_LOGIC ("Not using link acknowledgment");
1012  if (nextHop != destination)
1013  {
1014  SchedulePassivePacketRetry (newEntry, protocol);
1015  }
1016  else
1017  {
1018  // This is the first network retry
1019  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1020  }
1021  }
1022  }
1023  // we need to suspend the normal timer that checks the send buffer
1024  // until we are done sending packets
1025  if (!m_sendBuffTimer.IsSuspended ())
1026  {
1028  }
1030  return;
1031  }
1032  }
1033  else
1034  {
1035  ++i;
1036  }
1037  }
1038  //after going through the entire send buffer and send all packets found route,
1039  //we need to resume the timer if it has been suspended
1041  {
1042  NS_LOG_DEBUG ("Resume the send buffer timer");
1044  }
1045 }
1046 
1047 bool DsrRouting::PromiscReceive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &from,
1048  const Address &to, NetDevice::PacketType packetType)
1049 {
1050 
1051  if (protocol != Ipv4L3Protocol::PROT_NUMBER)
1052  {
1053  return false;
1054  }
1055  // Remove the ipv4 header here
1056  Ptr<Packet> pktMinusIpHdr = packet->Copy ();
1057  Ipv4Header ipv4Header;
1058  pktMinusIpHdr->RemoveHeader (ipv4Header);
1059 
1060  if (ipv4Header.GetProtocol () != DsrRouting::PROT_NUMBER)
1061  {
1062  return false;
1063  }
1064  // Remove the dsr routing header here
1065  Ptr<Packet> pktMinusDsrHdr = pktMinusIpHdr->Copy ();
1066  DsrRoutingHeader dsrRouting;
1067  pktMinusDsrHdr->RemoveHeader (dsrRouting);
1068 
1069  /*
1070  * Message type 2 means the data packet, we will further process the data
1071  * packet for delivery notification, safely ignore control packet
1072  * Another check here is our own address, if this is the data destinated for us,
1073  * process it further, otherwise, just ignore it
1074  */
1075  Ipv4Address ourAddress = m_ipv4->GetAddress (1, 0).GetLocal ();
1076  // check if the message type is 2 and if the ipv4 address matches
1077  if (dsrRouting.GetMessageType () == 2 && ourAddress == m_mainAddress)
1078  {
1079  NS_LOG_DEBUG ("data packet receives " << packet->GetUid ());
1080  Ipv4Address sourceIp = GetIPfromID (dsrRouting.GetSourceId ());
1081  Ipv4Address destinationIp = GetIPfromID ( dsrRouting.GetDestId ());
1083  Ipv4Address previousHop = GetIPfromMAC (Mac48Address::ConvertFrom (from));
1084 
1085  Ptr<Packet> p = Create<Packet> ();
1086  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
1087  DsrMaintainBuffEntry newEntry;
1088  newEntry.SetPacket (p);
1089  newEntry.SetSrc (sourceIp);
1090  newEntry.SetDst (destinationIp);
1092  newEntry.SetOurAdd (previousHop);
1093  newEntry.SetNextHop (ourAddress);
1095  Ptr<Node> node = GetNodeWithAddress (previousHop);
1096  NS_LOG_DEBUG ("The previous node " << previousHop);
1097 
1099  dsr->CancelLinkPacketTimer (newEntry);
1100  }
1101 
1102  // Receive only IP packets and packets destined for other hosts
1103  if (packetType == NetDevice::PACKET_OTHERHOST)
1104  {
1105  //just to minimize debug output
1106  NS_LOG_INFO (this << from << to << packetType << *pktMinusIpHdr);
1107 
1108  uint8_t offset = dsrRouting.GetDsrOptionsOffset (); // Get the offset for option header, 4 bytes in this case
1109  uint8_t nextHeader = dsrRouting.GetNextHeader ();
1110  uint32_t sourceId = dsrRouting.GetSourceId ();
1111  Ipv4Address source = GetIPfromID (sourceId);
1112 
1113  // This packet is used to peek option type
1114  pktMinusIpHdr->RemoveAtStart (offset);
1115  /*
1116  * Peek data to get the option type as well as length and segmentsLeft field
1117  */
1118  uint32_t size = pktMinusIpHdr->GetSize ();
1119  uint8_t *data = new uint8_t[size];
1120  pktMinusIpHdr->CopyData (data, size);
1121  uint8_t optionType = 0;
1122  optionType = *(data);
1123 
1124  Ptr<dsr::DsrOptions> dsrOption;
1125 
1126  if (optionType == 96) // This is the source route option
1127  {
1128  Ipv4Address promiscSource = GetIPfromMAC (Mac48Address::ConvertFrom (from));
1129  dsrOption = GetOption (optionType); // Get the relative DSR option and demux to the process function
1130  NS_LOG_DEBUG (Simulator::Now ().As (Time::S) <<
1131  " DSR node " << m_mainAddress <<
1132  " overhearing packet PID: " << pktMinusIpHdr->GetUid () <<
1133  " from " << promiscSource <<
1134  " to " << GetIPfromMAC (Mac48Address::ConvertFrom (to)) <<
1135  " with source IP " << ipv4Header.GetSource () <<
1136  " and destination IP " << ipv4Header.GetDestination () <<
1137  " and packet : " << *pktMinusDsrHdr);
1138 
1139  bool isPromisc = true; // Set the boolean value isPromisc as true
1140  dsrOption->Process (pktMinusIpHdr, pktMinusDsrHdr, m_mainAddress, source, ipv4Header, nextHeader, isPromisc, promiscSource);
1141  return true;
1142 
1143  }
1144  }
1145  return false;
1146 }
1147 
1148 void
1150  Ipv4Address source,
1151  Ipv4Address destination,
1152  uint8_t protocol)
1153 {
1154  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol);
1155  // Look up routes for the specific destination
1156  DsrRouteCacheEntry toDst;
1157  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1158  // Queue the packet if there is no route pre-existing
1159  if (!findRoute)
1160  {
1162  << " " << m_mainAddress << " there is no route for this packet, queue the packet");
1163 
1164  Ptr<Packet> p = packet->Copy ();
1165  DsrSendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol); // Create a new entry for send buffer
1166  bool result = m_sendBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1167  if (result)
1168  {
1170  << " Add packet PID: " << packet->GetUid () << " to queue. Packet: " << *packet);
1171 
1172  NS_LOG_LOGIC ("Send RREQ to" << destination);
1173  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1174  {
1175  /*
1176  * Call the send request function, it will update the request table entry and ttl there
1177  */
1178  SendInitialRequest (source, destination, protocol);
1179  }
1180  }
1181  }
1182  else
1183  {
1184  Ptr<Packet> cleanP = packet->Copy ();
1185  DsrRoutingHeader dsrRoutingHeader;
1186  dsrRoutingHeader.SetNextHeader (protocol);
1187  dsrRoutingHeader.SetMessageType (2);
1188  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1189  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1190 
1191  DsrOptionSRHeader sourceRoute;
1192  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1193  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1194  if (nextHop == "0.0.0.0")
1195  {
1196  PacketNewRoute (cleanP, source, destination, protocol);
1197  return;
1198  }
1199  uint8_t salvage = 0;
1200  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
1202  if (m_routeCache->IsLinkCache ())
1203  {
1204  m_routeCache->UseExtends (nodeList);
1205  }
1206  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
1207  sourceRoute.SetSalvage (salvage);
1208 
1209  uint8_t length = sourceRoute.GetLength ();
1210  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1211  dsrRoutingHeader.AddDsrOption (sourceRoute);
1212  cleanP->AddHeader (dsrRoutingHeader);
1213  Ptr<const Packet> mtP = cleanP->Copy ();
1214  SetRoute (nextHop, m_mainAddress);
1215  // Put the data packet in the maintenance queue for data packet retransmission
1216  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
1217  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1218  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1219  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1220 
1221  if (result)
1222  {
1223  NetworkKey networkKey;
1224  networkKey.m_ackId = newEntry.GetAckId ();
1225  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1226  networkKey.m_nextHop = newEntry.GetNextHop ();
1227  networkKey.m_source = newEntry.GetSrc ();
1228  networkKey.m_destination = newEntry.GetDst ();
1229 
1230  PassiveKey passiveKey;
1231  passiveKey.m_ackId = 0;
1232  passiveKey.m_source = newEntry.GetSrc ();
1233  passiveKey.m_destination = newEntry.GetDst ();
1234  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1235 
1236  LinkKey linkKey;
1237  linkKey.m_source = newEntry.GetSrc ();
1238  linkKey.m_destination = newEntry.GetDst ();
1239  linkKey.m_ourAdd = newEntry.GetOurAdd ();
1240  linkKey.m_nextHop = newEntry.GetNextHop ();
1241 
1242  m_addressForwardCnt[networkKey] = 0;
1243  m_passiveCnt[passiveKey] = 0;
1244  m_linkCnt[linkKey] = 0;
1245 
1246  if (m_linkAck)
1247  {
1248  ScheduleLinkPacketRetry (newEntry, protocol);
1249  }
1250  else
1251  {
1252  NS_LOG_LOGIC ("Not using link acknowledgment");
1253  if (nextHop != destination)
1254  {
1255  SchedulePassivePacketRetry (newEntry, protocol);
1256  }
1257  else
1258  {
1259  // This is the first network retry
1260  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1261  }
1262  }
1263  }
1264  }
1265 }
1266 
1267 void
1268 DsrRouting::SendUnreachError (Ipv4Address unreachNode, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
1269 {
1270  NS_LOG_FUNCTION (this << unreachNode << destination << originalDst << (uint32_t)salvage << (uint32_t)protocol);
1271  DsrRoutingHeader dsrRoutingHeader;
1272  dsrRoutingHeader.SetNextHeader (protocol);
1273  dsrRoutingHeader.SetMessageType (1);
1274  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
1275  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1276 
1277  DsrOptionRerrUnreachHeader rerrUnreachHeader;
1278  rerrUnreachHeader.SetErrorType (1);
1279  rerrUnreachHeader.SetErrorSrc (m_mainAddress);
1280  rerrUnreachHeader.SetUnreachNode (unreachNode);
1281  rerrUnreachHeader.SetErrorDst (destination);
1282  rerrUnreachHeader.SetOriginalDst (originalDst);
1283  rerrUnreachHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
1284  uint8_t rerrLength = rerrUnreachHeader.GetLength ();
1285 
1286 
1287  DsrRouteCacheEntry toDst;
1288  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1289  // Queue the packet if there is no route pre-existing
1290  Ptr<Packet> newPacket = Create<Packet> ();
1291  if (!findRoute)
1292  {
1293  if (destination == m_mainAddress)
1294  {
1295  NS_LOG_INFO ("We are the error source, send request to original dst " << originalDst);
1296  // Send error request message if we are the source node
1297  SendErrorRequest (rerrUnreachHeader, protocol);
1298  }
1299  else
1300  {
1302  << " " << m_mainAddress << " there is no route for this packet, queue the packet");
1303 
1304  dsrRoutingHeader.SetPayloadLength (rerrLength + 2);
1305  dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
1306  newPacket->AddHeader (dsrRoutingHeader);
1307  Ptr<Packet> p = newPacket->Copy ();
1308  // Save the error packet in the error buffer
1309  DsrErrorBuffEntry newEntry (p, destination, m_mainAddress, unreachNode, m_sendBufferTimeout, protocol);
1310  bool result = m_errorBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1311  if (result)
1312  {
1314  << " Add packet PID: " << p->GetUid () << " to queue. Packet: " << *p);
1315  NS_LOG_LOGIC ("Send RREQ to" << destination);
1316  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1317  {
1318  NS_LOG_DEBUG ("When there is no existing route request for " << destination << ", initialize one");
1319  /*
1320  * Call the send request function, it will update the request table entry and ttl there
1321  */
1322  SendInitialRequest (m_mainAddress, destination, protocol);
1323  }
1324  }
1325  }
1326  }
1327  else
1328  {
1329  std::vector<Ipv4Address> nodeList = toDst.GetVector ();
1330  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);
1331  if (nextHop == "0.0.0.0")
1332  {
1333  NS_LOG_DEBUG ("The route is not right");
1334  PacketNewRoute (newPacket, m_mainAddress, destination, protocol);
1335  return;
1336  }
1337  DsrOptionSRHeader sourceRoute;
1338  sourceRoute.SetNodesAddress (nodeList);
1340  if (m_routeCache->IsLinkCache ())
1341  {
1342  m_routeCache->UseExtends (nodeList);
1343  }
1344  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));
1345  uint8_t srLength = sourceRoute.GetLength ();
1346  uint8_t length = (srLength + rerrLength);
1347 
1348  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1349  dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
1350  dsrRoutingHeader.AddDsrOption (sourceRoute);
1351  newPacket->AddHeader (dsrRoutingHeader);
1352 
1353  SetRoute (nextHop, m_mainAddress);
1354  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1355  m_ipv4Route->SetOutputDevice (dev);
1356  NS_LOG_INFO ("Send the packet to the next hop address " << nextHop << " from " << m_mainAddress << " with the size " << newPacket->GetSize ());
1357 
1358  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1359  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1360  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1361  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1362 
1363  //m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1364 
1366  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
1367 
1368  if (dsrNetworkQueue->Enqueue (newEntry))
1369  {
1370  Scheduler (priority);
1371  }
1372  else
1373  {
1374  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1375  }
1376  }
1377 }
1378 
1379 void
1381  DsrOptionSRHeader &sourceRoute,
1382  Ipv4Address nextHop,
1383  uint8_t protocol,
1384  Ptr<Ipv4Route> route)
1385 {
1386  NS_LOG_FUNCTION (this << rerr << sourceRoute << nextHop << (uint32_t)protocol << route);
1387  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1388  DsrRoutingHeader dsrRoutingHeader;
1389  dsrRoutingHeader.SetNextHeader (protocol);
1390  dsrRoutingHeader.SetMessageType (1);
1391  dsrRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
1392  dsrRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
1393 
1394  uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
1395  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1396  dsrRoutingHeader.AddDsrOption (rerr);
1397  dsrRoutingHeader.AddDsrOption (sourceRoute);
1398  Ptr<Packet> packet = Create<Packet> ();
1399  packet->AddHeader (dsrRoutingHeader);
1400  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1401  route->SetOutputDevice (dev);
1402 
1403  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1404  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1405  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1406  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1407 
1408  //m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
1409 
1411  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, nextHop, Simulator::Now (), route);
1412 
1413  if (dsrNetworkQueue->Enqueue (newEntry))
1414  {
1415  Scheduler (priority);
1416  }
1417  else
1418  {
1419  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1420  }
1421 }
1422 
1423 void
1425  Ipv4Address source,
1426  Ipv4Address destination,
1427  uint8_t protocol,
1428  Ptr<Ipv4Route> route)
1429 {
1430  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
1431  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1432 
1433  if (protocol == 1)
1434  {
1435  NS_LOG_INFO ("Drop packet. Not handling ICMP packet for now");
1436  }
1437  else
1438  {
1439  // Look up routes for the specific destination
1440  DsrRouteCacheEntry toDst;
1441  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1442  // Queue the packet if there is no route pre-existing
1443  if (!findRoute)
1444  {
1446  << " " << m_mainAddress << " there is no route for this packet, queue the packet");
1447 
1448  Ptr<Packet> p = packet->Copy ();
1449  DsrSendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol); // Create a new entry for send buffer
1450  bool result = m_sendBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1451  if (result)
1452  {
1454  << " Add packet PID: " << packet->GetUid () << " to send buffer. Packet: " << *packet);
1455  // Only when there is no existing route request timer when new route request is scheduled
1456  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1457  {
1458  /*
1459  * Call the send request function, it will update the request table entry and ttl value
1460  */
1461  NS_LOG_LOGIC ("Send initial RREQ to " << destination);
1462  SendInitialRequest (source, destination, protocol);
1463  }
1464  else
1465  {
1466  NS_LOG_LOGIC ("There is existing route request timer with request count " << m_rreqTable->GetRreqCnt (destination));
1467  }
1468  }
1469  }
1470  else
1471  {
1472  Ptr<Packet> cleanP = packet->Copy ();
1473  DsrRoutingHeader dsrRoutingHeader;
1474  dsrRoutingHeader.SetNextHeader (protocol);
1475  dsrRoutingHeader.SetMessageType (2);
1476  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1477  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1478 
1479  DsrOptionSRHeader sourceRoute;
1480  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1481  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1482  if (nextHop == "0.0.0.0")
1483  {
1484  PacketNewRoute (cleanP, source, destination, protocol);
1485  return;
1486  }
1487  uint8_t salvage = 0;
1488  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
1490  if (m_routeCache->IsLinkCache ())
1491  {
1492  m_routeCache->UseExtends (nodeList);
1493  }
1494  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
1495  sourceRoute.SetSalvage (salvage);
1496 
1497  uint8_t length = sourceRoute.GetLength ();
1498 
1499  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1500  dsrRoutingHeader.AddDsrOption (sourceRoute);
1501  cleanP->AddHeader (dsrRoutingHeader);
1502 
1503  Ptr<const Packet> mtP = cleanP->Copy ();
1504  NS_LOG_DEBUG ("maintain packet size " << cleanP->GetSize ());
1505  // Put the data packet in the maintenance queue for data packet retransmission
1506  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
1507  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1508  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1509  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1510  if (result)
1511  {
1512  NetworkKey networkKey;
1513  networkKey.m_ackId = newEntry.GetAckId ();
1514  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1515  networkKey.m_nextHop = newEntry.GetNextHop ();
1516  networkKey.m_source = newEntry.GetSrc ();
1517  networkKey.m_destination = newEntry.GetDst ();
1518 
1519  PassiveKey passiveKey;
1520  passiveKey.m_ackId = 0;
1521  passiveKey.m_source = newEntry.GetSrc ();
1522  passiveKey.m_destination = newEntry.GetDst ();
1523  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1524 
1525  LinkKey linkKey;
1526  linkKey.m_source = newEntry.GetSrc ();
1527  linkKey.m_destination = newEntry.GetDst ();
1528  linkKey.m_ourAdd = newEntry.GetOurAdd ();
1529  linkKey.m_nextHop = newEntry.GetNextHop ();
1530 
1531  m_addressForwardCnt[networkKey] = 0;
1532  m_passiveCnt[passiveKey] = 0;
1533  m_linkCnt[linkKey] = 0;
1534 
1535  if (m_linkAck)
1536  {
1537  ScheduleLinkPacketRetry (newEntry, protocol);
1538  }
1539  else
1540  {
1541  NS_LOG_LOGIC ("Not using link acknowledgment");
1542  if (nextHop != destination)
1543  {
1544  SchedulePassivePacketRetry (newEntry, protocol);
1545  }
1546  else
1547  {
1548  // This is the first network retry
1549  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1550  }
1551  }
1552  }
1553 
1554  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
1555  {
1556  // Try to send packet from *previously* queued entries from send buffer if any
1558  &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
1559  }
1560  }
1561  }
1562 }
1563 
1564 uint16_t
1566 {
1567  NS_LOG_FUNCTION (this << packet << nextHop);
1568  // This packet is used to peek option type
1569  Ptr<Packet> dsrP = packet->Copy ();
1570  Ptr<Packet> tmpP = packet->Copy ();
1571 
1572  DsrRoutingHeader dsrRoutingHeader;
1573  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
1574  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
1575  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
1576  uint32_t destinationId = dsrRoutingHeader.GetDestId ();
1577  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1578  tmpP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1579 
1580  // Get the number of routers' address field
1581  uint8_t buf[2];
1582  tmpP->CopyData (buf, sizeof(buf));
1583  uint8_t numberAddress = (buf[1] - 2) / 4;
1584  DsrOptionSRHeader sourceRoute;
1585  sourceRoute.SetNumberAddress (numberAddress);
1586  tmpP->RemoveHeader (sourceRoute); // this is a clean packet without any dsr involved headers
1587 
1588  DsrOptionAckReqHeader ackReq;
1589  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
1590  ackReq.SetAckId (m_ackId);
1591  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
1592  DsrRoutingHeader newDsrRoutingHeader;
1593  newDsrRoutingHeader.SetNextHeader (protocol);
1594  newDsrRoutingHeader.SetMessageType (2);
1595  newDsrRoutingHeader.SetSourceId (sourceId);
1596  newDsrRoutingHeader.SetDestId (destinationId);
1597  newDsrRoutingHeader.SetPayloadLength (length + 4);
1598  newDsrRoutingHeader.AddDsrOption (sourceRoute);
1599  newDsrRoutingHeader.AddDsrOption (ackReq);
1600  dsrP->AddHeader (newDsrRoutingHeader);
1601  // give the dsrP value to packet and then return
1602  packet = dsrP;
1603  return m_ackId;
1604 }
1605 
1606 void
1607 DsrRouting::SendPacket (Ptr<Packet> packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol)
1608 {
1609  NS_LOG_FUNCTION (this << packet << source << nextHop << (uint32_t)protocol);
1610  // Send out the data packet
1611  m_ipv4Route = SetRoute (nextHop, m_mainAddress);
1612  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1613  m_ipv4Route->SetOutputDevice (dev);
1614 
1615  uint32_t priority = GetPriority (DSR_DATA_PACKET);
1616  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1617  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1618  NS_LOG_INFO ("Will be inserting into priority queue number: " << priority);
1619 
1620  //m_downTarget (packet, source, nextHop, GetProtocolNumber (), m_ipv4Route);
1621 
1623  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), m_ipv4Route);
1624 
1625  if (dsrNetworkQueue->Enqueue (newEntry))
1626  {
1627  Scheduler (priority);
1628  }
1629  else
1630  {
1631  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1632  }
1633 }
1634 
1635 void
1636 DsrRouting::Scheduler (uint32_t priority)
1637 {
1638  NS_LOG_FUNCTION (this);
1639  PriorityScheduler (priority, true);
1640 }
1641 
1642 void
1643 DsrRouting::PriorityScheduler (uint32_t priority, bool continueWithFirst)
1644 {
1645  NS_LOG_FUNCTION (this << priority << continueWithFirst);
1646  uint32_t numPriorities;
1647  if (continueWithFirst)
1648  {
1649  numPriorities = 0;
1650  }
1651  else
1652  {
1653  numPriorities = priority;
1654  }
1655  // priorities ranging from 0 to m_numPriorityQueues, with 0 as the highest priority
1656  for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
1657  {
1658  std::map<uint32_t, Ptr<DsrNetworkQueue> >::iterator q = m_priorityQueue.find (i);
1659  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
1660  uint32_t queueSize = dsrNetworkQueue->GetSize ();
1661  if (queueSize == 0)
1662  {
1663  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1664  {
1665  i = 0;
1666  }
1667  else
1668  {
1669  i++;
1670  }
1671  }
1672  else
1673  {
1674  uint32_t totalQueueSize = 0;
1675  for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator j = m_priorityQueue.begin (); j != m_priorityQueue.end (); j++)
1676  {
1677  NS_LOG_INFO ("The size of the network queue for " << j->first << " is " << j->second->GetSize ());
1678  totalQueueSize += j->second->GetSize ();
1679  NS_LOG_INFO ("The total network queue size is " << totalQueueSize);
1680  }
1681  if (totalQueueSize > 5)
1682  {
1683  // Here the queue size is larger than 5, we need to increase the retransmission timer for each packet in the network queue
1685  }
1686  DsrNetworkQueueEntry newEntry;
1687  dsrNetworkQueue->Dequeue (newEntry);
1688  if (SendRealDown (newEntry))
1689  {
1690  NS_LOG_LOGIC ("Packet sent by Dsr. Calling PriorityScheduler after some time");
1691  // packet was successfully sent down. call scheduler after some time
1693  &DsrRouting::PriorityScheduler,this, i, false);
1694  }
1695  else
1696  {
1697  // packet was dropped by Dsr. Call scheduler immediately so that we can
1698  // send another packet immediately.
1699  NS_LOG_LOGIC ("Packet dropped by Dsr. Calling PriorityScheduler immediately");
1701  }
1702 
1703  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1704  {
1705  i = 0;
1706  }
1707  else
1708  {
1709  i++;
1710  }
1711  }
1712  }
1713 }
1714 
1715 void
1717 {
1718  NS_LOG_FUNCTION (this);
1719  // We may want to get the queue first and then we need to save a vector of the entries here and then find
1720  uint32_t priority = GetPriority (DSR_DATA_PACKET);
1721  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1722  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1723 
1724  std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue ();
1725  for (std::vector<DsrNetworkQueueEntry>::iterator i = newNetworkQueue.begin (); i != newNetworkQueue.end (); i++)
1726  {
1727  Ipv4Address nextHop = i->GetNextHopAddress ();
1728  for (std::map<NetworkKey, Timer>::iterator j = m_addressForwardTimer.begin (); j != m_addressForwardTimer.end (); j++)
1729  {
1730  if (nextHop == j->first.m_nextHop)
1731  {
1732  NS_LOG_DEBUG ("The network delay left is " << j->second.GetDelayLeft ());
1733  j->second.SetDelay (j->second.GetDelayLeft () + m_retransIncr);
1734  }
1735  }
1736  }
1737 }
1738 
1739 bool
1741 {
1742  NS_LOG_FUNCTION (this);
1743  Ipv4Address source = newEntry.GetSourceAddress ();
1744  Ipv4Address nextHop = newEntry.GetNextHopAddress ();
1745  Ptr<Packet> packet = newEntry.GetPacket ()->Copy ();
1746  Ptr<Ipv4Route> route = newEntry.GetIpv4Route ();
1747  m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
1748  return true;
1749 }
1750 
1751 void
1752 DsrRouting::SendPacketFromBuffer (DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop, uint8_t protocol)
1753 {
1754  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
1755  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1756 
1757  // Reconstruct the route and Retransmit the data packet
1758  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1759  Ipv4Address destination = nodeList.back ();
1760  Ipv4Address source = nodeList.front (); // Get the source address
1761  NS_LOG_INFO ("The nexthop address " << nextHop << " the source " << source << " the destination " << destination);
1762  /*
1763  * Here we try to find data packet from send buffer, if packet with this destination found, send it out
1764  */
1765  if (m_sendBuffer.Find (destination))
1766  {
1767  NS_LOG_DEBUG ("destination over here " << destination);
1768 
1770  if (m_routeCache->IsLinkCache ())
1771  {
1772  m_routeCache->UseExtends (nodeList);
1773  }
1774  DsrSendBuffEntry entry;
1775  if (m_sendBuffer.Dequeue (destination, entry))
1776  {
1777  Ptr<Packet> packet = entry.GetPacket ()->Copy ();
1778  Ptr<Packet> p = packet->Copy (); // get a copy of the packet
1779  // Set the source route option
1780  DsrRoutingHeader dsrRoutingHeader;
1781  dsrRoutingHeader.SetNextHeader (protocol);
1782  dsrRoutingHeader.SetMessageType (2);
1783  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1784  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1785 
1786  uint8_t length = sourceRoute.GetLength ();
1787  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1788  dsrRoutingHeader.AddDsrOption (sourceRoute);
1789 
1790  p->AddHeader (dsrRoutingHeader);
1791 
1792  Ptr<const Packet> mtP = p->Copy ();
1793  // Put the data packet in the maintenance queue for data packet retransmission
1794  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
1795  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1796  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1797  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1798 
1799  if (result)
1800  {
1801  NetworkKey networkKey;
1802  networkKey.m_ackId = newEntry.GetAckId ();
1803  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1804  networkKey.m_nextHop = newEntry.GetNextHop ();
1805  networkKey.m_source = newEntry.GetSrc ();
1806  networkKey.m_destination = newEntry.GetDst ();
1807 
1808  PassiveKey passiveKey;
1809  passiveKey.m_ackId = 0;
1810  passiveKey.m_source = newEntry.GetSrc ();
1811  passiveKey.m_destination = newEntry.GetDst ();
1812  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1813 
1814  LinkKey linkKey;
1815  linkKey.m_source = newEntry.GetSrc ();
1816  linkKey.m_destination = newEntry.GetDst ();
1817  linkKey.m_ourAdd = newEntry.GetOurAdd ();
1818  linkKey.m_nextHop = newEntry.GetNextHop ();
1819 
1820  m_addressForwardCnt[networkKey] = 0;
1821  m_passiveCnt[passiveKey] = 0;
1822  m_linkCnt[linkKey] = 0;
1823 
1824  if (m_linkAck)
1825  {
1826  ScheduleLinkPacketRetry (newEntry, protocol);
1827  }
1828  else
1829  {
1830  NS_LOG_LOGIC ("Not using link acknowledgment");
1831  if (nextHop != destination)
1832  {
1833  SchedulePassivePacketRetry (newEntry, protocol);
1834  }
1835  else
1836  {
1837  // This is the first network retry
1838  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1839  }
1840  }
1841  }
1842 
1843  NS_LOG_DEBUG ("send buffer size here and the destination " << m_sendBuffer.GetSize () << " " << destination);
1844  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
1845  {
1846  NS_LOG_LOGIC ("Schedule sending the next packet in send buffer");
1848  &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
1849  }
1850  }
1851  else
1852  {
1853  NS_LOG_LOGIC ("All queued packets are out-dated for the destination in send buffer");
1854  }
1855  }
1856  /*
1857  * Here we try to find data packet from send buffer, if packet with this destination found, send it out
1858  */
1859  else if (m_errorBuffer.Find (destination))
1860  {
1861  DsrErrorBuffEntry entry;
1862  if (m_errorBuffer.Dequeue (destination, entry))
1863  {
1864  Ptr<Packet> packet = entry.GetPacket ()->Copy ();
1865  NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
1866 
1867  DsrRoutingHeader dsrRoutingHeader;
1868  Ptr<Packet> copyP = packet->Copy ();
1869  Ptr<Packet> dsrPacket = packet->Copy ();
1870  dsrPacket->RemoveHeader (dsrRoutingHeader);
1871  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1872  copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1873  /*
1874  * Peek data to get the option type as well as length and segmentsLeft field
1875  */
1876  uint32_t size = copyP->GetSize ();
1877  uint8_t *data = new uint8_t[size];
1878  copyP->CopyData (data, size);
1879 
1880  uint8_t optionType = 0;
1881  optionType = *(data);
1882  NS_LOG_DEBUG ("The option type value in send packet " << (uint32_t)optionType);
1883  if (optionType == 3)
1884  {
1885  NS_LOG_DEBUG ("The packet is error packet");
1886  Ptr<dsr::DsrOptions> dsrOption;
1887  DsrOptionHeader dsrOptionHeader;
1888 
1889  uint8_t errorType = *(data + 2);
1890  NS_LOG_DEBUG ("The error type");
1891  if (errorType == 1)
1892  {
1893  NS_LOG_DEBUG ("The packet is route error unreach packet");
1895  copyP->RemoveHeader (rerr);
1896  NS_ASSERT (copyP->GetSize () == 0);
1897  uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
1898 
1899  DsrOptionRerrUnreachHeader newUnreach;
1900  newUnreach.SetErrorType (1);
1901  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
1902  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
1903  newUnreach.SetErrorDst (rerr.GetErrorDst ());
1904  newUnreach.SetOriginalDst (rerr.GetOriginalDst ());
1905  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
1906 
1907  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1908  DsrRoutingHeader newRoutingHeader;
1909  newRoutingHeader.SetNextHeader (protocol);
1910  newRoutingHeader.SetMessageType (1);
1911  newRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
1912  newRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
1913  newRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1914  newRoutingHeader.AddDsrOption (newUnreach);
1915  newRoutingHeader.AddDsrOption (sourceRoute);
1917  if (m_routeCache->IsLinkCache ())
1918  {
1919  m_routeCache->UseExtends (nodeList);
1920  }
1921  SetRoute (nextHop, m_mainAddress);
1922  Ptr<Packet> newPacket = Create<Packet> ();
1923  newPacket->AddHeader (newRoutingHeader); // Add the extension header with rerr and sourceRoute attached to it
1924  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1925  m_ipv4Route->SetOutputDevice (dev);
1926 
1927  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1928  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1929  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1930  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1931 
1932  //m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1933 
1935  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
1936 
1937  if (dsrNetworkQueue->Enqueue (newEntry))
1938  {
1939  Scheduler (priority);
1940  }
1941  else
1942  {
1943  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1944  }
1945  }
1946  }
1947 
1948  if (m_errorBuffer.GetSize () != 0 && m_errorBuffer.Find (destination))
1949  {
1950  NS_LOG_LOGIC ("Schedule sending the next packet in error buffer");
1952  &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
1953  }
1954  }
1955  }
1956  else
1957  {
1958  NS_LOG_DEBUG ("Packet not found in either the send or error buffer");
1959  }
1960 }
1961 
1962 bool
1963 DsrRouting::PassiveEntryCheck (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft,
1964  uint16_t fragmentOffset, uint16_t identification, bool saveEntry)
1965 {
1966  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
1967 
1968  Ptr<Packet> p = packet->Copy ();
1969  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
1970  DsrPassiveBuffEntry newEntry;
1971  newEntry.SetPacket (p);
1972  newEntry.SetSource (source);
1973  newEntry.SetDestination (destination);
1974  newEntry.SetIdentification (identification);
1975  newEntry.SetFragmentOffset (fragmentOffset);
1976  newEntry.SetSegsLeft (segsLeft); // We try to make sure the segments left is larger for 1
1977 
1978 
1979  NS_LOG_DEBUG ("The passive buffer size " << m_passiveBuffer->GetSize ());
1980 
1981  if (m_passiveBuffer->AllEqual (newEntry) && (!saveEntry))
1982  {
1983  // The PromiscEqual function will remove the maintain buffer entry if equal value found
1984  // It only compares the source and destination address, ackId, and the segments left value
1985  NS_LOG_DEBUG ("We get the all equal for passive buffer here");
1986 
1987  DsrMaintainBuffEntry mbEntry;
1988  mbEntry.SetPacket (p);
1989  mbEntry.SetSrc (source);
1990  mbEntry.SetDst (destination);
1991  mbEntry.SetAckId (0);
1992  mbEntry.SetSegsLeft (segsLeft + 1);
1993 
1994  CancelPassivePacketTimer (mbEntry);
1995  return true;
1996  }
1997  if (saveEntry)
1998  {
2000  m_passiveBuffer->Enqueue (newEntry);
2001  }
2002  return false;
2003 }
2004 
2005 bool
2007  uint8_t segsLeft)
2008 {
2009  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
2010 
2011  NS_LOG_DEBUG ("Cancel the passive timer");
2012 
2013  Ptr<Packet> p = packet->Copy ();
2014  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2015  DsrMaintainBuffEntry newEntry;
2016  newEntry.SetPacket (p);
2017  newEntry.SetSrc (source);
2018  newEntry.SetDst (destination);
2019  newEntry.SetAckId (0);
2020  newEntry.SetSegsLeft (segsLeft + 1);
2021 
2022  if (m_maintainBuffer.PromiscEqual (newEntry))
2023  {
2024  // The PromiscEqual function will remove the maintain buffer entry if equal value found
2025  // It only compares the source and destination address, ackId, and the segments left value
2026  CancelPassivePacketTimer (newEntry);
2027  return true;
2028  }
2029  return false;
2030 }
2031 
2032 void
2033 DsrRouting::CallCancelPacketTimer (uint16_t ackId, Ipv4Header const& ipv4Header, Ipv4Address realSrc, Ipv4Address realDst)
2034 {
2035  NS_LOG_FUNCTION (this << (uint32_t)ackId << ipv4Header << realSrc << realDst);
2036  Ipv4Address sender = ipv4Header.GetDestination ();
2037  Ipv4Address receiver = ipv4Header.GetSource ();
2038  /*
2039  * Create a packet to fill maintenance buffer, not used to compare with maintenance entry
2040  * The reason is ack header doesn't have the original packet copy
2041  */
2042  Ptr<Packet> mainP = Create<Packet> ();
2043  DsrMaintainBuffEntry newEntry (/*Packet=*/ mainP, /*ourAddress=*/ sender, /*nextHop=*/ receiver,
2044  /*source=*/ realSrc, /*destination=*/ realDst, /*ackId=*/ ackId,
2045  /*SegsLeft=*/ 0, /*expire time=*/ Simulator::Now ());
2046  CancelNetworkPacketTimer (newEntry); // Only need to cancel network packet timer
2047 }
2048 
2049 void
2051 {
2052  NS_LOG_FUNCTION (this);
2053  CancelLinkPacketTimer (mb);
2056 }
2057 
2058 void
2060 {
2061  NS_LOG_FUNCTION (this);
2062  LinkKey linkKey;
2063  linkKey.m_ourAdd = mb.GetOurAdd ();
2064  linkKey.m_nextHop = mb.GetNextHop ();
2065  linkKey.m_source = mb.GetSrc ();
2066  linkKey.m_destination = mb.GetDst ();
2067  /*
2068  * Here we have found the entry for send retries, so we get the value and increase it by one
2069  */
2071  m_linkCnt[linkKey] = 0;
2072  m_linkCnt.erase (linkKey);
2073 
2074  // TODO if find the linkkey, we need to remove it
2075 
2076  // Find the network acknowledgment timer
2077  std::map<LinkKey, Timer>::const_iterator i =
2078  m_linkAckTimer.find (linkKey);
2079  if (i == m_linkAckTimer.end ())
2080  {
2081  NS_LOG_INFO ("did not find the link timer");
2082  }
2083  else
2084  {
2085  NS_LOG_INFO ("did find the link timer");
2086  /*
2087  * Schedule the packet retry
2088  * Push back the nextHop, source, destination address
2089  */
2090  m_linkAckTimer[linkKey].Cancel ();
2091  if (m_linkAckTimer[linkKey].IsRunning ())
2092  {
2093  NS_LOG_INFO ("Timer not canceled");
2094  }
2095  m_linkAckTimer.erase (linkKey);
2096  }
2097 
2098  // Erase the maintenance entry
2099  // yet this does not check the segments left value here
2100  NS_LOG_DEBUG ("The link buffer size " << m_maintainBuffer.GetSize ());
2101  if (m_maintainBuffer.LinkEqual (mb))
2102  {
2103  NS_LOG_INFO ("Link acknowledgment received, remove same maintenance buffer entry");
2104  }
2105 }
2106 
2107 void
2109 {
2110  NS_LOG_FUNCTION (this);
2111  NetworkKey networkKey;
2112  networkKey.m_ackId = mb.GetAckId ();
2113  networkKey.m_ourAdd = mb.GetOurAdd ();
2114  networkKey.m_nextHop = mb.GetNextHop ();
2115  networkKey.m_source = mb.GetSrc ();
2116  networkKey.m_destination = mb.GetDst ();
2117  /*
2118  * Here we have found the entry for send retries, so we get the value and increase it by one
2119  */
2120  m_addressForwardCnt[networkKey] = 0;
2121  m_addressForwardCnt.erase (networkKey);
2122 
2123  NS_LOG_INFO ("ackId " << mb.GetAckId () << " ourAdd " << mb.GetOurAdd () << " nextHop " << mb.GetNextHop ()
2124  << " source " << mb.GetSrc () << " destination " << mb.GetDst ()
2125  << " segsLeft " << (uint32_t)mb.GetSegsLeft ()
2126  );
2127  // Find the network acknowledgment timer
2128  std::map<NetworkKey, Timer>::const_iterator i =
2129  m_addressForwardTimer.find (networkKey);
2130  if (i == m_addressForwardTimer.end ())
2131  {
2132  NS_LOG_INFO ("did not find the packet timer");
2133  }
2134  else
2135  {
2136  NS_LOG_INFO ("did find the packet timer");
2137  /*
2138  * Schedule the packet retry
2139  * Push back the nextHop, source, destination address
2140  */
2141  m_addressForwardTimer[networkKey].Cancel ();
2142  if (m_addressForwardTimer[networkKey].IsRunning ())
2143  {
2144  NS_LOG_INFO ("Timer not canceled");
2145  }
2146  m_addressForwardTimer.erase (networkKey);
2147  }
2148  // Erase the maintenance entry
2149  // yet this does not check the segments left value here
2150  if (m_maintainBuffer.NetworkEqual (mb))
2151  {
2152  NS_LOG_INFO ("Remove same maintenance buffer entry based on network acknowledgment");
2153  }
2154 }
2155 
2156 void
2158 {
2159  NS_LOG_FUNCTION (this);
2160  PassiveKey passiveKey;
2161  passiveKey.m_ackId = 0;
2162  passiveKey.m_source = mb.GetSrc ();
2163  passiveKey.m_destination = mb.GetDst ();
2164  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2165 
2166  m_passiveCnt[passiveKey] = 0;
2167  m_passiveCnt.erase (passiveKey);
2168 
2169  // Find the passive acknowledgment timer
2170  std::map<PassiveKey, Timer>::const_iterator j =
2171  m_passiveAckTimer.find (passiveKey);
2172  if (j == m_passiveAckTimer.end ())
2173  {
2174  NS_LOG_INFO ("did not find the passive timer");
2175  }
2176  else
2177  {
2178  NS_LOG_INFO ("find the passive timer");
2179  /*
2180  * Cancel passive acknowledgment timer
2181  */
2182  m_passiveAckTimer[passiveKey].Cancel ();
2183  if (m_passiveAckTimer[passiveKey].IsRunning ())
2184  {
2185  NS_LOG_INFO ("Timer not canceled");
2186  }
2187  m_passiveAckTimer.erase (passiveKey);
2188  }
2189 }
2190 
2191 void
2193 {
2194  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
2195 
2196  DsrMaintainBuffEntry entry;
2197  std::vector<Ipv4Address> previousErrorDst;
2198  if (m_maintainBuffer.Dequeue (nextHop, entry))
2199  {
2200  Ipv4Address source = entry.GetSrc ();
2201  Ipv4Address destination = entry.GetDst ();
2202 
2203  Ptr<Packet> dsrP = entry.GetPacket ()->Copy ();
2204  Ptr<Packet> p = dsrP->Copy ();
2205  Ptr<Packet> packet = dsrP->Copy ();
2206  DsrRoutingHeader dsrRoutingHeader;
2207  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
2208  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2209  p->RemoveAtStart (offset);
2210 
2211  // Get the number of routers' address field
2212  uint8_t buf[2];
2213  p->CopyData (buf, sizeof(buf));
2214  uint8_t numberAddress = (buf[1] - 2) / 4;
2215  NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
2216  DsrOptionSRHeader sourceRoute;
2217  sourceRoute.SetNumberAddress (numberAddress);
2218  p->RemoveHeader (sourceRoute);
2219  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
2220  uint8_t salvage = sourceRoute.GetSalvage ();
2221  Ipv4Address address1 = nodeList[1];
2222  PrintVector (nodeList);
2223 
2224  /*
2225  * If the salvage is not 0, use the first address in the route as the error dst in error header
2226  * otherwise use the source of packet as the error destination
2227  */
2228  Ipv4Address errorDst;
2229  if (salvage)
2230  {
2231  errorDst = address1;
2232  }
2233  else
2234  {
2235  errorDst = source;
2236  }
2238  if (std::find (previousErrorDst.begin (), previousErrorDst.end (), destination) == previousErrorDst.end ())
2239  {
2240  NS_LOG_DEBUG ("have not seen this dst before " << errorDst << " in " << previousErrorDst.size ());
2241  SendUnreachError (nextHop, errorDst, destination, salvage, protocol);
2242  previousErrorDst.push_back (errorDst);
2243  }
2244 
2245  /*
2246  * Cancel the packet timer and then salvage the data packet
2247  */
2248 
2249  CancelPacketAllTimer (entry);
2250  SalvagePacket (packet, source, destination, protocol);
2251 
2252  if (m_maintainBuffer.GetSize () && m_maintainBuffer.Find (nextHop))
2253  {
2254  NS_LOG_INFO ("Cancel the packet timer for next maintenance entry");
2256  &DsrRouting::CancelPacketTimerNextHop,this,nextHop,protocol);
2257  }
2258  }
2259  else
2260  {
2261  NS_LOG_INFO ("Maintenance buffer entry not found");
2262  }
2264 }
2265 
2266 void
2268 {
2269  NS_LOG_FUNCTION (this << packet << source << dst << (uint32_t)protocol);
2270  // Create two copies of packet
2271  Ptr<Packet> p = packet->Copy ();
2272  Ptr<Packet> newPacket = packet->Copy ();
2273  // Remove the routing header in a whole to get a clean packet
2274  DsrRoutingHeader dsrRoutingHeader;
2275  p->RemoveHeader (dsrRoutingHeader);
2276  // Remove offset of dsr routing header
2277  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2278  newPacket->RemoveAtStart (offset);
2279 
2280  // Get the number of routers' address field
2281  uint8_t buf[2];
2282  newPacket->CopyData (buf, sizeof(buf));
2283  uint8_t numberAddress = (buf[1] - 2) / 4;
2284 
2285  DsrOptionSRHeader sourceRoute;
2286  sourceRoute.SetNumberAddress (numberAddress);
2287  newPacket->RemoveHeader (sourceRoute);
2288  uint8_t salvage = sourceRoute.GetSalvage ();
2289  /*
2290  * Look in the route cache for other routes for this destination
2291  */
2292  DsrRouteCacheEntry toDst;
2293  bool findRoute = m_routeCache->LookupRoute (dst, toDst);
2294  if (findRoute && (salvage < m_maxSalvageCount))
2295  {
2296  NS_LOG_DEBUG ("We have found a route for the packet");
2297  DsrRoutingHeader newDsrRoutingHeader;
2298  newDsrRoutingHeader.SetNextHeader (protocol);
2299  newDsrRoutingHeader.SetMessageType (2);
2300  newDsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2301  newDsrRoutingHeader.SetDestId (GetIDfromIP (dst));
2302 
2303  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
2304  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
2305  if (nextHop == "0.0.0.0")
2306  {
2307  PacketNewRoute (p, source, dst, protocol);
2308  return;
2309  }
2310  // Increase the salvage count by 1
2311  salvage++;
2312  DsrOptionSRHeader sourceRoute;
2313  sourceRoute.SetSalvage (salvage);
2314  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
2315  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
2317  if (m_routeCache->IsLinkCache ())
2318  {
2319  m_routeCache->UseExtends (nodeList);
2320  }
2321  uint8_t length = sourceRoute.GetLength ();
2322  NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ()));
2323  newDsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2324  newDsrRoutingHeader.AddDsrOption (sourceRoute);
2325  p->AddHeader (newDsrRoutingHeader);
2326 
2327  SetRoute (nextHop, m_mainAddress);
2328  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
2329  m_ipv4Route->SetOutputDevice (dev);
2330 
2331  // Send out the data packet
2332  uint32_t priority = GetPriority (DSR_DATA_PACKET);
2333  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2334  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2335  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2336 
2337  //m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
2338 
2340  DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
2341 
2342  if (dsrNetworkQueue->Enqueue (newEntry))
2343  {
2344  Scheduler (priority);
2345  }
2346  else
2347  {
2348  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2349  }
2350 
2351  /*
2352  * Mark the next hop address in blacklist
2353  */
2354 // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2355 // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2356  }
2357  else
2358  {
2359  NS_LOG_DEBUG ("Will not salvage this packet, silently drop");
2360  }
2361 }
2362 
2363 void
2365  uint8_t protocol)
2366 {
2367  NS_LOG_FUNCTION (this << (uint32_t) protocol);
2368 
2369  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2370  Ipv4Address source = mb.GetSrc ();
2371  Ipv4Address nextHop = mb.GetNextHop ();
2372 
2373  // Send the data packet out before schedule the next packet transmission
2374  SendPacket (p, source, nextHop, protocol);
2375 
2376  LinkKey linkKey;
2377  linkKey.m_source = mb.GetSrc ();
2378  linkKey.m_destination = mb.GetDst ();
2379  linkKey.m_ourAdd = mb.GetOurAdd ();
2380  linkKey.m_nextHop = mb.GetNextHop ();
2381 
2382  if (m_linkAckTimer.find (linkKey) == m_linkAckTimer.end ())
2383  {
2385  m_linkAckTimer[linkKey] = timer;
2386  }
2387  m_linkAckTimer[linkKey].SetFunction (&DsrRouting::LinkScheduleTimerExpire, this);
2388  m_linkAckTimer[linkKey].Cancel ();
2389  m_linkAckTimer[linkKey].SetArguments (mb, protocol);
2390  m_linkAckTimer[linkKey].Schedule (m_linkAckTimeout);
2391 }
2392 
2393 void
2395  uint8_t protocol)
2396 {
2397  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2398 
2399  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2400  Ipv4Address source = mb.GetSrc ();
2401  Ipv4Address nextHop = mb.GetNextHop ();
2402 
2403  // Send the data packet out before schedule the next packet transmission
2404  SendPacket (p, source, nextHop, protocol);
2405 
2406  PassiveKey passiveKey;
2407  passiveKey.m_ackId = 0;
2408  passiveKey.m_source = mb.GetSrc ();
2409  passiveKey.m_destination = mb.GetDst ();
2410  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2411 
2412  if (m_passiveAckTimer.find (passiveKey) == m_passiveAckTimer.end ())
2413  {
2415  m_passiveAckTimer[passiveKey] = timer;
2416  }
2417  NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
2418  m_passiveAckTimer[passiveKey].SetFunction (&DsrRouting::PassiveScheduleTimerExpire, this);
2419  m_passiveAckTimer[passiveKey].Cancel ();
2420  m_passiveAckTimer[passiveKey].SetArguments (mb, protocol);
2421  m_passiveAckTimer[passiveKey].Schedule (m_passiveAckTimeout);
2422 }
2423 
2424 void
2426  bool isFirst,
2427  uint8_t protocol)
2428 {
2429  Ptr<Packet> p = Create<Packet> ();
2430  Ptr<Packet> dsrP = Create<Packet> ();
2431  // The new entry will be used for retransmission
2432  NetworkKey networkKey;
2433  Ipv4Address nextHop = mb.GetNextHop ();
2434  NS_LOG_DEBUG ("is the first retry or not " << isFirst);
2435  if (isFirst)
2436  {
2437  // This is the very first network packet retry
2438  p = mb.GetPacket ()->Copy ();
2439  // Here we add the ack request header to the data packet for network acknowledgement
2440  uint16_t ackId = AddAckReqHeader (p, nextHop);
2441 
2442  Ipv4Address source = mb.GetSrc ();
2443  Ipv4Address nextHop = mb.GetNextHop ();
2444  // Send the data packet out before schedule the next packet transmission
2445  SendPacket (p, source, nextHop, protocol);
2446 
2447  dsrP = p->Copy ();
2448  DsrMaintainBuffEntry newEntry = mb;
2449  // The function AllEqual will find the exact entry and delete it if found
2451  newEntry.SetPacket (dsrP);
2452  newEntry.SetAckId (ackId);
2453  newEntry.SetExpireTime (m_maxMaintainTime);
2454 
2455  networkKey.m_ackId = newEntry.GetAckId ();
2456  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2457  networkKey.m_nextHop = newEntry.GetNextHop ();
2458  networkKey.m_source = newEntry.GetSrc ();
2459  networkKey.m_destination = newEntry.GetDst ();
2460 
2461  m_addressForwardCnt[networkKey] = 0;
2462  if (!m_maintainBuffer.Enqueue (newEntry))
2463  {
2464  NS_LOG_ERROR ("Failed to enqueue packet retry");
2465  }
2466 
2467  if (m_addressForwardTimer.find (networkKey) == m_addressForwardTimer.end ())
2468  {
2470  m_addressForwardTimer[networkKey] = timer;
2471  }
2472 
2473  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2474  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2475  m_addressForwardTimer[networkKey].Cancel ();
2476  m_addressForwardTimer[networkKey].SetArguments (newEntry, protocol);
2477  NS_LOG_DEBUG ("The packet retries time for " << newEntry.GetAckId () << " is " << m_sendRetries
2478  << " and the delay time is " << Time (2 * m_nodeTraversalTime).As (Time::S));
2479  // Back-off mechanism
2480  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_nodeTraversalTime));
2481  }
2482  else
2483  {
2484  networkKey.m_ackId = mb.GetAckId ();
2485  networkKey.m_ourAdd = mb.GetOurAdd ();
2486  networkKey.m_nextHop = mb.GetNextHop ();
2487  networkKey.m_source = mb.GetSrc ();
2488  networkKey.m_destination = mb.GetDst ();
2489  /*
2490  * Here we have found the entry for send retries, so we get the value and increase it by one
2491  */
2492  m_sendRetries = m_addressForwardCnt[networkKey];
2493  NS_LOG_DEBUG ("The packet retry we have done " << m_sendRetries);
2494 
2495  p = mb.GetPacket ()->Copy ();
2496  dsrP = mb.GetPacket ()->Copy ();
2497 
2498  Ipv4Address source = mb.GetSrc ();
2499  Ipv4Address nextHop = mb.GetNextHop ();
2500  // Send the data packet out before schedule the next packet transmission
2501  SendPacket (p, source, nextHop, protocol);
2502 
2503  NS_LOG_DEBUG ("The packet with dsr header " << dsrP->GetSize ());
2504  networkKey.m_ackId = mb.GetAckId ();
2505  networkKey.m_ourAdd = mb.GetOurAdd ();
2506  networkKey.m_nextHop = mb.GetNextHop ();
2507  networkKey.m_source = mb.GetSrc ();
2508  networkKey.m_destination = mb.GetDst ();
2509  /*
2510  * If a data packet has been attempted SendRetries times at the maximum TTL without
2511  * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2512  * dropped from the send buffer
2513  *
2514  * The maxMaintRexmt also needs to decrease one for the passive ack packet
2515  */
2516  /*
2517  * Check if the send retry time for a certain packet has already passed max maintenance retransmission
2518  * time or not
2519  */
2520 
2521  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2522  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2523  m_addressForwardTimer[networkKey].Cancel ();
2524  m_addressForwardTimer[networkKey].SetArguments (mb, protocol);
2525  NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId () << " is " << m_sendRetries
2526  << " and the delay time is " << Time (2 * m_sendRetries * m_nodeTraversalTime).As (Time::S));
2527  // Back-off mechanism
2528  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries * m_nodeTraversalTime));
2529  }
2530 }
2531 
2532 void
2534  uint8_t protocol)
2535 {
2536  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2537  Ipv4Address nextHop = mb.GetNextHop ();
2538  Ptr<const Packet> packet = mb.GetPacket ();
2539  SetRoute (nextHop, m_mainAddress);
2540  Ptr<Packet> p = packet->Copy ();
2541 
2542  LinkKey lk;
2543  lk.m_source = mb.GetSrc ();
2544  lk.m_destination = mb.GetDst ();
2545  lk.m_ourAdd = mb.GetOurAdd ();
2546  lk.m_nextHop = mb.GetNextHop ();
2547 
2548  // Cancel passive ack timer
2549  m_linkAckTimer[lk].Cancel ();
2550  if (m_linkAckTimer[lk].IsRunning ())
2551  {
2552  NS_LOG_DEBUG ("Timer not canceled");
2553  }
2554  m_linkAckTimer.erase (lk);
2555 
2556  // Increase the send retry times
2557  m_linkRetries = m_linkCnt[lk];
2559  {
2560  m_linkCnt[lk] = ++m_linkRetries;
2561  ScheduleLinkPacketRetry (mb, protocol);
2562  }
2563  else
2564  {
2565  NS_LOG_INFO ("We need to send error messages now");
2566 
2567  // Delete all the routes including the links
2568  m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
2569  /*
2570  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2571  * Also salvage the packet for the all the packet destined for the nextHop address
2572  * this is also responsible for send unreachable error back to source
2573  */
2574  CancelPacketTimerNextHop (nextHop, protocol);
2575  }
2576 }
2577 
2578 void
2580  uint8_t protocol)
2581 {
2582  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2583  Ipv4Address nextHop = mb.GetNextHop ();
2584  Ptr<const Packet> packet = mb.GetPacket ();
2585  SetRoute (nextHop, m_mainAddress);
2586  Ptr<Packet> p = packet->Copy ();
2587 
2588  PassiveKey pk;
2589  pk.m_ackId = 0;
2590  pk.m_source = mb.GetSrc ();
2591  pk.m_destination = mb.GetDst ();
2592  pk.m_segsLeft = mb.GetSegsLeft ();
2593 
2594  // Cancel passive ack timer
2595  m_passiveAckTimer[pk].Cancel ();
2596  if (m_passiveAckTimer[pk].IsRunning ())
2597  {
2598  NS_LOG_DEBUG ("Timer not canceled");
2599  }
2600  m_passiveAckTimer.erase (pk);
2601 
2602  // Increase the send retry times
2605  {
2607  SchedulePassivePacketRetry (mb, protocol);
2608  }
2609  else
2610  {
2611  // This is the first network acknowledgement retry
2612  // Cancel the passive packet timer now and remove maintenance buffer entry for it
2614  ScheduleNetworkPacketRetry (mb, true, protocol);
2615  }
2616 }
2617 
2618 int64_t
2620 {
2621  NS_LOG_FUNCTION (this << stream);
2623  return 1;
2624 }
2625 
2626 void
2628  uint8_t protocol)
2629 {
2630  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2631  Ipv4Address source = mb.GetSrc ();
2632  Ipv4Address nextHop = mb.GetNextHop ();
2633  Ipv4Address dst = mb.GetDst ();
2634 
2635  NetworkKey networkKey;
2636  networkKey.m_ackId = mb.GetAckId ();
2637  networkKey.m_ourAdd = mb.GetOurAdd ();
2638  networkKey.m_nextHop = nextHop;
2639  networkKey.m_source = source;
2640  networkKey.m_destination = dst;
2641 
2642  // Increase the send retry times
2643  m_sendRetries = m_addressForwardCnt[networkKey];
2644 
2646  {
2647  // Delete all the routes including the links
2648  m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
2649  /*
2650  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2651  * Also salvage the packet for the all the packet destined for the nextHop address
2652  */
2653  CancelPacketTimerNextHop (nextHop, protocol);
2654  }
2655  else
2656  {
2657  m_addressForwardCnt[networkKey] = ++m_sendRetries;
2658  ScheduleNetworkPacketRetry (mb, false, protocol);
2659  }
2660 }
2661 
2662 void
2664  DsrOptionSRHeader &sourceRoute,
2665  Ipv4Header const& ipv4Header,
2666  Ipv4Address source,
2667  Ipv4Address nextHop,
2668  Ipv4Address targetAddress,
2669  uint8_t protocol,
2670  Ptr<Ipv4Route> route)
2671 {
2672  NS_LOG_FUNCTION (this << packet << sourceRoute << source << nextHop << targetAddress << (uint32_t)protocol << route);
2673  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2674 
2675  DsrRoutingHeader dsrRoutingHeader;
2676  dsrRoutingHeader.SetNextHeader (protocol);
2677  dsrRoutingHeader.SetMessageType (2);
2678  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2679  dsrRoutingHeader.SetDestId (GetIDfromIP (targetAddress));
2680 
2681  // We get the salvage value in sourceRoute header and set it to route error header if triggered error
2682  Ptr<Packet> p = packet->Copy ();
2683  uint8_t length = sourceRoute.GetLength ();
2684  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2685  dsrRoutingHeader.AddDsrOption (sourceRoute);
2686  p->AddHeader (dsrRoutingHeader);
2687 
2688  Ptr<const Packet> mtP = p->Copy ();
2689 
2690  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
2691  /*source=*/ source, /*destination=*/ targetAddress, /*ackId=*/ m_ackId,
2692  /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
2693  bool result = m_maintainBuffer.Enqueue (newEntry);
2694 
2695  if (result)
2696  {
2697  NetworkKey networkKey;
2698  networkKey.m_ackId = newEntry.GetAckId ();
2699  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2700  networkKey.m_nextHop = newEntry.GetNextHop ();
2701  networkKey.m_source = newEntry.GetSrc ();
2702  networkKey.m_destination = newEntry.GetDst ();
2703 
2704  PassiveKey passiveKey;
2705  passiveKey.m_ackId = 0;
2706  passiveKey.m_source = newEntry.GetSrc ();
2707  passiveKey.m_destination = newEntry.GetDst ();
2708  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
2709 
2710  LinkKey linkKey;
2711  linkKey.m_source = newEntry.GetSrc ();
2712  linkKey.m_destination = newEntry.GetDst ();
2713  linkKey.m_ourAdd = newEntry.GetOurAdd ();
2714  linkKey.m_nextHop = newEntry.GetNextHop ();
2715 
2716  m_addressForwardCnt[networkKey] = 0;
2717  m_passiveCnt[passiveKey] = 0;
2718  m_linkCnt[linkKey] = 0;
2719 
2720  if (m_linkAck)
2721  {
2722  ScheduleLinkPacketRetry (newEntry, protocol);
2723  }
2724  else
2725  {
2726  NS_LOG_LOGIC ("Not using link acknowledgment");
2727  if (nextHop != targetAddress)
2728  {
2729  SchedulePassivePacketRetry (newEntry, protocol);
2730  }
2731  else
2732  {
2733  // This is the first network retry
2734  ScheduleNetworkPacketRetry (newEntry, true, protocol);
2735  }
2736  }
2737  }
2738 }
2739 
2740 void
2742  Ipv4Address destination,
2743  uint8_t protocol)
2744 {
2745  NS_LOG_FUNCTION (this << source << destination << (uint32_t)protocol);
2746  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2747  Ptr<Packet> packet = Create<Packet> ();
2748  // Create an empty Ipv4 route ptr
2749  Ptr<Ipv4Route> route;
2750  /*
2751  * Construct the route request option header
2752  */
2753  DsrRoutingHeader dsrRoutingHeader;
2754  dsrRoutingHeader.SetNextHeader (protocol);
2755  dsrRoutingHeader.SetMessageType (1);
2756  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2757  dsrRoutingHeader.SetDestId (255);
2758 
2759  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2760  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2761  rreqHeader.SetTarget (destination);
2762  m_requestId = m_rreqTable->CheckUniqueRreqId (destination); // Check the Id cache for duplicate ones
2763  rreqHeader.SetId (m_requestId);
2764 
2765  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2766  uint8_t length = rreqHeader.GetLength ();
2767  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2768  packet->AddHeader (dsrRoutingHeader);
2769 
2770  // Schedule the route requests retry with non-propagation set true
2771  bool nonProp = true;
2772  std::vector<Ipv4Address> address;
2773  address.push_back (source);
2774  address.push_back (destination);
2775  /*
2776  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2777  */
2778  SocketIpTtlTag tag;
2779  tag.SetTtl (0);
2780  Ptr<Packet> nonPropPacket = packet->Copy ();
2781  nonPropPacket->AddPacketTag (tag);
2782  // Increase the request count
2783  m_rreqTable->FindAndUpdate (destination);
2784  SendRequest (nonPropPacket, source);
2785  // Schedule the next route request
2786  ScheduleRreqRetry (packet, address, nonProp, m_requestId, protocol);
2787 }
2788 
2789 void
2791 {
2792  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2793  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2794  uint8_t salvage = rerr.GetSalvage ();
2795  Ipv4Address dst = rerr.GetOriginalDst ();
2796  NS_LOG_DEBUG ("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc () << " error destination " << rerr.GetErrorDst ()
2797  << " error next hop " << rerr.GetUnreachNode () << " original dst " << rerr.GetOriginalDst ()
2798  );
2799  DsrRouteCacheEntry toDst;
2800  if (m_routeCache->LookupRoute (dst, toDst))
2801  {
2802  /*
2803  * Found a route the dst, construct the source route option header
2804  */
2805  DsrOptionSRHeader sourceRoute;
2806  std::vector<Ipv4Address> ip = toDst.GetVector ();
2807  sourceRoute.SetNodesAddress (ip);
2809  if (m_routeCache->IsLinkCache ())
2810  {
2811  m_routeCache->UseExtends (ip);
2812  }
2813  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
2814  sourceRoute.SetSalvage (salvage);
2815  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
2816  NS_LOG_DEBUG ("The nextHop address " << nextHop);
2817  Ptr<Packet> packet = Create<Packet> ();
2818  if (nextHop == "0.0.0.0")
2819  {
2820  NS_LOG_DEBUG ("Error next hop address");
2821  PacketNewRoute (packet, m_mainAddress, dst, protocol);
2822  return;
2823  }
2824  SetRoute (nextHop, m_mainAddress);
2825  CancelRreqTimer (dst, true);
2827  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
2828  {
2829  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
2830  }
2831  NS_LOG_LOGIC ("Route to " << dst << " found");
2832  return;
2833  }
2834  else
2835  {
2836  NS_LOG_INFO ("No route found, initiate route error request");
2837  Ptr<Packet> packet = Create<Packet> ();
2838  Ipv4Address originalDst = rerr.GetOriginalDst ();
2839  // Create an empty route ptr
2840  Ptr<Ipv4Route> route = 0;
2841  /*
2842  * Construct the route request option header
2843  */
2844  DsrRoutingHeader dsrRoutingHeader;
2845  dsrRoutingHeader.SetNextHeader (protocol);
2846  dsrRoutingHeader.SetMessageType (1);
2847  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
2848  dsrRoutingHeader.SetDestId (255);
2849 
2850  Ptr<Packet> dstP = Create<Packet> ();
2851  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2852  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2853  rreqHeader.SetTarget (originalDst);
2854  m_requestId = m_rreqTable->CheckUniqueRreqId (originalDst); // Check the Id cache for duplicate ones
2855  rreqHeader.SetId (m_requestId);
2856 
2857  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2858  dsrRoutingHeader.AddDsrOption (rerr);
2859  uint8_t length = rreqHeader.GetLength () + rerr.GetLength ();
2860  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
2861  dstP->AddHeader (dsrRoutingHeader);
2862  // Schedule the route requests retry, propagate the route request message as it contains error
2863  bool nonProp = false;
2864  std::vector<Ipv4Address> address;
2865  address.push_back (m_mainAddress);
2866  address.push_back (originalDst);
2867  /*
2868  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2869  */
2870  SocketIpTtlTag tag;
2871  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
2872  Ptr<Packet> propPacket = dstP->Copy ();
2873  propPacket->AddPacketTag (tag);
2874 
2875  if ((m_addressReqTimer.find (originalDst) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (originalDst) == m_nonPropReqTimer.end ()))
2876  {
2877  NS_LOG_INFO ("Only when there is no existing route request time when the initial route request is scheduled");
2878  SendRequest (propPacket, m_mainAddress);
2879  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2880  }
2881  else
2882  {
2883  NS_LOG_INFO ("There is existing route request, find the existing route request entry");
2884  /*
2885  * Cancel the route request timer first before scheduling the route request
2886  * in this case, we do not want to remove the route request entry, so the isRemove value is false
2887  */
2888  CancelRreqTimer (originalDst, false);
2889  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2890  }
2891  }
2892 }
2893 
2894 void
2896 {
2897  NS_LOG_FUNCTION (this << dst << isRemove);
2898  // Cancel the non propagation request timer if found
2899  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2900  {
2901  NS_LOG_DEBUG ("Did not find the non-propagation timer");
2902  }
2903  else
2904  {
2905  NS_LOG_DEBUG ("did find the non-propagation timer");
2906  }
2907  m_nonPropReqTimer[dst].Cancel ();
2908 
2909  if (m_nonPropReqTimer[dst].IsRunning ())
2910  {
2911  NS_LOG_DEBUG ("Timer not canceled");
2912  }
2913  m_nonPropReqTimer.erase (dst);
2914 
2915  // Cancel the address request timer if found
2916  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2917  {
2918  NS_LOG_DEBUG ("Did not find the propagation timer");
2919  }
2920  else
2921  {
2922  NS_LOG_DEBUG ("did find the propagation timer");
2923  }
2924  m_addressReqTimer[dst].Cancel ();
2925  if (m_addressReqTimer[dst].IsRunning ())
2926  {
2927  NS_LOG_DEBUG ("Timer not canceled");
2928  }
2929  m_addressReqTimer.erase (dst);
2930  /*
2931  * If the route request is scheduled to remove the route request entry
2932  * Remove the route request entry with the route retry times done for certain destination
2933  */
2934  if (isRemove)
2935  {
2936  // remove the route request entry from route request table
2937  m_rreqTable->RemoveRreqEntry (dst);
2938  }
2939 }
2940 
2941 void
2942 DsrRouting::ScheduleRreqRetry (Ptr<Packet> packet, std::vector<Ipv4Address> address, bool nonProp, uint32_t requestId, uint8_t protocol)
2943 {
2944  NS_LOG_FUNCTION (this << packet << nonProp << requestId << (uint32_t)protocol);
2945  Ipv4Address source = address[0];
2946  Ipv4Address dst = address[1];
2947  if (nonProp)
2948  {
2949  // The nonProp route request is only sent out only and is already used
2950  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2951  {
2953  m_nonPropReqTimer[dst] = timer;
2954  }
2955  std::vector<Ipv4Address> address;
2956  address.push_back (source);
2957  address.push_back (dst);
2958  m_nonPropReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2959  m_nonPropReqTimer[dst].Cancel ();
2960  m_nonPropReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2962  }
2963  else
2964  {
2965  // Cancel the non propagation request timer if found
2966  m_nonPropReqTimer[dst].Cancel ();
2967  if (m_nonPropReqTimer[dst].IsRunning ())
2968  {
2969  NS_LOG_DEBUG ("Timer not canceled");
2970  }
2971  m_nonPropReqTimer.erase (dst);
2972 
2973  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2974  {
2976  m_addressReqTimer[dst] = timer;
2977  }
2978  std::vector<Ipv4Address> address;
2979  address.push_back (source);
2980  address.push_back (dst);
2981  m_addressReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2982  m_addressReqTimer[dst].Cancel ();
2983  m_addressReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2984  Time rreqDelay;
2985  // back off mechanism for sending route requests
2986  if (m_rreqTable->GetRreqCnt (dst))
2987  {
2988  // When the route request count is larger than 0
2989  // This is the exponential back-off mechanism for route request
2990  rreqDelay = Time (std::pow (static_cast<double> (m_rreqTable->GetRreqCnt (dst)), 2.0) * m_requestPeriod);
2991  }
2992  else
2993  {
2994  // This is the first route request retry
2995  rreqDelay = m_requestPeriod;
2996  }
2997  NS_LOG_LOGIC ("Request count for " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with delay time " << rreqDelay.As (Time::S));
2998  if (rreqDelay > m_maxRequestPeriod)
2999  {
3000  // use the max request period
3001  NS_LOG_LOGIC ("The max request delay time " << m_maxRequestPeriod.As (Time::S));
3002  m_addressReqTimer[dst].Schedule (m_maxRequestPeriod);
3003  }
3004  else
3005  {
3006  NS_LOG_LOGIC ("The request delay time " << rreqDelay.As (Time::S));
3007  m_addressReqTimer[dst].Schedule (rreqDelay);
3008  }
3009  }
3010 }
3011 
3012 void
3013 DsrRouting::RouteRequestTimerExpire (Ptr<Packet> packet, std::vector<Ipv4Address> address, uint32_t requestId, uint8_t protocol)
3014 {
3015  NS_LOG_FUNCTION (this << packet << requestId << (uint32_t)protocol);
3016  // Get a clean packet without dsr header
3017  Ptr<Packet> dsrP = packet->Copy ();
3018  DsrRoutingHeader dsrRoutingHeader;
3019  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
3020 
3021  Ipv4Address source = address[0];
3022  Ipv4Address dst = address[1];
3023  DsrRouteCacheEntry toDst;
3024  if (m_routeCache->LookupRoute (dst, toDst))
3025  {
3026  /*
3027  * Found a route the dst, construct the source route option header
3028  */
3029  DsrOptionSRHeader sourceRoute;
3030  std::vector<Ipv4Address> ip = toDst.GetVector ();
3031  sourceRoute.SetNodesAddress (ip);
3032  // When we found the route and use it, UseExtends for the link cache
3033  if (m_routeCache->IsLinkCache ())
3034  {
3035  m_routeCache->UseExtends (ip);
3036  }
3037  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
3039  sourceRoute.SetSalvage (0);
3040  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
3041  NS_LOG_INFO ("The nextHop address is " << nextHop);
3042  if (nextHop == "0.0.0.0")
3043  {
3044  NS_LOG_DEBUG ("Error next hop address");
3045  PacketNewRoute (dsrP, source, dst, protocol);
3046  return;
3047  }
3048  SetRoute (nextHop, m_mainAddress);
3049  CancelRreqTimer (dst, true);
3051  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
3052  {
3053  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
3054  }
3055  NS_LOG_LOGIC ("Route to " << dst << " found");
3056  return;
3057  }
3058  /*
3059  * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
3060  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
3061  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
3062  */
3063  NS_LOG_LOGIC ("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt (dst) << " the max " << m_rreqRetries);
3064  if (m_rreqTable->GetRreqCnt (dst) >= m_rreqRetries)
3065  {
3066  NS_LOG_LOGIC ("Route discovery to " << dst << " has been attempted " << m_rreqRetries << " times");
3067  CancelRreqTimer (dst, true);
3068  NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
3070  }
3071  else
3072  {
3073  SocketIpTtlTag tag;
3074  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
3075  Ptr<Packet> propPacket = packet->Copy ();
3076  propPacket->AddPacketTag (tag);
3077  // Increase the request count
3078  m_rreqTable->FindAndUpdate (dst);
3079  SendRequest (propPacket, source);
3080  NS_LOG_DEBUG ("Check the route request entry " << source << " " << dst);
3081  ScheduleRreqRetry (packet, address, false, requestId, protocol);
3082  }
3083  return;
3084 }
3085 
3086 void
3088  Ipv4Address source)
3089 {
3090  NS_LOG_FUNCTION (this << packet << source);
3091 
3092  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3093  /*
3094  * The destination address here is directed broadcast address
3095  */
3096  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3097  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3098  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3099  NS_LOG_LOGIC ("Inserting into priority queue number: " << priority);
3100 
3101  //m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
3102 
3104  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
3105  if (dsrNetworkQueue->Enqueue (newEntry))
3106  {
3107  Scheduler (priority);
3108  }
3109  else
3110  {
3111  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3112  }
3113 }
3114 
3115 void
3117 {
3118  NS_LOG_FUNCTION (this << packet);
3119  /*
3120  * This is a forwarding case when sending route requests, a random delay time [0, m_broadcastJitter]
3121  * used before forwarding as link-layer broadcast
3122  */
3124  packet, m_mainAddress);
3125 }
3126 
3127 void
3128 DsrRouting::SendGratuitousReply (Ipv4Address source, Ipv4Address srcAddress, std::vector<Ipv4Address> &nodeList, uint8_t protocol)
3129 {
3130  NS_LOG_FUNCTION (this << source << srcAddress << (uint32_t)protocol);
3131  if (!(m_graReply.FindAndUpdate (source, srcAddress, m_gratReplyHoldoff))) // Find the gratuitous reply entry
3132  {
3133  NS_LOG_LOGIC ("Update gratuitous reply " << source);
3134  GraReplyEntry graReplyEntry (source, srcAddress, m_gratReplyHoldoff + Simulator::Now ());
3135  m_graReply.AddEntry (graReplyEntry);
3136  /*
3137  * Automatic route shortening
3138  */
3139  m_finalRoute.clear (); // Clear the final route vector
3143  std::vector<Ipv4Address>::iterator before = find (nodeList.begin (), nodeList.end (), srcAddress);
3144  for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != before; ++i)
3145  {
3146  m_finalRoute.push_back (*i);
3147  }
3148  m_finalRoute.push_back (srcAddress);
3149  std::vector<Ipv4Address>::iterator after = find (nodeList.begin (), nodeList.end (), m_mainAddress);
3150  for (std::vector<Ipv4Address>::iterator j = after; j != nodeList.end (); ++j)
3151  {
3152  m_finalRoute.push_back (*j);
3153  }
3154  DsrOptionRrepHeader rrep;
3155  rrep.SetNodesAddress (m_finalRoute); // Set the node addresses in the route reply header
3156  // Get the real reply source and destination
3157  Ipv4Address replySrc = m_finalRoute.back ();
3158  Ipv4Address replyDst = m_finalRoute.front ();
3159  /*
3160  * Set the route and use it in send back route reply
3161  */
3162  m_ipv4Route = SetRoute (srcAddress, m_mainAddress);
3163  /*
3164  * This part adds DSR header to the packet and send reply
3165  */
3166  DsrRoutingHeader dsrRoutingHeader;
3167  dsrRoutingHeader.SetNextHeader (protocol);
3168  dsrRoutingHeader.SetMessageType (1);
3169  dsrRoutingHeader.SetSourceId (GetIDfromIP (replySrc));
3170  dsrRoutingHeader.SetDestId (GetIDfromIP (replyDst));
3171 
3172  uint8_t length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
3173  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
3174  dsrRoutingHeader.AddDsrOption (rrep);
3175  Ptr<Packet> newPacket = Create<Packet> ();
3176  newPacket->AddHeader (dsrRoutingHeader);
3177  /*
3178  * Send gratuitous reply
3179  */
3180  NS_LOG_INFO ("Send back gratuitous route reply");
3181  SendReply (newPacket, m_mainAddress, srcAddress, m_ipv4Route);
3182  }
3183  else
3184  {
3185  NS_LOG_INFO ("The same gratuitous route reply has already sent");
3186  }
3187 }
3188 
3189 void
3191  Ipv4Address source,
3192  Ipv4Address nextHop,
3193  Ptr<Ipv4Route> route)
3194 {
3195  NS_LOG_FUNCTION (this << packet << source << nextHop);
3196  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3197 
3198  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (m_mainAddress));
3199  route->SetOutputDevice (dev);
3200  NS_LOG_INFO ("The output device " << dev << " packet is: " << *packet);
3201 
3202  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3203  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3204  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3205  NS_LOG_INFO ("Inserting into priority queue number: " << priority);
3206 
3207  //m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3208 
3210  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
3211  if (dsrNetworkQueue->Enqueue (newEntry))
3212  {
3213  Scheduler (priority);
3214  }
3215  else
3216  {
3217  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3218  }
3219 }
3220 
3221 void
3223  Ipv4Address source,
3224  Ipv4Address nextHop,
3225  Ptr<Ipv4Route> route)
3226 {
3227  NS_LOG_FUNCTION (this << packet << source << nextHop);
3229  packet, source, nextHop, route);
3230 }
3231 
3232 void
3234  Ipv4Address source,
3235  Ipv4Address destination,
3236  Ptr<Ipv4Route> route,
3237  double hops)
3238 {
3239  NS_LOG_FUNCTION (this << packet << source << destination);
3240  Simulator::Schedule (Time (2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue (0,1))), &DsrRouting::SendReply, this, packet, source, destination, route);
3241 }
3242 
3243 void
3244 DsrRouting::SendAck (uint16_t ackId,
3245  Ipv4Address destination,
3246  Ipv4Address realSrc,
3247  Ipv4Address realDst,
3248  uint8_t protocol,
3249  Ptr<Ipv4Route> route)
3250 {
3251  NS_LOG_FUNCTION (this << ackId << destination << realSrc << realDst << (uint32_t)protocol << route);
3252  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3253 
3254  // This is a route reply option header
3255  DsrRoutingHeader dsrRoutingHeader;
3256  dsrRoutingHeader.SetNextHeader (protocol);
3257  dsrRoutingHeader.SetMessageType (1);
3258  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
3259  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
3260 
3261  DsrOptionAckHeader ack;
3262  /*
3263  * Set the ack Id and set the ack source address and destination address
3264  */
3265  ack.SetAckId (ackId);
3266  ack.SetRealSrc (realSrc);
3267  ack.SetRealDst (realDst);
3268 
3269  uint8_t length = ack.GetLength ();
3270  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
3271  dsrRoutingHeader.AddDsrOption (ack);
3272 
3273  Ptr<Packet> packet = Create<Packet> ();
3274  packet->AddHeader (dsrRoutingHeader);
3275  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
3276  route->SetOutputDevice (dev);
3277 
3278  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3279  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3280  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3281 
3282  NS_LOG_LOGIC ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
3283 
3284  //m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
3285 
3287  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
3288  if (dsrNetworkQueue->Enqueue (newEntry))
3289  {
3290  Scheduler (priority);
3291  }
3292  else
3293  {
3294  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3295  }
3296 }
3297 
3300  Ipv4Header const &ip,
3301  Ptr<Ipv4Interface> incomingInterface)
3302 {
3303  NS_LOG_FUNCTION (this << p << ip << incomingInterface);
3304 
3305  NS_LOG_INFO ("Our own IP address " << m_mainAddress << " The incoming interface address " << incomingInterface);
3306  m_node = GetNode (); // Get the node
3307  Ptr<Packet> packet = p->Copy (); // Save a copy of the received packet
3308  /*
3309  * When forwarding or local deliver packets, this one should be used always!!
3310  */
3311  DsrRoutingHeader dsrRoutingHeader;
3312  packet->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
3313  Ptr<Packet> copy = packet->Copy ();
3314 
3315  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
3316  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
3317  Ipv4Address source = GetIPfromID (sourceId);
3318  NS_LOG_INFO ("The source address " << source << " with source id " << sourceId);
3319  /*
3320  * Get the IP source and destination address
3321  */
3322  Ipv4Address src = ip.GetSource ();
3323 
3324  bool isPromisc = false;
3325  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset (); // Get the offset for option header, 8 bytes in this case
3326 
3327  // This packet is used to peek option type
3328  p->RemoveAtStart (offset);
3329 
3330  Ptr<dsr::DsrOptions> dsrOption;
3331  DsrOptionHeader dsrOptionHeader;
3332  /*
3333  * Peek data to get the option type as well as length and segmentsLeft field
3334  */
3335  uint32_t size = p->GetSize ();
3336  uint8_t *data = new uint8_t[size];
3337  p->CopyData (data, size);
3338 
3339  uint8_t optionType = 0;
3340  uint8_t optionLength = 0;
3341  uint8_t segmentsLeft = 0;
3342 
3343  optionType = *(data);
3344  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet id " << p->GetUid ());
3345  dsrOption = GetOption (optionType); // Get the relative dsr option and demux to the process function
3346  Ipv4Address promiscSource;
3347  if (optionType == 1) // This is the request option
3348  {
3349  BlackList *blackList = m_rreqTable->FindUnidirectional (src);
3350  if (blackList)
3351  {
3352  NS_LOG_INFO ("Discard this packet due to unidirectional link");
3353  m_dropTrace (p);
3354  }
3355 
3356  dsrOption = GetOption (optionType);
3357  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3358 
3359  if (optionLength == 0)
3360  {
3361  NS_LOG_INFO ("Discard this packet");
3362  m_dropTrace (p);
3363  }
3364  }
3365  else if (optionType == 2)
3366  {
3367  dsrOption = GetOption (optionType);
3368  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3369 
3370  if (optionLength == 0)
3371  {
3372  NS_LOG_INFO ("Discard this packet");
3373  m_dropTrace (p);
3374  }
3375  }
3376 
3377  else if (optionType == 32) // This is the ACK option
3378  {
3379  NS_LOG_INFO ("This is the ack option");
3380  dsrOption = GetOption (optionType);
3381  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3382 
3383  if (optionLength == 0)
3384  {
3385  NS_LOG_INFO ("Discard this packet");
3386  m_dropTrace (p);
3387  }
3388  }
3389 
3390  else if (optionType == 3) // This is a route error header
3391  {
3392  // populate this route error
3393  NS_LOG_INFO ("The option type value " << (uint32_t)optionType);
3394 
3395  dsrOption = GetOption (optionType);
3396  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3397 
3398  if (optionLength == 0)
3399  {
3400  NS_LOG_INFO ("Discard this packet");
3401  m_dropTrace (p);
3402  }
3403  NS_LOG_INFO ("The option Length " << (uint32_t)optionLength);
3404  }
3405 
3406  else if (optionType == 96) // This is the source route option
3407  {
3408  dsrOption = GetOption (optionType);
3409  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3410  segmentsLeft = *(data + 3);
3411  if (optionLength == 0)
3412  {
3413  NS_LOG_INFO ("Discard this packet");
3414  m_dropTrace (p);
3415  }
3416  else
3417  {
3418  if (segmentsLeft == 0)
3419  {
3420  // / Get the next header
3421  uint8_t nextHeader = dsrRoutingHeader.GetNextHeader ();
3422  Ptr<Ipv4L3Protocol> l3proto = m_node->GetObject<Ipv4L3Protocol> ();
3423  Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol (nextHeader);
3424  if (nextProto != 0)
3425  {
3426  // we need to make a copy in the unlikely event we hit the
3427  // RX_ENDPOINT_UNREACH code path
3428  // Here we can use the packet that has been get off whole DSR header
3429  enum IpL4Protocol::RxStatus status =
3430  nextProto->Receive (copy, ip, incomingInterface);
3431  NS_LOG_DEBUG ("The receive status " << status);
3432  switch (status)
3433  {
3434  case IpL4Protocol::RX_OK:
3435  // fall through
3437  // fall through
3439  break;
3441  if (ip.GetDestination ().IsBroadcast () == true
3442  || ip.GetDestination ().IsMulticast () == true)
3443  {
3444  break; // Do not reply to broadcast or multicast
3445  }
3446  // Another case to suppress ICMP is a subnet-directed broadcast
3447  }
3448  return status;
3449  }
3450  else
3451  {
3452  NS_FATAL_ERROR ("Should not have 0 next protocol value");
3453  }
3454  }
3455  else
3456  {
3457  NS_LOG_INFO ("This is not the final destination, the packet has already been forward to next hop");
3458  }
3459  }
3460  }
3461  else
3462  {
3463  NS_LOG_LOGIC ("Unknown Option. Drop!");
3464  /*
3465  * Initialize the salvage value to 0
3466  */
3467  uint8_t salvage = 0;
3468 
3469  DsrOptionRerrUnsupportHeader rerrUnsupportHeader;
3470  rerrUnsupportHeader.SetErrorType (3); // The error type 3 means Option not supported
3471  rerrUnsupportHeader.SetErrorSrc (m_mainAddress); // The error source address is our own address
3472  rerrUnsupportHeader.SetUnsupported (optionType); // The unsupported option type number
3473  rerrUnsupportHeader.SetErrorDst (src); // Error destination address is the destination of the data packet
3474  rerrUnsupportHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
3475 
3476  /*
3477  * The unknown option error is not supported currently in this implementation, and it's also not likely to
3478  * happen in simulations
3479  */
3480 // SendError (rerrUnsupportHeader, 0, protocol); // Send the error packet
3481  }
3482  return IpL4Protocol::RX_OK;
3483 }
3484 
3486 DsrRouting::Receive (Ptr<Packet> p,
3487  Ipv6Header const &ip,
3488  Ptr<Ipv6Interface> incomingInterface)
3489 {
3490  NS_LOG_FUNCTION (this << p << ip.GetSource () << ip.GetDestination () << incomingInterface);
3492 }
3493 
3494 void
3496 {
3497  m_downTarget = callback;
3498 }
3499 
3500 void
3502 {
3503  NS_FATAL_ERROR ("Unimplemented");
3504 }
3505 
3506 
3509 {
3510  return m_downTarget;
3511 }
3512 
3515 {
3516  NS_FATAL_ERROR ("Unimplemented");
3517  return MakeNullCallback<void,Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route> > ();
3518 }
3519 
3521 {
3522  m_options.push_back (option);
3523 }
3524 
3526 {
3527  for (DsrOptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
3528  {
3529  if ((*i)->GetOptionNumber () == optionNumber)
3530  {
3531  return *i;
3532  }
3533  }
3534  return 0;
3535 }
3536 } /* namespace dsr */
3537 } /* namespace ns3 */
a polymophic address class
Definition: address.h:91
Wifi MAC high model for an ad-hoc Wifi MAC.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
L4 Protocol abstract base class.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
bool IsMulticast(void) const
bool IsBroadcast(void) const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
Describes an IPv6 address.
Definition: ipv6-address.h:50
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address ConvertFrom(const Address &address)
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:304
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
static uint32_t GetNNodes(void)
Definition: node-list.cc:247
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:390
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:587
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1117
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:604
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
AttributeValue implementation for Time.
Definition: nstime.h:1308
A simple virtual Timer class.
Definition: timer.h:74
void SetFunction(FN fn)
Definition: timer.h:278
void Suspend(void)
Pause the timer and save the amount of time left until it was set to expire.
Definition: timer.cc:177
bool IsRunning(void) const
Definition: timer.cc:127
@ CANCEL_ON_DESTROY
This policy cancels the event from the destructor of the Timer or from Suspend().
Definition: timer.h:93
void Resume(void)
Restart the timer to expire within the amount of time left saved during Suspend.
Definition: timer.cc:194
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
bool IsSuspended(void) const
Definition: timer.cc:133
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
Hold together all Wifi-related objects.
DSR Error Buffer Entry.
Definition: dsr-errorbuff.h:46
Ptr< const Packet > GetPacket() const
Get packet from entry.
Definition: dsr-errorbuff.h:83
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
bool Enqueue(DsrErrorBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
bool Dequeue(Ipv4Address dst, DsrErrorBuffEntry &entry)
Return first found (the earliest) entry for given destination.
bool Find(Ipv4Address dst)
Finds whether a packet with destination dst exists in the queue.
void DropPacketForErrLink(Ipv4Address source, Ipv4Address nextHop)
Remove all packets with the error link.
void SetErrorBufferTimeout(Time t)
Set error buffer timeout.
uint32_t GetSize()
Returns the number of entries in the queue.
void SetSourceId(uint16_t sourceId)
brief Set the source ID of the header.
void SetNextHeader(uint8_t protocol)
Set the "Next header" field.
void SetDestId(uint16_t destId)
brief Set the dest ID of the header.
uint8_t GetMessageType() const
brief Get the message type of the header.
uint8_t GetNextHeader() const
Get the next header.
uint16_t GetSourceId() const
brief Get the source ID of the header.
uint16_t GetDestId() const
brief Get the dest ID of the header.
void SetMessageType(uint8_t messageType)
brief Set the message type of the header.
void SetPayloadLength(uint16_t length)
brief Set the payload length of the header.
bool AddEntry(GraReplyEntry &graTableEntry)
Add a new gratuitous reply entry.
void SetGraTableSize(uint32_t g)
Set the gratuitous reply table size.
bool FindAndUpdate(Ipv4Address replyTo, Ipv4Address replyFrom, Time gratReplyHoldoff)
Update the route entry if found.
DSR Maintain Buffer Entry.
uint8_t GetSegsLeft() const
Get segments left.
void SetDst(Ipv4Address n)
Set destination address.
void SetExpireTime(Time exp)
Set expiration time.
Ptr< const Packet > GetPacket() const
Get packet.
void SetNextHop(Ipv4Address n)
Set next hop of entry.
Ipv4Address GetSrc() const
Get source address.
void SetSegsLeft(uint8_t segs)
Set segments left.
void SetPacket(Ptr< const Packet > p)
Set packet.
void SetOurAdd(Ipv4Address us)
Set local address of entry.
void SetSrc(Ipv4Address s)
Set source address.
uint16_t GetAckId() const
Get acknowledge ID.
Ipv4Address GetOurAdd() const
Get local address of entry.
void SetAckId(uint16_t ackId)
Set acknowledge ID.
Ipv4Address GetNextHop() const
Get next hop of entry.
Ipv4Address GetDst() const
Get destination address.
bool Dequeue(Ipv4Address dst, DsrMaintainBuffEntry &entry)
Return first found (the earliest) entry for given destination.
void SetMaxQueueLen(uint32_t len)
Set maximum queue length.
bool AllEqual(DsrMaintainBuffEntry &entry)
Verify if all the elements in the maintenance buffer entry is the same.
bool LinkEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for link ack.
bool Find(Ipv4Address nextHop)
Finds whether a packet with next hop dst exists in the queue.
void SetMaintainBufferTimeout(Time t)
Set maintain buffer timeout.
uint32_t GetSize()
Number of entries.
bool PromiscEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for promiscuous ack.
bool NetworkEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for network ack.
bool Enqueue(DsrMaintainBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
DSR Network Queue Entry.
Ipv4Address GetSourceAddress() const
Get source address function.
Ptr< const Packet > GetPacket() const
Get packet function.
Ptr< Ipv4Route > GetIpv4Route() const
Get IP route function.
Ipv4Address GetNextHopAddress() const
Get next hop address function.
Acknowledgement (ACK) Message Format.
void SetAckId(uint16_t identification)
Set the Ack id number.
void SetRealSrc(Ipv4Address realSrcAddress)
Set Error source ip address.
void SetRealDst(Ipv4Address realDstAddress)
Set Error source ip address.
Acknowledgement Request (ACK_RREQ) Message Format.
void SetAckId(uint16_t identification)
Set the Ack request id number.
uint32_t GetDsrOptionsOffset()
Get the offset where the options begin, measured from the start of the extension header.
void AddDsrOption(DsrOptionHeader const &option)
Serialize the option, prepending pad1 or padn option as necessary.
Header for Dsr Options.
uint8_t GetLength() const
Get the option length.
void SetErrorType(uint8_t errorType)
Set the route error type.
Route Error (RERR) Unreachable node address option Message Format.
void SetOriginalDst(Ipv4Address originalDst)
Set the unreachable node ip address.
virtual void SetErrorSrc(Ipv4Address errorSrcAddress)
Set the route error source address.
Ipv4Address GetOriginalDst() const
Get the unreachable node ip address.
void SetUnreachNode(Ipv4Address unreachNode)
Set the unreachable node ip address.
virtual void SetErrorDst(Ipv4Address errorDstAddress)
Set the error destination ip address.
virtual Ipv4Address GetErrorSrc() const
Get the route error source address.
virtual uint8_t GetSalvage() const
Get the salvage value of the packet.
virtual void SetSalvage(uint8_t salvage)
Set the salvage value of the packet.
virtual Ipv4Address GetErrorDst() const
Get the error destination ip address.
Ipv4Address GetUnreachNode() const
Get the unreachable node ip address.
Route Reply (RREP) Message Format.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
Route Request (RREQ) Message Format.
void SetTarget(Ipv4Address target)
Set the target ipv4 address.
void AddNodeAddress(Ipv4Address ipv4)
Add one node address.
void SetId(uint16_t identification)
Set the request id number.
Source Route (SR) Message Format.
std::vector< Ipv4Address > GetNodesAddress() const
Get the vector of ipv4 address.
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
void SetSalvage(uint8_t salvage)
Set the salvage value for a packet.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the number of segments left to send.
uint8_t GetSalvage() const
Get the salvage value for a packet.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
uint8_t GetSegmentsLeft() const
Get the number of segments left to send.
DSR Passive Buffer Entry.
void SetIdentification(uint16_t i)
Set identification function.
void SetDestination(Ipv4Address d)
Set destination address function.
void SetSegsLeft(uint8_t seg)
Set segments left.
void SetSource(Ipv4Address s)
Set surce address function.
void SetPacket(Ptr< const Packet > p)
Set packet function.
void SetFragmentOffset(uint16_t f)
Set fragment offset function.
DsrRouteCacheEntry class for entries in the route cache.
Definition: dsr-rcache.h:221
IP_VECTOR GetVector() const
Get the IP vector.
Definition: dsr-rcache.h:293
std::vector< Ipv4Address > IP_VECTOR
Define the vector to hold Ip address.
Definition: dsr-rcache.h:223
Header of Dsr Routing.
Dsr Routing base.
Definition: dsr-routing.h:96
Ptr< dsr::DsrRreqTable > GetRequestTable() const
Get the request table.
Definition: dsr-routing.cc:609
void ScheduleInterRequest(Ptr< Packet > packet)
Schedule the intermediate route request.
void CheckSendBuffer()
Check the send buffer of packets with route when send buffer timer expire.
Definition: dsr-routing.cc:835
Ptr< Ipv4 > m_ip
The ip ptr.
Definition: dsr-routing.h:754
void ScheduleRreqRetry(Ptr< Packet > packet, std::vector< Ipv4Address > address, bool nonProp, uint32_t requestId, uint8_t protocol)
Schedule the route request retry.
Time m_blacklistTimeout
The black list time out.
Definition: dsr-routing.h:820
std::string m_cacheType
The type of route cache.
Definition: dsr-routing.h:844
std::map< Ipv4Address, Timer > m_nonPropReqTimer
Map IP address + RREQ timer.
Definition: dsr-routing.h:866
void SetNode(Ptr< Node > node)
Set the node.
Definition: dsr-routing.cc:577
void SendBuffTimerExpire()
The send buffer timer expire.
Definition: dsr-routing.cc:825
void SetPassiveBuffer(Ptr< dsr::DsrPassiveBuffer > r)
Set the node.
Definition: dsr-routing.cc:615
std::vector< std::string > GetElementsFromContext(std::string context)
Get the elements from the tracing context.
Definition: dsr-routing.cc:534
void UseExtends(DsrRouteCacheEntry::IP_VECTOR rt)
Extends the lifetime of a route cache entry.
Definition: dsr-routing.cc:651
uint32_t m_maxRreqId
The max number of request ids for a single destination.
Definition: dsr-routing.h:818
void SetDownTarget6(IpL4Protocol::DownTargetCallback6 callback)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
void SendPacketFromBuffer(DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop, uint8_t protocol)
This function is responsible for sending out data packets when have route, if no route found,...
bool SendRealDown(DsrNetworkQueueEntry &newEntry)
This function is called to send packets down stack.
Time m_sendBufferTimeout
The maximum period of time that a routing protocol is allowed to buffer a packet for.
Definition: dsr-routing.h:790
uint8_t segsLeft
The segment left value from SR header.
Definition: dsr-routing.h:760
void SendRequest(Ptr< Packet > packet, Ipv4Address source)
Forward the route request if the node is not the destination.
void CancelPacketTimerNextHop(Ipv4Address nextHop, uint8_t protocol)
Cancel the packet retransmission timer for a all maintenance entries with nextHop address.
bool m_linkAck
define if we use link acknowledgement or not
Definition: dsr-routing.h:888
void PrintVector(std::vector< Ipv4Address > &vec)
Print the route vector.
Definition: dsr-routing.cc:710
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
Definition: dsr-routing.h:902
virtual void DoDispose(void)
Drop trace callback.
Definition: dsr-routing.cc:549
void ForwardErrPacket(DsrOptionRerrUnreachHeader &rerr, DsrOptionSRHeader &sourceRoute, Ipv4Address nextHop, uint8_t protocol, Ptr< Ipv4Route > route)
This function is responsible for forwarding error packets along the route.
bool CancelPassiveTimer(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft)
Cancel the passive timer.
void PassiveScheduleTimerExpire(DsrMaintainBuffEntry &mb, uint8_t protocol)
This function deals with packet retransmission timer expire using passive acknowledgment.
void SetDownTarget(IpL4Protocol::DownTargetCallback callback)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
bool AddRoute_Link(DsrRouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source)
dd route link to cache See also DsrRouteCache::AddRoute_Link
Definition: dsr-routing.cc:661
uint16_t m_ackId
The ack id assigned to each acknowledge.
Definition: dsr-routing.h:812
DsrRouting()
Constructor.
Definition: dsr-routing.cc:356
void CancelLinkPacketTimer(DsrMaintainBuffEntry &mb)
Cancel the link packet retransmission timer for a specific maintenance entry.
IpL4Protocol::DownTargetCallback6 GetDownTarget6(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
Time m_nonpropRequestTimeout
The non-propagation request timeout.
Definition: dsr-routing.h:774
Time m_gratReplyHoldoff
The max gratuitous reply hold off time.
Definition: dsr-routing.h:838
uint16_t GetIDfromIP(Ipv4Address address)
Get the node id from ip address.
Definition: dsr-routing.cc:781
std::map< uint32_t, Ptr< dsr::DsrNetworkQueue > > m_priorityQueue
priority queues
Definition: dsr-routing.h:890
uint32_t m_maxEntriesEachDst
Max number of route entries to save for each destination.
Definition: dsr-routing.h:806
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
Definition: dsr-routing.h:864
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)
Time m_retransIncr
the increase time for retransmission timer when face network congestion
Definition: dsr-routing.h:860
std::map< NetworkKey, Timer > m_addressForwardTimer
Map network key + forward timer.
Definition: dsr-routing.h:868
uint32_t m_stabilityDecrFactor
The initial decrease factor for link cache.
Definition: dsr-routing.h:848
Time m_nodeTraversalTime
Time estimated for packet to travel between two nodes.
Definition: dsr-routing.h:786
uint32_t m_requestId
The id assigned to each route request.
Definition: dsr-routing.h:810
std::map< NetworkKey, uint32_t > m_addressForwardCnt
Map network key + forward counts.
Definition: dsr-routing.h:870
Ptr< NetDevice > GetNetDeviceFromContext(std::string context)
Get the netdevice from the context.
Definition: dsr-routing.cc:522
bool FindSourceEntry(Ipv4Address src, Ipv4Address dst, uint16_t id)
Find the source request entry in the route request queue, return false if not found.
Definition: dsr-routing.cc:686
Ipv4Address m_broadcast
The broadcast IP address.
Definition: dsr-routing.h:822
Ptr< dsr::DsrPassiveBuffer > GetPassiveBuffer() const
Get the passive buffer.
Definition: dsr-routing.cc:622
Ipv4Address GetIPfromMAC(Mac48Address address)
Get the Ip address from mac address.
Definition: dsr-routing.cc:692
Ptr< dsr::DsrRouteCache > GetRouteCache() const
Get the route cache.
Definition: dsr-routing.cc:596
Time m_maxNetworkDelay
Maximum network delay.
Definition: dsr-routing.h:766
Ptr< dsr::DsrOptions > GetOption(int optionNumber)
Get the option corresponding to optionNumber.
uint32_t m_maxSendBuffLen
The maximum number of packets that we allow a routing protocol to buffer.
Definition: dsr-routing.h:788
IpL4Protocol::DownTargetCallback GetDownTarget(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
TracedCallback< const DsrOptionSRHeader & > m_txPacketTrace
packet trace callback
Definition: dsr-routing.h:719
Time m_passiveAckTimeout
The timeout value for passive acknowledge.
Definition: dsr-routing.h:826
void SetRequestTable(Ptr< dsr::DsrRreqTable > r)
Set the node.
Definition: dsr-routing.cc:602
uint32_t m_maxMaintainLen
Max # of entries for maintenance buffer.
Definition: dsr-routing.h:796
static const uint8_t PROT_NUMBER
Define the dsr protocol number.
Definition: dsr-routing.h:106
uint32_t GetPriority(DsrMessageType messageType)
Set the priority of the packet in network queue.
Definition: dsr-routing.cc:813
void SendReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, Ptr< Ipv4Route > route)
Send the route reply back to the request originator with the cumulated route.
void ScheduleNetworkPacketRetry(DsrMaintainBuffEntry &mb, bool isFirst, uint8_t protocol)
Schedule the packet retransmission based on network layer acknowledgment.
void CallCancelPacketTimer(uint16_t ackId, Ipv4Header const &ipv4Header, Ipv4Address realSrc, Ipv4Address realDst)
Call the cancel packet retransmission timer function.
Ipv4Address m_mainAddress
Our own Ip address.
Definition: dsr-routing.h:758
void SendInitialRequest(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
Broadcast the route request packet in subnet.
Timer m_sendBuffTimer
The send buffer timer.
Definition: dsr-routing.h:834
Time m_maxCacheTime
Max time for caching the route cache entry.
Definition: dsr-routing.h:802
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: dsr-routing.cc:397
void SendGratuitousReply(Ipv4Address replyTo, Ipv4Address replyFrom, std::vector< Ipv4Address > &nodeList, uint8_t protocol)
Send the gratuitous reply.
void DeleteAllRoutesIncludeLink(Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node)
Delete all the routes which includes the link from next hop address that has just been notified as un...
Definition: dsr-routing.cc:676
DsrOptionList_t m_options
List of DSR Options supported.
Definition: dsr-routing.h:748
std::map< PassiveKey, uint32_t > m_passiveCnt
Map packet key + passive forward counts.
Definition: dsr-routing.h:872
DsrErrorBuffer m_errorBuffer
The error buffer to save the error messages.
Definition: dsr-routing.h:794
void SalvagePacket(Ptr< const Packet > packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol)
Salvage the packet which has been transmitted for 3 times.
bool m_subRoute
Whether to save sub route or not.
Definition: dsr-routing.h:858
void SendPacket(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol)
This function is called by when really sending out the packet.
bool IsLinkCache()
Checks if the link is cached in the route cache See also DsrRouteCache::IsLinkCache.
Definition: dsr-routing.cc:646
std::map< LinkKey, uint32_t > m_linkCnt
Map packet key + link forward counts.
Definition: dsr-routing.h:876
DsrSendBuffer m_sendBuffer
The send buffer.
Definition: dsr-routing.h:792
uint32_t m_passiveRetries
Definition: dsr-routing.h:778
uint32_t m_rreqRetries
Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route.
Definition: dsr-routing.h:782
uint8_t m_maxSalvageCount
Maximum # times to salvage a packet.
Definition: dsr-routing.h:770
Ptr< Ipv4Route > SetRoute(Ipv4Address nextHop, Ipv4Address srcAddress)
Set the route to use for data packets, used by the option headers when sending data/control packets.
Definition: dsr-routing.cc:763
uint16_t AddAckReqHeader(Ptr< Packet > &packet, Ipv4Address nextHop)
This function is called to add ack request header for network acknowledgement.
uint32_t m_requestTableSize
The max size of the request table size.
Definition: dsr-routing.h:814
DsrGraReply m_graReply
The gratuitous route reply.
Definition: dsr-routing.h:892
void ScheduleLinkPacketRetry(DsrMaintainBuffEntry &mb, uint8_t protocol)
Schedule the packet retransmission based on link-layer acknowledgment.
bool PromiscReceive(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Promiscuous receive data packets destined to some other node.
Time m_sendBuffInterval
how often to check send buffer
Definition: dsr-routing.h:836
void ScheduleInitialReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, Ptr< Ipv4Route > route)
this is a generating the initial route reply from the destination address, a random delay time [0,...
bool LookupRoute(Ipv4Address id, DsrRouteCacheEntry &rt)
Lookup route cache entry with destination address dst See also DsrRouteCache::LookupRoute.
Definition: dsr-routing.cc:656
Time m_initStability
The initial stability value for link cache.
Definition: dsr-routing.h:852
uint32_t m_stabilityIncrFactor
The initial increase factor for link cache.
Definition: dsr-routing.h:850
Time m_useExtends
The use extension of the life time for link cache.
Definition: dsr-routing.h:856
uint32_t m_numPriorityQueues
The number of priority queues used.
Definition: dsr-routing.h:886
Ipv4Address SearchNextHop(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Get the next hop of the route.
Definition: dsr-routing.cc:730
IpL4Protocol::DownTargetCallback m_downTarget
The callback for down layer.
Definition: dsr-routing.h:762
uint32_t m_graReplyTableSize
Set the gratuitous reply table size.
Definition: dsr-routing.h:842
bool PassiveEntryCheck(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft, uint16_t fragmentOffset, uint16_t identification, bool saveEntry)
Find the same passive entry.
Ptr< Node > GetNodeWithAddress(Ipv4Address ipv4Address)
Get the node with give ip address.
Definition: dsr-routing.cc:629
Ptr< Ipv4L3Protocol > m_ipv4
Ipv4l3Protocol.
Definition: dsr-routing.h:750
void Scheduler(uint32_t priority)
This function is called to schedule sending packets from the network queue.
void RouteRequestTimerExpire(Ptr< Packet > packet, std::vector< Ipv4Address > address, uint32_t requestId, uint8_t protocol)
Handle route discovery timer.
void NetworkScheduleTimerExpire(DsrMaintainBuffEntry &mb, uint8_t protocol)
This function deals with packet retransmission timer expire using network acknowledgment.
uint32_t m_requestTableIds
The request table identifiers.
Definition: dsr-routing.h:816
TracedCallback< Ptr< const Packet > > m_dropTrace
The trace for drop, receive and send data packets.
Definition: dsr-routing.h:718
uint32_t m_tryPassiveAcks
Maximum number of packet transmission using passive acknowledgment.
Definition: dsr-routing.h:828
void LinkScheduleTimerExpire(DsrMaintainBuffEntry &mb, uint8_t protocol)
This function deals with packet retransmission timer expire using link acknowledgment.
bool UpdateRouteEntry(Ipv4Address dst)
Update route cache entry if it has been recently used and successfully delivered the data packet.
Definition: dsr-routing.cc:681
uint32_t m_maxNetworkSize
Maximum network queue size.
Definition: dsr-routing.h:764
Ptr< Ipv4Route > m_ipv4Route
Ipv4 Route.
Definition: dsr-routing.h:752
Ptr< Node > GetNode() const
Get the node.
Definition: dsr-routing.cc:583
Ipv4Address GetIPfromID(uint16_t id)
Get the ip address from id.
Definition: dsr-routing.cc:797
Time m_maxRequestPeriod
The max request period.
Definition: dsr-routing.h:840
void SchedulePassivePacketRetry(DsrMaintainBuffEntry &mb, uint8_t protocol)
Schedule the packet retransmission based on passive acknowledgment.
Ptr< dsr::DsrPassiveBuffer > m_passiveBuffer
A "drop-front" queue used by the routing layer to cache route request sent.
Definition: dsr-routing.h:884
Ptr< Node > m_node
The node ptr.
Definition: dsr-routing.h:756
Ptr< dsr::DsrRouteCache > m_routeCache
A "drop-front" queue used by the routing layer to cache routes found.
Definition: dsr-routing.h:880
std::map< PassiveKey, Timer > m_passiveAckTimer
The timer for passive acknowledgment.
Definition: dsr-routing.h:874
bool AddRoute(DsrRouteCacheEntry &rt)
Add route cache entry if it doesn't yet exist in route cache See also DsrRouteCache::AddRoute.
Definition: dsr-routing.cc:668
Time m_maxMaintainTime
Time out for maintenance buffer.
Definition: dsr-routing.h:798
DsrMaintainBuffer m_maintainBuffer
The declaration of maintain buffer.
Definition: dsr-routing.h:808
uint32_t m_maxMaintRexmt
Maximum number of retransmissions of data packets.
Definition: dsr-routing.h:784
void ForwardPacket(Ptr< const Packet > packet, DsrOptionSRHeader &sourceRoute, Ipv4Header const &ipv4Header, Ipv4Address source, Ipv4Address destination, Ipv4Address targetAddress, uint8_t protocol, Ptr< Ipv4Route > route)
Forward the packet using the route saved in the source route option header.
Time m_requestPeriod
The base time interval between route requests.
Definition: dsr-routing.h:772
Time m_linkAckTimeout
The timeout value for link acknowledge.
Definition: dsr-routing.h:830
void SendUnreachError(Ipv4Address unreachNode, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
This function is responsible for sending error packets in case of break link to next hop.
uint32_t m_tryLinkAcks
Maximum number of packet transmission using link acknowledgment.
Definition: dsr-routing.h:832
uint32_t m_discoveryHopLimit
Maximum hops to go for route request.
Definition: dsr-routing.h:768
void CancelRreqTimer(Ipv4Address dst, bool isRemove)
Cancel the route request timer.
std::map< LinkKey, Timer > m_linkAckTimer
The timer for link acknowledgment.
Definition: dsr-routing.h:878
Time m_minLifeTime
The min life time.
Definition: dsr-routing.h:854
static TypeId GetTypeId()
Get the type identificator.
Definition: dsr-routing.cc:108
void SendErrorRequest(DsrOptionRerrUnreachHeader &rerr, uint8_t protocol)
Send the error request packet.
void PacketNewRoute(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol)
When route vector corrupted, originate a new packet, normally not happening.
Ptr< dsr::DsrRreqTable > m_rreqTable
A "drop-front" queue used by the routing layer to cache route request sent.
Definition: dsr-routing.h:882
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void IncreaseRetransTimer()
This function is called to increase the retransmission timer for data packet in the network queue.
int GetProtocolNumber(void) const
Get the dsr protocol number.
Definition: dsr-routing.cc:774
void CancelPassivePacketTimer(DsrMaintainBuffEntry &mb)
Cancel the passive packet retransmission timer for a specific maintenance entry.
void CancelNetworkPacketTimer(DsrMaintainBuffEntry &mb)
Cancel the network packet retransmission timer for a specific maintenance entry.
void PriorityScheduler(uint32_t priority, bool continueWithFirst)
This function is called to schedule sending packets from the network queue by priority.
void ScheduleCachedReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, Ptr< Ipv4Route > route, double hops)
Schedule the cached reply to a random start time to avoid possible route reply storm.
void SendAck(uint16_t ackId, Ipv4Address destination, Ipv4Address realSrc, Ipv4Address realDst, uint8_t protocol, Ptr< Ipv4Route > route)
Send network layer acknowledgment back to the earlier hop to notify the receipt of data packet.
void SetRouteCache(Ptr< dsr::DsrRouteCache > r)
Set the route cache.
Definition: dsr-routing.cc:589
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
This function is called by higher layer protocol when sending packets.
virtual ~DsrRouting()
Destructor.
Definition: dsr-routing.cc:391
void Insert(Ptr< dsr::DsrOptions > option)
Insert a new Dsr Option.
std::vector< Ipv4Address > m_finalRoute
The route cache.
Definition: dsr-routing.h:862
void CancelPacketAllTimer(DsrMaintainBuffEntry &mb)
Cancel all the packet timers.
uint32_t m_broadcastJitter
The max time to delay route request broadcast.
Definition: dsr-routing.h:824
uint32_t m_maxCacheLen
Max # of cache entries for route cache.
Definition: dsr-routing.h:800
DSR Send Buffer Entry.
Definition: dsr-rsendbuff.h:46
Ptr< const Packet > GetPacket() const
Get pointer to entry's packet.
Definition: dsr-rsendbuff.h:79
void SetMaxQueueLen(uint32_t len)
Set the maximum queue length.
uint32_t GetSize()
Number of entries.
bool Dequeue(Ipv4Address dst, DsrSendBuffEntry &entry)
Return first found (the earliest) entry for the given destination.
void SetSendBufferTimeout(Time t)
Set the entry lifetime in the queue.
bool Enqueue(DsrSendBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue.
bool Find(Ipv4Address dst)
Check if a packet with destination dst exists in the queue.
std::vector< DsrSendBuffEntry > & GetBuffer()
Return a pointer to the internal queue.
void DropPacketWithDst(Ipv4Address dst)
Remove all packets with destination IP address dst.
#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
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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:85
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:227
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: string.h:42
Ptr< const AttributeChecker > MakeStringChecker(void)
Definition: string.cc:30
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:1309
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:44
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:793
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
mac
Definition: third.py:99
wifi
Definition: third.py:96
uint8_t data[writeSize]
BlackList description.
The gratuitous table entries, it maintains the already sent gratuitous route reply entries.
NetworkKey structure.
Ipv4Address m_ourAdd
local address
Ipv4Address m_destination
destination address
uint16_t m_ackId
acknowledge ID
Ipv4Address m_source
source address
Ipv4Address m_nextHop
next hop
PassiveKey structure.
Ipv4Address m_destination
destination address
Ipv4Address m_source
source address
uint8_t m_segsLeft
segments left
uint16_t m_ackId
acknowledge ID