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