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  std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator, bool> result_i =
447  m_priorityQueue.insert(std::make_pair(i, queue_i));
448  NS_ASSERT_MSG(result_i.second, "Error in creating queues");
449  }
450  Ptr<dsr::DsrRreqTable> rreqTable = CreateObject<dsr::DsrRreqTable>();
451  // Set the initial hop limit
452  rreqTable->SetInitHopLimit(m_discoveryHopLimit);
453  // Configure the request table parameters
454  rreqTable->SetRreqTableSize(m_requestTableSize);
455  rreqTable->SetRreqIdSize(m_requestTableIds);
456  rreqTable->SetUniqueRreqIdSize(m_maxRreqId);
457  SetRequestTable(rreqTable);
458  // Set the passive buffer parameters using just the send buffer parameters
459  Ptr<dsr::DsrPassiveBuffer> passiveBuffer = CreateObject<dsr::DsrPassiveBuffer>();
460  passiveBuffer->SetMaxQueueLen(m_maxSendBuffLen);
461  passiveBuffer->SetPassiveBufferTimeout(m_sendBufferTimeout);
462  SetPassiveBuffer(passiveBuffer);
463 
464  // Set the send buffer parameters
467  // Set the error buffer parameters using just the send buffer parameters
470  // Set the maintenance buffer parameters
473  // Set the gratuitous reply table size
475 
476  if (m_mainAddress == Ipv4Address())
477  {
478  Ipv4Address loopback("127.0.0.1");
479  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
480  {
481  // Use primary address, if multiple
482  Ipv4Address addr = m_ipv4->GetAddress(i, 0).GetLocal();
483  m_broadcast = m_ipv4->GetAddress(i, 0).GetBroadcast();
484  if (addr != loopback)
485  {
486  /*
487  * Set dsr route cache
488  */
489  Ptr<dsr::DsrRouteCache> routeCache = CreateObject<dsr::DsrRouteCache>();
490  // Configure the path cache parameters
491  routeCache->SetCacheType(m_cacheType);
492  routeCache->SetSubRoute(m_subRoute);
493  routeCache->SetMaxCacheLen(m_maxCacheLen);
494  routeCache->SetCacheTimeout(m_maxCacheTime);
495  routeCache->SetMaxEntriesEachDst(m_maxEntriesEachDst);
496  // Parameters for link cache
497  routeCache->SetStabilityDecrFactor(m_stabilityDecrFactor);
498  routeCache->SetStabilityIncrFactor(m_stabilityIncrFactor);
499  routeCache->SetInitStability(m_initStability);
500  routeCache->SetMinLifeTime(m_minLifeTime);
501  routeCache->SetUseExtends(m_useExtends);
502  routeCache->ScheduleTimer();
503  // The call back to handle link error and send error message to appropriate nodes
505  // routeCache->SetCallback (MakeCallback
506  // (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
507  SetRouteCache(routeCache);
508  // Set the main address as the current ip address
509  m_mainAddress = addr;
510 
511  m_ipv4->GetNetDevice(1)->SetPromiscReceiveCallback(
513 
514  // Allow neighbor manager use this interface for layer 2 feedback if possible
515  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(addr));
516  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
517  if (!wifi)
518  {
519  break;
520  }
521  Ptr<WifiMac> mac = wifi->GetMac();
522  if (!mac)
523  {
524  break;
525  }
526 
527  routeCache->AddArpCache(m_ipv4->GetInterface(i)->GetArpCache());
528  NS_LOG_LOGIC("Starting DSR on node " << m_mainAddress);
529  break;
530  }
531  }
533  }
534 }
535 
538 {
539  // Use "NodeList/*/DeviceList/*/ as reference
540  // where element [1] is the Node Id
541  // element [2] is the NetDevice Id
542  std::vector<std::string> elements = GetElementsFromContext(context);
543  Ptr<Node> n = NodeList::GetNode(std::stoi(elements[1]));
544  NS_ASSERT(n);
545  return n->GetDevice(std::stoi(elements[3]));
546 }
547 
548 std::vector<std::string>
550 {
551  std::vector<std::string> elements;
552  size_t pos1 = 0;
553  size_t pos2;
554  while (pos1 != std::string::npos)
555  {
556  pos1 = context.find('/', pos1);
557  pos2 = context.find('/', pos1 + 1);
558  elements.push_back(context.substr(pos1 + 1, pos2 - (pos1 + 1)));
559  pos1 = pos2;
560  }
561  return elements;
562 }
563 
564 void
566 {
568  m_node = nullptr;
569  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); i++)
570  {
571  // Disable layer 2 link state monitoring (if possible)
572  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(i);
573  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice>();
574  if (wifi)
575  {
576  Ptr<WifiMac> mac = wifi->GetMac();
577  if (mac)
578  {
579  Ptr<AdhocWifiMac> adhoc = mac->GetObject<AdhocWifiMac>();
580  if (adhoc)
581  {
582  adhoc->TraceDisconnectWithoutContext("TxErrHeader",
583  m_routeCache->GetTxErrorCallback());
584  m_routeCache->DelArpCache(m_ipv4->GetInterface(i)->GetArpCache());
585  }
586  }
587  }
588  }
590 }
591 
592 void
594 {
595  m_node = node;
596 }
597 
598 Ptr<Node>
600 {
602  return m_node;
603 }
604 
605 void
607 {
608  // / Set the route cache to use
609  m_routeCache = r;
610 }
611 
614 {
615  // / Get the route cache to use
616  return m_routeCache;
617 }
618 
619 void
621 {
622  // / Set the request table to use
623  m_rreqTable = q;
624 }
625 
628 {
629  // / Get the request table to use
630  return m_rreqTable;
631 }
632 
633 void
635 {
636  // / Set the request table to use
637  m_passiveBuffer = p;
638 }
639 
642 {
643  // / Get the request table to use
644  return m_passiveBuffer;
645 }
646 
647 Ptr<Node>
649 {
650  NS_LOG_FUNCTION(this << ipv4Address);
651  int32_t nNodes = NodeList::GetNNodes();
652  for (int32_t i = 0; i < nNodes; ++i)
653  {
654  Ptr<Node> node = NodeList::GetNode(i);
655  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
656  int32_t ifIndex = ipv4->GetInterfaceForAddress(ipv4Address);
657  if (ifIndex != -1)
658  {
659  return node;
660  }
661  }
662  return nullptr;
663 }
664 
665 bool
667 {
668  return m_routeCache->IsLinkCache();
669 }
670 
671 void
673 {
674  m_routeCache->UseExtends(rt);
675 }
676 
677 bool
679 {
680  return m_routeCache->LookupRoute(id, rt);
681 }
682 
683 bool
685 {
686  Ipv4Address nextHop = SearchNextHop(source, nodelist);
687  m_errorBuffer.DropPacketForErrLink(source, nextHop);
688  return m_routeCache->AddRoute_Link(nodelist, source);
689 }
690 
691 bool
693 {
694  std::vector<Ipv4Address> nodelist = rt.GetVector();
695  Ipv4Address nextHop = SearchNextHop(m_mainAddress, nodelist);
697  return m_routeCache->AddRoute(rt);
698 }
699 
700 void
702  Ipv4Address unreachNode,
703  Ipv4Address node)
704 {
705  m_routeCache->DeleteAllRoutesIncludeLink(errorSrc, unreachNode, node);
706 }
707 
708 bool
710 {
711  return m_routeCache->UpdateRouteEntry(dst);
712 }
713 
714 bool
716 {
717  return m_rreqTable->FindSourceEntry(src, dst, id);
718 }
719 
722 {
723  NS_LOG_FUNCTION(this << address);
724  int32_t nNodes = NodeList::GetNNodes();
725  for (int32_t i = 0; i < nNodes; ++i)
726  {
727  Ptr<Node> node = NodeList::GetNode(i);
728  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
729  Ptr<NetDevice> netDevice = ipv4->GetNetDevice(1);
730 
731  if (netDevice->GetAddress() == address)
732  {
733  return ipv4->GetAddress(1, 0).GetLocal();
734  }
735  }
736  return nullptr;
737 }
738 
739 void
740 DsrRouting::PrintVector(std::vector<Ipv4Address>& vec)
741 {
742  NS_LOG_FUNCTION(this);
743  /*
744  * Check elements in a route vector
745  */
746  if (vec.empty())
747  {
748  NS_LOG_DEBUG("The vector is empty");
749  }
750  else
751  {
752  NS_LOG_DEBUG("Print all the elements in a vector");
753  for (std::vector<Ipv4Address>::const_iterator i = vec.begin(); i != vec.end(); ++i)
754  {
755  NS_LOG_DEBUG("The ip address " << *i);
756  }
757  }
758 }
759 
761 DsrRouting::SearchNextHop(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
762 {
763  NS_LOG_FUNCTION(this << ipv4Address);
764  Ipv4Address nextHop;
765  NS_LOG_DEBUG("the vector size " << vec.size());
766  if (vec.size() == 2)
767  {
768  NS_LOG_DEBUG("The two nodes are neighbors");
769  nextHop = vec[1];
770  return nextHop;
771  }
772  else
773  {
774  if (ipv4Address == vec.back())
775  {
776  NS_LOG_DEBUG("We have reached to the final destination " << ipv4Address << " "
777  << vec.back());
778  return ipv4Address;
779  }
780  for (std::vector<Ipv4Address>::const_iterator i = vec.begin(); i != vec.end(); ++i)
781  {
782  if (ipv4Address == (*i))
783  {
784  nextHop = *(++i);
785  return nextHop;
786  }
787  }
788  }
789  NS_LOG_DEBUG("Next hop address not found");
790  Ipv4Address none = "0.0.0.0";
791  return none;
792 }
793 
796 {
797  NS_LOG_FUNCTION(this << nextHop << srcAddress);
798  m_ipv4Route = Create<Ipv4Route>();
799  m_ipv4Route->SetDestination(nextHop);
800  m_ipv4Route->SetGateway(nextHop);
801  m_ipv4Route->SetSource(srcAddress);
802  return m_ipv4Route;
803 }
804 
805 int
807 {
808  // / This is the protocol number for DSR which is 48
809  return PROT_NUMBER;
810 }
811 
812 uint16_t
814 {
815  int32_t nNodes = NodeList::GetNNodes();
816  for (int32_t i = 0; i < nNodes; ++i)
817  {
818  Ptr<Node> node = NodeList::GetNode(i);
819  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
820  if (ipv4->GetAddress(1, 0).GetLocal() == address)
821  {
822  return uint16_t(i);
823  }
824  }
825  return 256;
826 }
827 
830 {
831  if (id >= 256)
832  {
833  NS_LOG_DEBUG("Exceed the node range");
834  return "0.0.0.0";
835  }
836  else
837  {
838  Ptr<Node> node = NodeList::GetNode(uint32_t(id));
839  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
840  return ipv4->GetAddress(1, 0).GetLocal();
841  }
842 }
843 
844 uint32_t
846 {
847  if (messageType == DSR_CONTROL_PACKET)
848  {
849  return 0;
850  }
851  else
852  {
853  return 1;
854  }
855 }
856 
857 void
859 {
861  {
863  }
865  CheckSendBuffer();
866 }
867 
868 void
870 {
871  NS_LOG_INFO(Simulator::Now().As(Time::S) << " Checking send buffer at " << m_mainAddress
872  << " with size " << m_sendBuffer.GetSize());
873 
874  for (std::vector<DsrSendBuffEntry>::iterator i = m_sendBuffer.GetBuffer().begin();
875  i != m_sendBuffer.GetBuffer().end();)
876  {
877  NS_LOG_DEBUG("Here we try to find the data packet in the send buffer");
878  Ipv4Address destination = i->GetDestination();
879  DsrRouteCacheEntry toDst;
880  bool findRoute = m_routeCache->LookupRoute(destination, toDst);
881  if (findRoute)
882  {
883  NS_LOG_INFO("We have found a route for the packet");
884  Ptr<const Packet> packet = i->GetPacket();
885  Ptr<Packet> cleanP = packet->Copy();
886  uint8_t protocol = i->GetProtocol();
887 
888  i = m_sendBuffer.GetBuffer().erase(i);
889 
890  DsrRoutingHeader dsrRoutingHeader;
891  Ptr<Packet> copyP = packet->Copy();
892  Ptr<Packet> dsrPacket = packet->Copy();
893  dsrPacket->RemoveHeader(dsrRoutingHeader);
894  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
895  copyP->RemoveAtStart(offset); // Here the processed size is 8 bytes, which is the fixed
896  // sized extension header
897  // The packet to get ipv4 header
898  Ptr<Packet> ipv4P = copyP->Copy();
899  /*
900  * Peek data to get the option type as well as length and segmentsLeft field
901  */
902  uint32_t size = copyP->GetSize();
903  uint8_t* data = new uint8_t[size];
904  copyP->CopyData(data, size);
905 
906  uint8_t optionType = 0;
907  optionType = *(data);
908 
909  if (optionType == 3)
910  {
911  Ptr<dsr::DsrOptions> dsrOption;
912  DsrOptionHeader dsrOptionHeader;
913  uint8_t errorType = *(data + 2);
914 
915  if (errorType == 1) // This is the Route Error Option
916  {
918  copyP->RemoveHeader(rerr);
919  NS_ASSERT(copyP->GetSize() == 0);
920 
921  DsrOptionRerrUnreachHeader newUnreach;
922  newUnreach.SetErrorType(1);
923  newUnreach.SetErrorSrc(rerr.GetErrorSrc());
924  newUnreach.SetUnreachNode(rerr.GetUnreachNode());
925  newUnreach.SetErrorDst(rerr.GetErrorDst());
926  newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
927  // salvage a packet or not
928 
929  DsrOptionSRHeader sourceRoute;
930  std::vector<Ipv4Address> errorRoute = toDst.GetVector();
931  sourceRoute.SetNodesAddress(errorRoute);
933  if (m_routeCache->IsLinkCache())
934  {
935  m_routeCache->UseExtends(errorRoute);
936  }
937  sourceRoute.SetSegmentsLeft((errorRoute.size() - 2));
938  uint8_t salvage = 0;
939  sourceRoute.SetSalvage(salvage);
940  Ipv4Address nextHop =
941  SearchNextHop(m_mainAddress, errorRoute); // Get the next hop address
942 
943  if (nextHop == "0.0.0.0")
944  {
945  PacketNewRoute(dsrPacket, m_mainAddress, destination, protocol);
946  return;
947  }
948 
949  SetRoute(nextHop, m_mainAddress);
950  uint8_t length = (sourceRoute.GetLength() + newUnreach.GetLength());
951  dsrRoutingHeader.SetNextHeader(protocol);
952  dsrRoutingHeader.SetMessageType(1);
953  dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
954  dsrRoutingHeader.SetDestId(255);
955  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
956  dsrRoutingHeader.AddDsrOption(newUnreach);
957  dsrRoutingHeader.AddDsrOption(sourceRoute);
958 
959  Ptr<Packet> newPacket = Create<Packet>();
960  newPacket->AddHeader(dsrRoutingHeader); // Add the routing header with rerr and
961  // sourceRoute attached to it
962  Ptr<NetDevice> dev =
963  m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
964  m_ipv4Route->SetOutputDevice(dev);
965 
966  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
967  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i =
968  m_priorityQueue.find(priority);
969  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
970  NS_LOG_LOGIC("Will be inserting into priority queue number: " << priority);
971 
972  // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (),
973  // m_ipv4Route);
974 
976  DsrNetworkQueueEntry newEntry(newPacket,
978  nextHop,
979  Simulator::Now(),
980  m_ipv4Route);
981 
982  if (dsrNetworkQueue->Enqueue(newEntry))
983  {
984  Scheduler(priority);
985  }
986  else
987  {
988  NS_LOG_INFO("Packet dropped as dsr network queue is full");
989  }
990  }
991  }
992  else
993  {
994  dsrRoutingHeader.SetNextHeader(protocol);
995  dsrRoutingHeader.SetMessageType(2);
996  dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
997  dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
998 
999  DsrOptionSRHeader sourceRoute;
1000  std::vector<Ipv4Address> nodeList =
1001  toDst.GetVector(); // Get the route from the route entry we found
1002  Ipv4Address nextHop =
1004  nodeList); // Get the next hop address for the route
1005  if (nextHop == "0.0.0.0")
1006  {
1007  PacketNewRoute(dsrPacket, m_mainAddress, destination, protocol);
1008  return;
1009  }
1010  uint8_t salvage = 0;
1011  sourceRoute.SetNodesAddress(
1012  nodeList); // Save the whole route in the source route header of the packet
1013  sourceRoute.SetSegmentsLeft(
1014  (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
1015  sourceRoute.SetSalvage(salvage);
1017  if (m_routeCache->IsLinkCache())
1018  {
1019  m_routeCache->UseExtends(nodeList);
1020  }
1021  uint8_t length = sourceRoute.GetLength();
1022  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1023  dsrRoutingHeader.AddDsrOption(sourceRoute);
1024  cleanP->AddHeader(dsrRoutingHeader);
1025  Ptr<const Packet> mtP = cleanP->Copy();
1026  // Put the data packet in the maintenance queue for data packet retransmission
1027  DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1028  /*ourAddress=*/m_mainAddress,
1029  /*nextHop=*/nextHop,
1030  /*src=*/m_mainAddress,
1031  /*dst=*/destination,
1032  /*ackId=*/0,
1033  /*segsLeft=*/nodeList.size() - 2,
1034  /*expire=*/m_maxMaintainTime);
1035  bool result = m_maintainBuffer.Enqueue(
1036  newEntry); // Enqueue the packet the the maintenance buffer
1037  if (result)
1038  {
1039  NetworkKey networkKey;
1040  networkKey.m_ackId = newEntry.GetAckId();
1041  networkKey.m_ourAdd = newEntry.GetOurAdd();
1042  networkKey.m_nextHop = newEntry.GetNextHop();
1043  networkKey.m_source = newEntry.GetSrc();
1044  networkKey.m_destination = newEntry.GetDst();
1045 
1046  PassiveKey passiveKey;
1047  passiveKey.m_ackId = 0;
1048  passiveKey.m_source = newEntry.GetSrc();
1049  passiveKey.m_destination = newEntry.GetDst();
1050  passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1051 
1052  LinkKey linkKey;
1053  linkKey.m_source = newEntry.GetSrc();
1054  linkKey.m_destination = newEntry.GetDst();
1055  linkKey.m_ourAdd = newEntry.GetOurAdd();
1056  linkKey.m_nextHop = newEntry.GetNextHop();
1057 
1058  m_addressForwardCnt[networkKey] = 0;
1059  m_passiveCnt[passiveKey] = 0;
1060  m_linkCnt[linkKey] = 0;
1061 
1062  if (m_linkAck)
1063  {
1064  ScheduleLinkPacketRetry(newEntry, protocol);
1065  }
1066  else
1067  {
1068  NS_LOG_LOGIC("Not using link acknowledgment");
1069  if (nextHop != destination)
1070  {
1071  SchedulePassivePacketRetry(newEntry, protocol);
1072  }
1073  else
1074  {
1075  // This is the first network retry
1076  ScheduleNetworkPacketRetry(newEntry, true, protocol);
1077  }
1078  }
1079  }
1080  // we need to suspend the normal timer that checks the send buffer
1081  // until we are done sending packets
1083  {
1085  }
1087  return;
1088  }
1089  }
1090  else
1091  {
1092  ++i;
1093  }
1094  }
1095  // after going through the entire send buffer and send all packets found route,
1096  // we need to resume the timer if it has been suspended
1098  {
1099  NS_LOG_DEBUG("Resume the send buffer timer");
1101  }
1102 }
1103 
1104 bool
1106  Ptr<const Packet> packet,
1107  uint16_t protocol,
1108  const Address& from,
1109  const Address& to,
1110  NetDevice::PacketType packetType)
1111 {
1112  if (protocol != Ipv4L3Protocol::PROT_NUMBER)
1113  {
1114  return false;
1115  }
1116  // Remove the ipv4 header here
1117  Ptr<Packet> pktMinusIpHdr = packet->Copy();
1118  Ipv4Header ipv4Header;
1119  pktMinusIpHdr->RemoveHeader(ipv4Header);
1120 
1121  if (ipv4Header.GetProtocol() != DsrRouting::PROT_NUMBER)
1122  {
1123  return false;
1124  }
1125  // Remove the dsr routing header here
1126  Ptr<Packet> pktMinusDsrHdr = pktMinusIpHdr->Copy();
1127  DsrRoutingHeader dsrRouting;
1128  pktMinusDsrHdr->RemoveHeader(dsrRouting);
1129 
1130  /*
1131  * Message type 2 means the data packet, we will further process the data
1132  * packet for delivery notification, safely ignore control packet
1133  * Another check here is our own address, if this is the data destinated for us,
1134  * process it further, otherwise, just ignore it
1135  */
1136  Ipv4Address ourAddress = m_ipv4->GetAddress(1, 0).GetLocal();
1137  // check if the message type is 2 and if the ipv4 address matches
1138  if (dsrRouting.GetMessageType() == 2 && ourAddress == m_mainAddress)
1139  {
1140  NS_LOG_DEBUG("data packet receives " << packet->GetUid());
1141  Ipv4Address sourceIp = GetIPfromID(dsrRouting.GetSourceId());
1142  Ipv4Address destinationIp = GetIPfromID(dsrRouting.GetDestId());
1144  Ipv4Address previousHop = GetIPfromMAC(Mac48Address::ConvertFrom(from));
1145 
1146  Ptr<Packet> p = Create<Packet>();
1147  // Here the segments left value need to plus one to check the earlier hop maintain buffer
1148  // entry
1149  DsrMaintainBuffEntry newEntry;
1150  newEntry.SetPacket(p);
1151  newEntry.SetSrc(sourceIp);
1152  newEntry.SetDst(destinationIp);
1154  newEntry.SetOurAdd(previousHop);
1155  newEntry.SetNextHop(ourAddress);
1157  Ptr<Node> node = GetNodeWithAddress(previousHop);
1158  NS_LOG_DEBUG("The previous node " << previousHop);
1159 
1161  dsr->CancelLinkPacketTimer(newEntry);
1162  }
1163 
1164  // Receive only IP packets and packets destined for other hosts
1165  if (packetType == NetDevice::PACKET_OTHERHOST)
1166  {
1167  // just to minimize debug output
1168  NS_LOG_INFO(this << from << to << packetType << *pktMinusIpHdr);
1169 
1170  uint8_t offset =
1171  dsrRouting
1172  .GetDsrOptionsOffset(); // Get the offset for option header, 4 bytes in this case
1173  uint8_t nextHeader = dsrRouting.GetNextHeader();
1174  uint32_t sourceId = dsrRouting.GetSourceId();
1175  Ipv4Address source = GetIPfromID(sourceId);
1176 
1177  // This packet is used to peek option type
1178  pktMinusIpHdr->RemoveAtStart(offset);
1179  /*
1180  * Peek data to get the option type as well as length and segmentsLeft field
1181  */
1182  uint32_t size = pktMinusIpHdr->GetSize();
1183  uint8_t* data = new uint8_t[size];
1184  pktMinusIpHdr->CopyData(data, size);
1185  uint8_t optionType = 0;
1186  optionType = *(data);
1187 
1188  Ptr<dsr::DsrOptions> dsrOption;
1189 
1190  if (optionType == 96) // This is the source route option
1191  {
1192  Ipv4Address promiscSource = GetIPfromMAC(Mac48Address::ConvertFrom(from));
1193  dsrOption = GetOption(
1194  optionType); // Get the relative DSR option and demux to the process function
1196  << " DSR node " << m_mainAddress
1197  << " overhearing packet PID: " << pktMinusIpHdr->GetUid() << " from "
1198  << promiscSource << " to " << GetIPfromMAC(Mac48Address::ConvertFrom(to))
1199  << " with source IP " << ipv4Header.GetSource() << " and destination IP "
1200  << ipv4Header.GetDestination() << " and packet : " << *pktMinusDsrHdr);
1201 
1202  bool isPromisc = true; // Set the boolean value isPromisc as true
1203  dsrOption->Process(pktMinusIpHdr,
1204  pktMinusDsrHdr,
1205  m_mainAddress,
1206  source,
1207  ipv4Header,
1208  nextHeader,
1209  isPromisc,
1210  promiscSource);
1211  return true;
1212  }
1213  }
1214  return false;
1215 }
1216 
1217 void
1219  Ipv4Address source,
1220  Ipv4Address destination,
1221  uint8_t protocol)
1222 {
1223  NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol);
1224  // Look up routes for the specific destination
1225  DsrRouteCacheEntry toDst;
1226  bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1227  // Queue the packet if there is no route pre-existing
1228  if (!findRoute)
1229  {
1231  << " " << m_mainAddress
1232  << " there is no route for this packet, queue the packet");
1233 
1234  Ptr<Packet> p = packet->Copy();
1235  DsrSendBuffEntry newEntry(p,
1236  destination,
1238  protocol); // Create a new entry for send buffer
1239  bool result = m_sendBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1240  if (result)
1241  {
1242  NS_LOG_INFO(Simulator::Now().As(Time::S) << " Add packet PID: " << packet->GetUid()
1243  << " to queue. Packet: " << *packet);
1244 
1245  NS_LOG_LOGIC("Send RREQ to" << destination);
1246  if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1247  (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1248  {
1249  /*
1250  * Call the send request function, it will update the request table entry and ttl
1251  * there
1252  */
1253  SendInitialRequest(source, destination, protocol);
1254  }
1255  }
1256  }
1257  else
1258  {
1259  Ptr<Packet> cleanP = packet->Copy();
1260  DsrRoutingHeader dsrRoutingHeader;
1261  dsrRoutingHeader.SetNextHeader(protocol);
1262  dsrRoutingHeader.SetMessageType(2);
1263  dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1264  dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1265 
1266  DsrOptionSRHeader sourceRoute;
1267  std::vector<Ipv4Address> nodeList =
1268  toDst.GetVector(); // Get the route from the route entry we found
1269  Ipv4Address nextHop =
1270  SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
1271  if (nextHop == "0.0.0.0")
1272  {
1273  PacketNewRoute(cleanP, source, destination, protocol);
1274  return;
1275  }
1276  uint8_t salvage = 0;
1277  sourceRoute.SetNodesAddress(
1278  nodeList); // Save the whole route in the source route header of the packet
1280  if (m_routeCache->IsLinkCache())
1281  {
1282  m_routeCache->UseExtends(nodeList);
1283  }
1284  sourceRoute.SetSegmentsLeft(
1285  (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
1286  sourceRoute.SetSalvage(salvage);
1287 
1288  uint8_t length = sourceRoute.GetLength();
1289  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1290  dsrRoutingHeader.AddDsrOption(sourceRoute);
1291  cleanP->AddHeader(dsrRoutingHeader);
1292  Ptr<const Packet> mtP = cleanP->Copy();
1293  SetRoute(nextHop, m_mainAddress);
1294  // Put the data packet in the maintenance queue for data packet retransmission
1295  DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1296  /*ourAddress=*/m_mainAddress,
1297  /*nextHop=*/nextHop,
1298  /*src=*/source,
1299  /*dst=*/destination,
1300  /*ackId=*/0,
1301  /*segsLeft=*/nodeList.size() - 2,
1302  /*expire=*/m_maxMaintainTime);
1303  bool result =
1304  m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1305 
1306  if (result)
1307  {
1308  NetworkKey networkKey;
1309  networkKey.m_ackId = newEntry.GetAckId();
1310  networkKey.m_ourAdd = newEntry.GetOurAdd();
1311  networkKey.m_nextHop = newEntry.GetNextHop();
1312  networkKey.m_source = newEntry.GetSrc();
1313  networkKey.m_destination = newEntry.GetDst();
1314 
1315  PassiveKey passiveKey;
1316  passiveKey.m_ackId = 0;
1317  passiveKey.m_source = newEntry.GetSrc();
1318  passiveKey.m_destination = newEntry.GetDst();
1319  passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1320 
1321  LinkKey linkKey;
1322  linkKey.m_source = newEntry.GetSrc();
1323  linkKey.m_destination = newEntry.GetDst();
1324  linkKey.m_ourAdd = newEntry.GetOurAdd();
1325  linkKey.m_nextHop = newEntry.GetNextHop();
1326 
1327  m_addressForwardCnt[networkKey] = 0;
1328  m_passiveCnt[passiveKey] = 0;
1329  m_linkCnt[linkKey] = 0;
1330 
1331  if (m_linkAck)
1332  {
1333  ScheduleLinkPacketRetry(newEntry, protocol);
1334  }
1335  else
1336  {
1337  NS_LOG_LOGIC("Not using link acknowledgment");
1338  if (nextHop != destination)
1339  {
1340  SchedulePassivePacketRetry(newEntry, protocol);
1341  }
1342  else
1343  {
1344  // This is the first network retry
1345  ScheduleNetworkPacketRetry(newEntry, true, protocol);
1346  }
1347  }
1348  }
1349  }
1350 }
1351 
1352 void
1354  Ipv4Address destination,
1355  Ipv4Address originalDst,
1356  uint8_t salvage,
1357  uint8_t protocol)
1358 {
1359  NS_LOG_FUNCTION(this << unreachNode << destination << originalDst << (uint32_t)salvage
1360  << (uint32_t)protocol);
1361  DsrRoutingHeader dsrRoutingHeader;
1362  dsrRoutingHeader.SetNextHeader(protocol);
1363  dsrRoutingHeader.SetMessageType(1);
1364  dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
1365  dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1366 
1367  DsrOptionRerrUnreachHeader rerrUnreachHeader;
1368  rerrUnreachHeader.SetErrorType(1);
1369  rerrUnreachHeader.SetErrorSrc(m_mainAddress);
1370  rerrUnreachHeader.SetUnreachNode(unreachNode);
1371  rerrUnreachHeader.SetErrorDst(destination);
1372  rerrUnreachHeader.SetOriginalDst(originalDst);
1373  rerrUnreachHeader.SetSalvage(salvage); // Set the value about whether to salvage a packet or not
1374  uint8_t rerrLength = rerrUnreachHeader.GetLength();
1375 
1376  DsrRouteCacheEntry toDst;
1377  bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1378  // Queue the packet if there is no route pre-existing
1379  Ptr<Packet> newPacket = Create<Packet>();
1380  if (!findRoute)
1381  {
1382  if (destination == m_mainAddress)
1383  {
1384  NS_LOG_INFO("We are the error source, send request to original dst " << originalDst);
1385  // Send error request message if we are the source node
1386  SendErrorRequest(rerrUnreachHeader, protocol);
1387  }
1388  else
1389  {
1391  << " " << m_mainAddress
1392  << " there is no route for this packet, queue the packet");
1393 
1394  dsrRoutingHeader.SetPayloadLength(rerrLength + 2);
1395  dsrRoutingHeader.AddDsrOption(rerrUnreachHeader);
1396  newPacket->AddHeader(dsrRoutingHeader);
1397  Ptr<Packet> p = newPacket->Copy();
1398  // Save the error packet in the error buffer
1399  DsrErrorBuffEntry newEntry(p,
1400  destination,
1401  m_mainAddress,
1402  unreachNode,
1404  protocol);
1405  bool result = m_errorBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1406  if (result)
1407  {
1409  << " Add packet PID: " << p->GetUid() << " to queue. Packet: " << *p);
1410  NS_LOG_LOGIC("Send RREQ to" << destination);
1411  if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1412  (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1413  {
1414  NS_LOG_DEBUG("When there is no existing route request for "
1415  << destination << ", initialize one");
1416  /*
1417  * Call the send request function, it will update the request table entry and
1418  * ttl there
1419  */
1420  SendInitialRequest(m_mainAddress, destination, protocol);
1421  }
1422  }
1423  }
1424  }
1425  else
1426  {
1427  std::vector<Ipv4Address> nodeList = toDst.GetVector();
1428  Ipv4Address nextHop = SearchNextHop(m_mainAddress, nodeList);
1429  if (nextHop == "0.0.0.0")
1430  {
1431  NS_LOG_DEBUG("The route is not right");
1432  PacketNewRoute(newPacket, m_mainAddress, destination, protocol);
1433  return;
1434  }
1435  DsrOptionSRHeader sourceRoute;
1436  sourceRoute.SetNodesAddress(nodeList);
1438  if (m_routeCache->IsLinkCache())
1439  {
1440  m_routeCache->UseExtends(nodeList);
1441  }
1442  sourceRoute.SetSegmentsLeft((nodeList.size() - 2));
1443  uint8_t srLength = sourceRoute.GetLength();
1444  uint8_t length = (srLength + rerrLength);
1445 
1446  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
1447  dsrRoutingHeader.AddDsrOption(rerrUnreachHeader);
1448  dsrRoutingHeader.AddDsrOption(sourceRoute);
1449  newPacket->AddHeader(dsrRoutingHeader);
1450 
1451  SetRoute(nextHop, m_mainAddress);
1452  Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1453  m_ipv4Route->SetOutputDevice(dev);
1454  NS_LOG_INFO("Send the packet to the next hop address " << nextHop << " from "
1455  << m_mainAddress << " with the size "
1456  << newPacket->GetSize());
1457 
1458  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
1459  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1460  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1461  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
1462  << " number: " << priority);
1463 
1464  // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1465 
1467  DsrNetworkQueueEntry newEntry(newPacket,
1468  m_mainAddress,
1469  nextHop,
1470  Simulator::Now(),
1471  m_ipv4Route);
1472 
1473  if (dsrNetworkQueue->Enqueue(newEntry))
1474  {
1475  Scheduler(priority);
1476  }
1477  else
1478  {
1479  NS_LOG_INFO("Packet dropped as dsr network queue is full");
1480  }
1481  }
1482 }
1483 
1484 void
1486  DsrOptionSRHeader& sourceRoute,
1487  Ipv4Address nextHop,
1488  uint8_t protocol,
1489  Ptr<Ipv4Route> route)
1490 {
1491  NS_LOG_FUNCTION(this << rerr << sourceRoute << nextHop << (uint32_t)protocol << route);
1492  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1493  DsrRoutingHeader dsrRoutingHeader;
1494  dsrRoutingHeader.SetNextHeader(protocol);
1495  dsrRoutingHeader.SetMessageType(1);
1496  dsrRoutingHeader.SetSourceId(GetIDfromIP(rerr.GetErrorSrc()));
1497  dsrRoutingHeader.SetDestId(GetIDfromIP(rerr.GetErrorDst()));
1498 
1499  uint8_t length = (sourceRoute.GetLength() + rerr.GetLength());
1500  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
1501  dsrRoutingHeader.AddDsrOption(rerr);
1502  dsrRoutingHeader.AddDsrOption(sourceRoute);
1503  Ptr<Packet> packet = Create<Packet>();
1504  packet->AddHeader(dsrRoutingHeader);
1505  Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1506  route->SetOutputDevice(dev);
1507 
1508  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
1509  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1510  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1511  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
1512  << " number: " << priority);
1513 
1514  // m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
1515 
1517  DsrNetworkQueueEntry newEntry(packet, m_mainAddress, nextHop, Simulator::Now(), route);
1518 
1519  if (dsrNetworkQueue->Enqueue(newEntry))
1520  {
1521  Scheduler(priority);
1522  }
1523  else
1524  {
1525  NS_LOG_INFO("Packet dropped as dsr network queue is full");
1526  }
1527 }
1528 
1529 void
1531  Ipv4Address source,
1532  Ipv4Address destination,
1533  uint8_t protocol,
1534  Ptr<Ipv4Route> route)
1535 {
1536  NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)protocol << route);
1537  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1538 
1539  if (protocol == 1)
1540  {
1541  NS_LOG_INFO("Drop packet. Not handling ICMP packet for now");
1542  }
1543  else
1544  {
1545  // Look up routes for the specific destination
1546  DsrRouteCacheEntry toDst;
1547  bool findRoute = m_routeCache->LookupRoute(destination, toDst);
1548  // Queue the packet if there is no route pre-existing
1549  if (!findRoute)
1550  {
1552  << " " << m_mainAddress
1553  << " there is no route for this packet, queue the packet");
1554 
1555  Ptr<Packet> p = packet->Copy();
1556  DsrSendBuffEntry newEntry(p,
1557  destination,
1559  protocol); // Create a new entry for send buffer
1560  bool result = m_sendBuffer.Enqueue(newEntry); // Enqueue the packet in send buffer
1561  if (result)
1562  {
1563  NS_LOG_INFO(Simulator::Now().As(Time::S) << " Add packet PID: " << packet->GetUid()
1564  << " to send buffer. Packet: " << *packet);
1565  // Only when there is no existing route request timer when new route request is
1566  // scheduled
1567  if ((m_addressReqTimer.find(destination) == m_addressReqTimer.end()) &&
1568  (m_nonPropReqTimer.find(destination) == m_nonPropReqTimer.end()))
1569  {
1570  /*
1571  * Call the send request function, it will update the request table entry and
1572  * ttl value
1573  */
1574  NS_LOG_LOGIC("Send initial RREQ to " << destination);
1575  SendInitialRequest(source, destination, protocol);
1576  }
1577  else
1578  {
1579  NS_LOG_LOGIC("There is existing route request timer with request count "
1580  << m_rreqTable->GetRreqCnt(destination));
1581  }
1582  }
1583  }
1584  else
1585  {
1586  Ptr<Packet> cleanP = packet->Copy();
1587  DsrRoutingHeader dsrRoutingHeader;
1588  dsrRoutingHeader.SetNextHeader(protocol);
1589  dsrRoutingHeader.SetMessageType(2);
1590  dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1591  dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1592 
1593  DsrOptionSRHeader sourceRoute;
1594  std::vector<Ipv4Address> nodeList =
1595  toDst.GetVector(); // Get the route from the route entry we found
1596  Ipv4Address nextHop =
1597  SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
1598  if (nextHop == "0.0.0.0")
1599  {
1600  PacketNewRoute(cleanP, source, destination, protocol);
1601  return;
1602  }
1603  uint8_t salvage = 0;
1604  sourceRoute.SetNodesAddress(
1605  nodeList); // Save the whole route in the source route header of the packet
1607  if (m_routeCache->IsLinkCache())
1608  {
1609  m_routeCache->UseExtends(nodeList);
1610  }
1611  sourceRoute.SetSegmentsLeft(
1612  (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
1613  sourceRoute.SetSalvage(salvage);
1614 
1615  uint8_t length = sourceRoute.GetLength();
1616 
1617  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1618  dsrRoutingHeader.AddDsrOption(sourceRoute);
1619  cleanP->AddHeader(dsrRoutingHeader);
1620 
1621  Ptr<const Packet> mtP = cleanP->Copy();
1622  NS_LOG_DEBUG("maintain packet size " << cleanP->GetSize());
1623  // Put the data packet in the maintenance queue for data packet retransmission
1624  DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1625  /*ourAddress=*/m_mainAddress,
1626  /*nextHop=*/nextHop,
1627  /*src=*/source,
1628  /*dst=*/destination,
1629  /*ackId=*/0,
1630  /*segsLeft=*/nodeList.size() - 2,
1631  /*expire=*/m_maxMaintainTime);
1632  bool result =
1633  m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1634  if (result)
1635  {
1636  NetworkKey networkKey;
1637  networkKey.m_ackId = newEntry.GetAckId();
1638  networkKey.m_ourAdd = newEntry.GetOurAdd();
1639  networkKey.m_nextHop = newEntry.GetNextHop();
1640  networkKey.m_source = newEntry.GetSrc();
1641  networkKey.m_destination = newEntry.GetDst();
1642 
1643  PassiveKey passiveKey;
1644  passiveKey.m_ackId = 0;
1645  passiveKey.m_source = newEntry.GetSrc();
1646  passiveKey.m_destination = newEntry.GetDst();
1647  passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1648 
1649  LinkKey linkKey;
1650  linkKey.m_source = newEntry.GetSrc();
1651  linkKey.m_destination = newEntry.GetDst();
1652  linkKey.m_ourAdd = newEntry.GetOurAdd();
1653  linkKey.m_nextHop = newEntry.GetNextHop();
1654 
1655  m_addressForwardCnt[networkKey] = 0;
1656  m_passiveCnt[passiveKey] = 0;
1657  m_linkCnt[linkKey] = 0;
1658 
1659  if (m_linkAck)
1660  {
1661  ScheduleLinkPacketRetry(newEntry, protocol);
1662  }
1663  else
1664  {
1665  NS_LOG_LOGIC("Not using link acknowledgment");
1666  if (nextHop != destination)
1667  {
1668  SchedulePassivePacketRetry(newEntry, protocol);
1669  }
1670  else
1671  {
1672  // This is the first network retry
1673  ScheduleNetworkPacketRetry(newEntry, true, protocol);
1674  }
1675  }
1676  }
1677 
1678  if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(destination))
1679  {
1680  // Try to send packet from *previously* queued entries from send buffer if any
1683  this,
1684  sourceRoute,
1685  nextHop,
1686  protocol);
1687  }
1688  }
1689  }
1690 }
1691 
1692 uint16_t
1694 {
1695  NS_LOG_FUNCTION(this << packet << nextHop);
1696  // This packet is used to peek option type
1697  Ptr<Packet> dsrP = packet->Copy();
1698  Ptr<Packet> tmpP = packet->Copy();
1699 
1700  DsrRoutingHeader dsrRoutingHeader;
1701  dsrP->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
1702  uint8_t protocol = dsrRoutingHeader.GetNextHeader();
1703  uint32_t sourceId = dsrRoutingHeader.GetSourceId();
1704  uint32_t destinationId = dsrRoutingHeader.GetDestId();
1705  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
1706  tmpP->RemoveAtStart(
1707  offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1708 
1709  // Get the number of routers' address field
1710  uint8_t buf[2];
1711  tmpP->CopyData(buf, sizeof(buf));
1712  uint8_t numberAddress = (buf[1] - 2) / 4;
1713  DsrOptionSRHeader sourceRoute;
1714  sourceRoute.SetNumberAddress(numberAddress);
1715  tmpP->RemoveHeader(sourceRoute); // this is a clean packet without any dsr involved headers
1716 
1717  DsrOptionAckReqHeader ackReq;
1718  m_ackId = m_routeCache->CheckUniqueAckId(nextHop);
1719  ackReq.SetAckId(m_ackId);
1720  uint8_t length = (sourceRoute.GetLength() + ackReq.GetLength());
1721  DsrRoutingHeader newDsrRoutingHeader;
1722  newDsrRoutingHeader.SetNextHeader(protocol);
1723  newDsrRoutingHeader.SetMessageType(2);
1724  newDsrRoutingHeader.SetSourceId(sourceId);
1725  newDsrRoutingHeader.SetDestId(destinationId);
1726  newDsrRoutingHeader.SetPayloadLength(length + 4);
1727  newDsrRoutingHeader.AddDsrOption(sourceRoute);
1728  newDsrRoutingHeader.AddDsrOption(ackReq);
1729  dsrP->AddHeader(newDsrRoutingHeader);
1730  // give the dsrP value to packet and then return
1731  packet = dsrP;
1732  return m_ackId;
1733 }
1734 
1735 void
1737  Ipv4Address source,
1738  Ipv4Address nextHop,
1739  uint8_t protocol)
1740 {
1741  NS_LOG_FUNCTION(this << packet << source << nextHop << (uint32_t)protocol);
1742  // Send out the data packet
1743  m_ipv4Route = SetRoute(nextHop, m_mainAddress);
1744  Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
1745  m_ipv4Route->SetOutputDevice(dev);
1746 
1747  uint32_t priority = GetPriority(DSR_DATA_PACKET);
1748  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1749  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1750  NS_LOG_INFO("Will be inserting into priority queue number: " << priority);
1751 
1752  // m_downTarget (packet, source, nextHop, GetProtocolNumber (), m_ipv4Route);
1753 
1755  DsrNetworkQueueEntry newEntry(packet, source, nextHop, Simulator::Now(), m_ipv4Route);
1756 
1757  if (dsrNetworkQueue->Enqueue(newEntry))
1758  {
1759  Scheduler(priority);
1760  }
1761  else
1762  {
1763  NS_LOG_INFO("Packet dropped as dsr network queue is full");
1764  }
1765 }
1766 
1767 void
1768 DsrRouting::Scheduler(uint32_t priority)
1769 {
1770  NS_LOG_FUNCTION(this);
1771  PriorityScheduler(priority, true);
1772 }
1773 
1774 void
1775 DsrRouting::PriorityScheduler(uint32_t priority, bool continueWithFirst)
1776 {
1777  NS_LOG_FUNCTION(this << priority << continueWithFirst);
1778  uint32_t numPriorities;
1779  if (continueWithFirst)
1780  {
1781  numPriorities = 0;
1782  }
1783  else
1784  {
1785  numPriorities = priority;
1786  }
1787  // priorities ranging from 0 to m_numPriorityQueues, with 0 as the highest priority
1788  for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
1789  {
1790  std::map<uint32_t, Ptr<DsrNetworkQueue>>::iterator q = m_priorityQueue.find(i);
1791  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
1792  uint32_t queueSize = dsrNetworkQueue->GetSize();
1793  if (queueSize == 0)
1794  {
1795  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1796  {
1797  i = 0;
1798  }
1799  else
1800  {
1801  i++;
1802  }
1803  }
1804  else
1805  {
1806  uint32_t totalQueueSize = 0;
1807  for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator j =
1808  m_priorityQueue.begin();
1809  j != m_priorityQueue.end();
1810  j++)
1811  {
1812  NS_LOG_INFO("The size of the network queue for " << j->first << " is "
1813  << j->second->GetSize());
1814  totalQueueSize += j->second->GetSize();
1815  NS_LOG_INFO("The total network queue size is " << totalQueueSize);
1816  }
1817  if (totalQueueSize > 5)
1818  {
1819  // Here the queue size is larger than 5, we need to increase the retransmission
1820  // timer for each packet in the network queue
1822  }
1823  DsrNetworkQueueEntry newEntry;
1824  dsrNetworkQueue->Dequeue(newEntry);
1825  if (SendRealDown(newEntry))
1826  {
1827  NS_LOG_LOGIC("Packet sent by Dsr. Calling PriorityScheduler after some time");
1828  // packet was successfully sent down. call scheduler after some time
1831  this,
1832  i,
1833  false);
1834  }
1835  else
1836  {
1837  // packet was dropped by Dsr. Call scheduler immediately so that we can
1838  // send another packet immediately.
1839  NS_LOG_LOGIC("Packet dropped by Dsr. Calling PriorityScheduler immediately");
1841  }
1842 
1843  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1844  {
1845  i = 0;
1846  }
1847  else
1848  {
1849  i++;
1850  }
1851  }
1852  }
1853 }
1854 
1855 void
1857 {
1858  NS_LOG_FUNCTION(this);
1859  // We may want to get the queue first and then we need to save a vector of the entries here and
1860  // then find
1861  uint32_t priority = GetPriority(DSR_DATA_PACKET);
1862  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
1863  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1864 
1865  std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue();
1866  for (std::vector<DsrNetworkQueueEntry>::iterator i = newNetworkQueue.begin();
1867  i != newNetworkQueue.end();
1868  i++)
1869  {
1870  Ipv4Address nextHop = i->GetNextHopAddress();
1871  for (std::map<NetworkKey, Timer>::iterator j = m_addressForwardTimer.begin();
1872  j != m_addressForwardTimer.end();
1873  j++)
1874  {
1875  if (nextHop == j->first.m_nextHop)
1876  {
1877  NS_LOG_DEBUG("The network delay left is " << j->second.GetDelayLeft());
1878  j->second.SetDelay(j->second.GetDelayLeft() + m_retransIncr);
1879  }
1880  }
1881  }
1882 }
1883 
1884 bool
1886 {
1887  NS_LOG_FUNCTION(this);
1888  Ipv4Address source = newEntry.GetSourceAddress();
1889  Ipv4Address nextHop = newEntry.GetNextHopAddress();
1890  Ptr<Packet> packet = newEntry.GetPacket()->Copy();
1891  Ptr<Ipv4Route> route = newEntry.GetIpv4Route();
1892  m_downTarget(packet, source, nextHop, GetProtocolNumber(), route);
1893  return true;
1894 }
1895 
1896 void
1898  Ipv4Address nextHop,
1899  uint8_t protocol)
1900 {
1901  NS_LOG_FUNCTION(this << nextHop << (uint32_t)protocol);
1902  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
1903 
1904  // Reconstruct the route and Retransmit the data packet
1905  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1906  Ipv4Address destination = nodeList.back();
1907  Ipv4Address source = nodeList.front(); // Get the source address
1908  NS_LOG_INFO("The nexthop address " << nextHop << " the source " << source << " the destination "
1909  << destination);
1910  /*
1911  * Here we try to find data packet from send buffer, if packet with this destination found, send
1912  * it out
1913  */
1914  if (m_sendBuffer.Find(destination))
1915  {
1916  NS_LOG_DEBUG("destination over here " << destination);
1917 
1919  if (m_routeCache->IsLinkCache())
1920  {
1921  m_routeCache->UseExtends(nodeList);
1922  }
1923  DsrSendBuffEntry entry;
1924  if (m_sendBuffer.Dequeue(destination, entry))
1925  {
1926  Ptr<Packet> packet = entry.GetPacket()->Copy();
1927  Ptr<Packet> p = packet->Copy(); // get a copy of the packet
1928  // Set the source route option
1929  DsrRoutingHeader dsrRoutingHeader;
1930  dsrRoutingHeader.SetNextHeader(protocol);
1931  dsrRoutingHeader.SetMessageType(2);
1932  dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1933  dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
1934 
1935  uint8_t length = sourceRoute.GetLength();
1936  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
1937  dsrRoutingHeader.AddDsrOption(sourceRoute);
1938 
1939  p->AddHeader(dsrRoutingHeader);
1940 
1941  Ptr<const Packet> mtP = p->Copy();
1942  // Put the data packet in the maintenance queue for data packet retransmission
1943  DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
1944  /*ourAddress=*/m_mainAddress,
1945  /*nextHop=*/nextHop,
1946  /*src=*/source,
1947  /*dst=*/destination,
1948  /*ackId=*/0,
1949  /*segsLeft=*/nodeList.size() - 2,
1950  /*expire=*/m_maxMaintainTime);
1951  bool result =
1952  m_maintainBuffer.Enqueue(newEntry); // Enqueue the packet the the maintenance buffer
1953 
1954  if (result)
1955  {
1956  NetworkKey networkKey;
1957  networkKey.m_ackId = newEntry.GetAckId();
1958  networkKey.m_ourAdd = newEntry.GetOurAdd();
1959  networkKey.m_nextHop = newEntry.GetNextHop();
1960  networkKey.m_source = newEntry.GetSrc();
1961  networkKey.m_destination = newEntry.GetDst();
1962 
1963  PassiveKey passiveKey;
1964  passiveKey.m_ackId = 0;
1965  passiveKey.m_source = newEntry.GetSrc();
1966  passiveKey.m_destination = newEntry.GetDst();
1967  passiveKey.m_segsLeft = newEntry.GetSegsLeft();
1968 
1969  LinkKey linkKey;
1970  linkKey.m_source = newEntry.GetSrc();
1971  linkKey.m_destination = newEntry.GetDst();
1972  linkKey.m_ourAdd = newEntry.GetOurAdd();
1973  linkKey.m_nextHop = newEntry.GetNextHop();
1974 
1975  m_addressForwardCnt[networkKey] = 0;
1976  m_passiveCnt[passiveKey] = 0;
1977  m_linkCnt[linkKey] = 0;
1978 
1979  if (m_linkAck)
1980  {
1981  ScheduleLinkPacketRetry(newEntry, protocol);
1982  }
1983  else
1984  {
1985  NS_LOG_LOGIC("Not using link acknowledgment");
1986  if (nextHop != destination)
1987  {
1988  SchedulePassivePacketRetry(newEntry, protocol);
1989  }
1990  else
1991  {
1992  // This is the first network retry
1993  ScheduleNetworkPacketRetry(newEntry, true, protocol);
1994  }
1995  }
1996  }
1997 
1998  NS_LOG_DEBUG("send buffer size here and the destination " << m_sendBuffer.GetSize()
1999  << " " << destination);
2000  if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(destination))
2001  {
2002  NS_LOG_LOGIC("Schedule sending the next packet in send buffer");
2005  this,
2006  sourceRoute,
2007  nextHop,
2008  protocol);
2009  }
2010  }
2011  else
2012  {
2013  NS_LOG_LOGIC("All queued packets are out-dated for the destination in send buffer");
2014  }
2015  }
2016  /*
2017  * Here we try to find data packet from send buffer, if packet with this destination found, send
2018  * it out
2019  */
2020  else if (m_errorBuffer.Find(destination))
2021  {
2022  DsrErrorBuffEntry entry;
2023  if (m_errorBuffer.Dequeue(destination, entry))
2024  {
2025  Ptr<Packet> packet = entry.GetPacket()->Copy();
2026  NS_LOG_DEBUG("The queued packet size " << packet->GetSize());
2027 
2028  DsrRoutingHeader dsrRoutingHeader;
2029  Ptr<Packet> copyP = packet->Copy();
2030  Ptr<Packet> dsrPacket = packet->Copy();
2031  dsrPacket->RemoveHeader(dsrRoutingHeader);
2032  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2033  copyP->RemoveAtStart(offset); // Here the processed size is 8 bytes, which is the fixed
2034  // sized extension header
2035  /*
2036  * Peek data to get the option type as well as length and segmentsLeft field
2037  */
2038  uint32_t size = copyP->GetSize();
2039  uint8_t* data = new uint8_t[size];
2040  copyP->CopyData(data, size);
2041 
2042  uint8_t optionType = 0;
2043  optionType = *(data);
2044  NS_LOG_DEBUG("The option type value in send packet " << (uint32_t)optionType);
2045  if (optionType == 3)
2046  {
2047  NS_LOG_DEBUG("The packet is error packet");
2048  Ptr<dsr::DsrOptions> dsrOption;
2049  DsrOptionHeader dsrOptionHeader;
2050 
2051  uint8_t errorType = *(data + 2);
2052  NS_LOG_DEBUG("The error type");
2053  if (errorType == 1)
2054  {
2055  NS_LOG_DEBUG("The packet is route error unreach packet");
2057  copyP->RemoveHeader(rerr);
2058  NS_ASSERT(copyP->GetSize() == 0);
2059  uint8_t length = (sourceRoute.GetLength() + rerr.GetLength());
2060 
2061  DsrOptionRerrUnreachHeader newUnreach;
2062  newUnreach.SetErrorType(1);
2063  newUnreach.SetErrorSrc(rerr.GetErrorSrc());
2064  newUnreach.SetUnreachNode(rerr.GetUnreachNode());
2065  newUnreach.SetErrorDst(rerr.GetErrorDst());
2066  newUnreach.SetOriginalDst(rerr.GetOriginalDst());
2067  newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
2068  // salvage a packet or not
2069 
2070  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2071  DsrRoutingHeader newRoutingHeader;
2072  newRoutingHeader.SetNextHeader(protocol);
2073  newRoutingHeader.SetMessageType(1);
2074  newRoutingHeader.SetSourceId(GetIDfromIP(rerr.GetErrorSrc()));
2075  newRoutingHeader.SetDestId(GetIDfromIP(rerr.GetErrorDst()));
2076  newRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
2077  newRoutingHeader.AddDsrOption(newUnreach);
2078  newRoutingHeader.AddDsrOption(sourceRoute);
2080  if (m_routeCache->IsLinkCache())
2081  {
2082  m_routeCache->UseExtends(nodeList);
2083  }
2084  SetRoute(nextHop, m_mainAddress);
2085  Ptr<Packet> newPacket = Create<Packet>();
2086  newPacket->AddHeader(newRoutingHeader); // Add the extension header with rerr
2087  // and sourceRoute attached to it
2088  Ptr<NetDevice> dev =
2089  m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2090  m_ipv4Route->SetOutputDevice(dev);
2091 
2092  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
2093  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i =
2094  m_priorityQueue.find(priority);
2095  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2096  NS_LOG_DEBUG("Will be inserting into priority queue "
2097  << dsrNetworkQueue << " number: " << priority);
2098 
2099  // m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (),
2100  // m_ipv4Route);
2101 
2103  DsrNetworkQueueEntry newEntry(newPacket,
2104  m_mainAddress,
2105  nextHop,
2106  Simulator::Now(),
2107  m_ipv4Route);
2108 
2109  if (dsrNetworkQueue->Enqueue(newEntry))
2110  {
2111  Scheduler(priority);
2112  }
2113  else
2114  {
2115  NS_LOG_INFO("Packet dropped as dsr network queue is full");
2116  }
2117  }
2118  }
2119 
2120  if (m_errorBuffer.GetSize() != 0 && m_errorBuffer.Find(destination))
2121  {
2122  NS_LOG_LOGIC("Schedule sending the next packet in error buffer");
2125  this,
2126  sourceRoute,
2127  nextHop,
2128  protocol);
2129  }
2130  }
2131  }
2132  else
2133  {
2134  NS_LOG_DEBUG("Packet not found in either the send or error buffer");
2135  }
2136 }
2137 
2138 bool
2140  Ipv4Address source,
2141  Ipv4Address destination,
2142  uint8_t segsLeft,
2143  uint16_t fragmentOffset,
2144  uint16_t identification,
2145  bool saveEntry)
2146 {
2147  NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)segsLeft);
2148 
2149  Ptr<Packet> p = packet->Copy();
2150  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2151  DsrPassiveBuffEntry newEntry;
2152  newEntry.SetPacket(p);
2153  newEntry.SetSource(source);
2154  newEntry.SetDestination(destination);
2155  newEntry.SetIdentification(identification);
2156  newEntry.SetFragmentOffset(fragmentOffset);
2157  newEntry.SetSegsLeft(segsLeft); // We try to make sure the segments left is larger for 1
2158 
2159  NS_LOG_DEBUG("The passive buffer size " << m_passiveBuffer->GetSize());
2160 
2161  if (m_passiveBuffer->AllEqual(newEntry) && (!saveEntry))
2162  {
2163  // The PromiscEqual function will remove the maintain buffer entry if equal value found
2164  // It only compares the source and destination address, ackId, and the segments left value
2165  NS_LOG_DEBUG("We get the all equal for passive buffer here");
2166 
2167  DsrMaintainBuffEntry mbEntry;
2168  mbEntry.SetPacket(p);
2169  mbEntry.SetSrc(source);
2170  mbEntry.SetDst(destination);
2171  mbEntry.SetAckId(0);
2172  mbEntry.SetSegsLeft(segsLeft + 1);
2173 
2174  CancelPassivePacketTimer(mbEntry);
2175  return true;
2176  }
2177  if (saveEntry)
2178  {
2180  m_passiveBuffer->Enqueue(newEntry);
2181  }
2182  return false;
2183 }
2184 
2185 bool
2187  Ipv4Address source,
2188  Ipv4Address destination,
2189  uint8_t segsLeft)
2190 {
2191  NS_LOG_FUNCTION(this << packet << source << destination << (uint32_t)segsLeft);
2192 
2193  NS_LOG_DEBUG("Cancel the passive timer");
2194 
2195  Ptr<Packet> p = packet->Copy();
2196  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2197  DsrMaintainBuffEntry newEntry;
2198  newEntry.SetPacket(p);
2199  newEntry.SetSrc(source);
2200  newEntry.SetDst(destination);
2201  newEntry.SetAckId(0);
2202  newEntry.SetSegsLeft(segsLeft + 1);
2203 
2204  if (m_maintainBuffer.PromiscEqual(newEntry))
2205  {
2206  // The PromiscEqual function will remove the maintain buffer entry if equal value found
2207  // It only compares the source and destination address, ackId, and the segments left value
2208  CancelPassivePacketTimer(newEntry);
2209  return true;
2210  }
2211  return false;
2212 }
2213 
2214 void
2216  const Ipv4Header& ipv4Header,
2217  Ipv4Address realSrc,
2218  Ipv4Address realDst)
2219 {
2220  NS_LOG_FUNCTION(this << (uint32_t)ackId << ipv4Header << realSrc << realDst);
2221  Ipv4Address sender = ipv4Header.GetDestination();
2222  Ipv4Address receiver = ipv4Header.GetSource();
2223  /*
2224  * Create a packet to fill maintenance buffer, not used to compare with maintenance entry
2225  * The reason is ack header doesn't have the original packet copy
2226  */
2227  Ptr<Packet> mainP = Create<Packet>();
2228  DsrMaintainBuffEntry newEntry(/*packet=*/mainP,
2229  /*ourAddress=*/sender,
2230  /*nextHop=*/receiver,
2231  /*src=*/realSrc,
2232  /*dst=*/realDst,
2233  /*ackId=*/ackId,
2234  /*segsLeft=*/0,
2235  /*expire=*/Simulator::Now());
2236  CancelNetworkPacketTimer(newEntry); // Only need to cancel network packet timer
2237 }
2238 
2239 void
2241 {
2242  NS_LOG_FUNCTION(this);
2246 }
2247 
2248 void
2250 {
2251  NS_LOG_FUNCTION(this);
2252  LinkKey linkKey;
2253  linkKey.m_ourAdd = mb.GetOurAdd();
2254  linkKey.m_nextHop = mb.GetNextHop();
2255  linkKey.m_source = mb.GetSrc();
2256  linkKey.m_destination = mb.GetDst();
2257  /*
2258  * Here we have found the entry for send retries, so we get the value and increase it by one
2259  */
2261  m_linkCnt[linkKey] = 0;
2262  m_linkCnt.erase(linkKey);
2263 
2264  // TODO if find the linkkey, we need to remove it
2265 
2266  // Find the network acknowledgment timer
2267  std::map<LinkKey, Timer>::const_iterator i = m_linkAckTimer.find(linkKey);
2268  if (i == m_linkAckTimer.end())
2269  {
2270  NS_LOG_INFO("did not find the link timer");
2271  }
2272  else
2273  {
2274  NS_LOG_INFO("did find the link timer");
2275  /*
2276  * Schedule the packet retry
2277  * Push back the nextHop, source, destination address
2278  */
2279  m_linkAckTimer[linkKey].Cancel();
2280  if (m_linkAckTimer[linkKey].IsRunning())
2281  {
2282  NS_LOG_INFO("Timer not canceled");
2283  }
2284  m_linkAckTimer.erase(linkKey);
2285  }
2286 
2287  // Erase the maintenance entry
2288  // yet this does not check the segments left value here
2289  NS_LOG_DEBUG("The link buffer size " << m_maintainBuffer.GetSize());
2290  if (m_maintainBuffer.LinkEqual(mb))
2291  {
2292  NS_LOG_INFO("Link acknowledgment received, remove same maintenance buffer entry");
2293  }
2294 }
2295 
2296 void
2298 {
2299  NS_LOG_FUNCTION(this);
2300  NetworkKey networkKey;
2301  networkKey.m_ackId = mb.GetAckId();
2302  networkKey.m_ourAdd = mb.GetOurAdd();
2303  networkKey.m_nextHop = mb.GetNextHop();
2304  networkKey.m_source = mb.GetSrc();
2305  networkKey.m_destination = mb.GetDst();
2306  /*
2307  * Here we have found the entry for send retries, so we get the value and increase it by one
2308  */
2309  m_addressForwardCnt[networkKey] = 0;
2310  m_addressForwardCnt.erase(networkKey);
2311 
2312  NS_LOG_INFO("ackId " << mb.GetAckId() << " ourAdd " << mb.GetOurAdd() << " nextHop "
2313  << mb.GetNextHop() << " source " << mb.GetSrc() << " destination "
2314  << mb.GetDst() << " segsLeft " << (uint32_t)mb.GetSegsLeft());
2315  // Find the network acknowledgment timer
2316  std::map<NetworkKey, Timer>::const_iterator i = m_addressForwardTimer.find(networkKey);
2317  if (i == m_addressForwardTimer.end())
2318  {
2319  NS_LOG_INFO("did not find the packet timer");
2320  }
2321  else
2322  {
2323  NS_LOG_INFO("did find the packet timer");
2324  /*
2325  * Schedule the packet retry
2326  * Push back the nextHop, source, destination address
2327  */
2328  m_addressForwardTimer[networkKey].Cancel();
2329  if (m_addressForwardTimer[networkKey].IsRunning())
2330  {
2331  NS_LOG_INFO("Timer not canceled");
2332  }
2333  m_addressForwardTimer.erase(networkKey);
2334  }
2335  // Erase the maintenance entry
2336  // yet this does not check the segments left value here
2338  {
2339  NS_LOG_INFO("Remove same maintenance buffer entry based on network acknowledgment");
2340  }
2341 }
2342 
2343 void
2345 {
2346  NS_LOG_FUNCTION(this);
2347  PassiveKey passiveKey;
2348  passiveKey.m_ackId = 0;
2349  passiveKey.m_source = mb.GetSrc();
2350  passiveKey.m_destination = mb.GetDst();
2351  passiveKey.m_segsLeft = mb.GetSegsLeft();
2352 
2353  m_passiveCnt[passiveKey] = 0;
2354  m_passiveCnt.erase(passiveKey);
2355 
2356  // Find the passive acknowledgment timer
2357  std::map<PassiveKey, Timer>::const_iterator j = m_passiveAckTimer.find(passiveKey);
2358  if (j == m_passiveAckTimer.end())
2359  {
2360  NS_LOG_INFO("did not find the passive timer");
2361  }
2362  else
2363  {
2364  NS_LOG_INFO("find the passive timer");
2365  /*
2366  * Cancel passive acknowledgment timer
2367  */
2368  m_passiveAckTimer[passiveKey].Cancel();
2369  if (m_passiveAckTimer[passiveKey].IsRunning())
2370  {
2371  NS_LOG_INFO("Timer not canceled");
2372  }
2373  m_passiveAckTimer.erase(passiveKey);
2374  }
2375 }
2376 
2377 void
2379 {
2380  NS_LOG_FUNCTION(this << nextHop << (uint32_t)protocol);
2381 
2382  DsrMaintainBuffEntry entry;
2383  std::vector<Ipv4Address> previousErrorDst;
2384  if (m_maintainBuffer.Dequeue(nextHop, entry))
2385  {
2386  Ipv4Address source = entry.GetSrc();
2387  Ipv4Address destination = entry.GetDst();
2388 
2389  Ptr<Packet> dsrP = entry.GetPacket()->Copy();
2390  Ptr<Packet> p = dsrP->Copy();
2391  Ptr<Packet> packet = dsrP->Copy();
2392  DsrRoutingHeader dsrRoutingHeader;
2393  dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
2394  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2395  p->RemoveAtStart(offset);
2396 
2397  // Get the number of routers' address field
2398  uint8_t buf[2];
2399  p->CopyData(buf, sizeof(buf));
2400  uint8_t numberAddress = (buf[1] - 2) / 4;
2401  NS_LOG_DEBUG("The number of addresses " << (uint32_t)numberAddress);
2402  DsrOptionSRHeader sourceRoute;
2403  sourceRoute.SetNumberAddress(numberAddress);
2404  p->RemoveHeader(sourceRoute);
2405  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
2406  uint8_t salvage = sourceRoute.GetSalvage();
2407  Ipv4Address address1 = nodeList[1];
2408  PrintVector(nodeList);
2409 
2410  /*
2411  * If the salvage is not 0, use the first address in the route as the error dst in error
2412  * header otherwise use the source of packet as the error destination
2413  */
2414  Ipv4Address errorDst;
2415  if (salvage)
2416  {
2417  errorDst = address1;
2418  }
2419  else
2420  {
2421  errorDst = source;
2422  }
2424  if (std::find(previousErrorDst.begin(), previousErrorDst.end(), destination) ==
2425  previousErrorDst.end())
2426  {
2427  NS_LOG_DEBUG("have not seen this dst before " << errorDst << " in "
2428  << previousErrorDst.size());
2429  SendUnreachError(nextHop, errorDst, destination, salvage, protocol);
2430  previousErrorDst.push_back(errorDst);
2431  }
2432 
2433  /*
2434  * Cancel the packet timer and then salvage the data packet
2435  */
2436 
2437  CancelPacketAllTimer(entry);
2438  SalvagePacket(packet, source, destination, protocol);
2439 
2440  if (m_maintainBuffer.GetSize() && m_maintainBuffer.Find(nextHop))
2441  {
2442  NS_LOG_INFO("Cancel the packet timer for next maintenance entry");
2445  this,
2446  nextHop,
2447  protocol);
2448  }
2449  }
2450  else
2451  {
2452  NS_LOG_INFO("Maintenance buffer entry not found");
2453  }
2455 }
2456 
2457 void
2459  Ipv4Address source,
2460  Ipv4Address dst,
2461  uint8_t protocol)
2462 {
2463  NS_LOG_FUNCTION(this << packet << source << dst << (uint32_t)protocol);
2464  // Create two copies of packet
2465  Ptr<Packet> p = packet->Copy();
2466  Ptr<Packet> newPacket = packet->Copy();
2467  // Remove the routing header in a whole to get a clean packet
2468  DsrRoutingHeader dsrRoutingHeader;
2469  p->RemoveHeader(dsrRoutingHeader);
2470  // Remove offset of dsr routing header
2471  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset();
2472  newPacket->RemoveAtStart(offset);
2473 
2474  // Get the number of routers' address field
2475  uint8_t buf[2];
2476  newPacket->CopyData(buf, sizeof(buf));
2477  uint8_t numberAddress = (buf[1] - 2) / 4;
2478 
2479  DsrOptionSRHeader sourceRoute;
2480  sourceRoute.SetNumberAddress(numberAddress);
2481  newPacket->RemoveHeader(sourceRoute);
2482  uint8_t salvage = sourceRoute.GetSalvage();
2483  /*
2484  * Look in the route cache for other routes for this destination
2485  */
2486  DsrRouteCacheEntry toDst;
2487  bool findRoute = m_routeCache->LookupRoute(dst, toDst);
2488  if (findRoute && (salvage < m_maxSalvageCount))
2489  {
2490  NS_LOG_DEBUG("We have found a route for the packet");
2491  DsrRoutingHeader newDsrRoutingHeader;
2492  newDsrRoutingHeader.SetNextHeader(protocol);
2493  newDsrRoutingHeader.SetMessageType(2);
2494  newDsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2495  newDsrRoutingHeader.SetDestId(GetIDfromIP(dst));
2496 
2497  std::vector<Ipv4Address> nodeList =
2498  toDst.GetVector(); // Get the route from the route entry we found
2499  Ipv4Address nextHop =
2500  SearchNextHop(m_mainAddress, nodeList); // Get the next hop address for the route
2501  if (nextHop == "0.0.0.0")
2502  {
2503  PacketNewRoute(p, source, dst, protocol);
2504  return;
2505  }
2506  // Increase the salvage count by 1
2507  salvage++;
2508  DsrOptionSRHeader sourceRoute;
2509  sourceRoute.SetSalvage(salvage);
2510  sourceRoute.SetNodesAddress(
2511  nodeList); // Save the whole route in the source route header of the packet
2512  sourceRoute.SetSegmentsLeft(
2513  (nodeList.size() - 2)); // The segmentsLeft field will indicate the hops to go
2515  if (m_routeCache->IsLinkCache())
2516  {
2517  m_routeCache->UseExtends(nodeList);
2518  }
2519  uint8_t length = sourceRoute.GetLength();
2520  NS_LOG_INFO("length of source route header " << (uint32_t)(sourceRoute.GetLength()));
2521  newDsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2522  newDsrRoutingHeader.AddDsrOption(sourceRoute);
2523  p->AddHeader(newDsrRoutingHeader);
2524 
2525  SetRoute(nextHop, m_mainAddress);
2526  Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
2527  m_ipv4Route->SetOutputDevice(dev);
2528 
2529  // Send out the data packet
2530  uint32_t priority = GetPriority(DSR_DATA_PACKET);
2531  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
2532  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2533  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue
2534  << " number: " << priority);
2535 
2536  // m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
2537 
2540 
2541  if (dsrNetworkQueue->Enqueue(newEntry))
2542  {
2543  Scheduler(priority);
2544  }
2545  else
2546  {
2547  NS_LOG_INFO("Packet dropped as dsr network queue is full");
2548  }
2549 
2550  /*
2551  * Mark the next hop address in blacklist
2552  */
2553  // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2554  // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2555  }
2556  else
2557  {
2558  NS_LOG_DEBUG("Will not salvage this packet, silently drop");
2559  }
2560 }
2561 
2562 void
2564 {
2565  NS_LOG_FUNCTION(this << (uint32_t)protocol);
2566 
2567  Ptr<Packet> p = mb.GetPacket()->Copy();
2568  Ipv4Address source = mb.GetSrc();
2569  Ipv4Address nextHop = mb.GetNextHop();
2570 
2571  // Send the data packet out before schedule the next packet transmission
2572  SendPacket(p, source, nextHop, protocol);
2573 
2574  LinkKey linkKey;
2575  linkKey.m_source = mb.GetSrc();
2576  linkKey.m_destination = mb.GetDst();
2577  linkKey.m_ourAdd = mb.GetOurAdd();
2578  linkKey.m_nextHop = mb.GetNextHop();
2579 
2580  if (m_linkAckTimer.find(linkKey) == m_linkAckTimer.end())
2581  {
2583  m_linkAckTimer[linkKey] = timer;
2584  }
2585  m_linkAckTimer[linkKey].SetFunction(&DsrRouting::LinkScheduleTimerExpire, this);
2586  m_linkAckTimer[linkKey].Cancel();
2587  m_linkAckTimer[linkKey].SetArguments(mb, protocol);
2588  m_linkAckTimer[linkKey].Schedule(m_linkAckTimeout);
2589 }
2590 
2591 void
2593 {
2594  NS_LOG_FUNCTION(this << (uint32_t)protocol);
2595 
2596  Ptr<Packet> p = mb.GetPacket()->Copy();
2597  Ipv4Address source = mb.GetSrc();
2598  Ipv4Address nextHop = mb.GetNextHop();
2599 
2600  // Send the data packet out before schedule the next packet transmission
2601  SendPacket(p, source, nextHop, protocol);
2602 
2603  PassiveKey passiveKey;
2604  passiveKey.m_ackId = 0;
2605  passiveKey.m_source = mb.GetSrc();
2606  passiveKey.m_destination = mb.GetDst();
2607  passiveKey.m_segsLeft = mb.GetSegsLeft();
2608 
2609  if (m_passiveAckTimer.find(passiveKey) == m_passiveAckTimer.end())
2610  {
2612  m_passiveAckTimer[passiveKey] = timer;
2613  }
2614  NS_LOG_DEBUG("The passive acknowledgment option for data packet");
2615  m_passiveAckTimer[passiveKey].SetFunction(&DsrRouting::PassiveScheduleTimerExpire, this);
2616  m_passiveAckTimer[passiveKey].Cancel();
2617  m_passiveAckTimer[passiveKey].SetArguments(mb, protocol);
2618  m_passiveAckTimer[passiveKey].Schedule(m_passiveAckTimeout);
2619 }
2620 
2621 void
2623 {
2624  Ptr<Packet> p = Create<Packet>();
2625  Ptr<Packet> dsrP = Create<Packet>();
2626  // The new entry will be used for retransmission
2627  NetworkKey networkKey;
2628  Ipv4Address nextHop = mb.GetNextHop();
2629  NS_LOG_DEBUG("is the first retry or not " << isFirst);
2630  if (isFirst)
2631  {
2632  // This is the very first network packet retry
2633  p = mb.GetPacket()->Copy();
2634  // Here we add the ack request header to the data packet for network acknowledgement
2635  uint16_t ackId = AddAckReqHeader(p, nextHop);
2636 
2637  Ipv4Address source = mb.GetSrc();
2638  Ipv4Address nextHop = mb.GetNextHop();
2639  // Send the data packet out before schedule the next packet transmission
2640  SendPacket(p, source, nextHop, protocol);
2641 
2642  dsrP = p->Copy();
2643  DsrMaintainBuffEntry newEntry = mb;
2644  // The function AllEqual will find the exact entry and delete it if found
2646  newEntry.SetPacket(dsrP);
2647  newEntry.SetAckId(ackId);
2648  newEntry.SetExpireTime(m_maxMaintainTime);
2649 
2650  networkKey.m_ackId = newEntry.GetAckId();
2651  networkKey.m_ourAdd = newEntry.GetOurAdd();
2652  networkKey.m_nextHop = newEntry.GetNextHop();
2653  networkKey.m_source = newEntry.GetSrc();
2654  networkKey.m_destination = newEntry.GetDst();
2655 
2656  m_addressForwardCnt[networkKey] = 0;
2657  if (!m_maintainBuffer.Enqueue(newEntry))
2658  {
2659  NS_LOG_ERROR("Failed to enqueue packet retry");
2660  }
2661 
2662  if (m_addressForwardTimer.find(networkKey) == m_addressForwardTimer.end())
2663  {
2665  m_addressForwardTimer[networkKey] = timer;
2666  }
2667 
2668  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2669  // option
2671  this);
2672  m_addressForwardTimer[networkKey].Cancel();
2673  m_addressForwardTimer[networkKey].SetArguments(newEntry, protocol);
2674  NS_LOG_DEBUG("The packet retries time for " << newEntry.GetAckId() << " is "
2675  << m_sendRetries << " and the delay time is "
2676  << Time(2 * m_nodeTraversalTime).As(Time::S));
2677  // Back-off mechanism
2678  m_addressForwardTimer[networkKey].Schedule(Time(2 * m_nodeTraversalTime));
2679  }
2680  else
2681  {
2682  networkKey.m_ackId = mb.GetAckId();
2683  networkKey.m_ourAdd = mb.GetOurAdd();
2684  networkKey.m_nextHop = mb.GetNextHop();
2685  networkKey.m_source = mb.GetSrc();
2686  networkKey.m_destination = mb.GetDst();
2687  /*
2688  * Here we have found the entry for send retries, so we get the value and increase it by one
2689  */
2690  m_sendRetries = m_addressForwardCnt[networkKey];
2691  NS_LOG_DEBUG("The packet retry we have done " << m_sendRetries);
2692 
2693  p = mb.GetPacket()->Copy();
2694  dsrP = mb.GetPacket()->Copy();
2695 
2696  Ipv4Address source = mb.GetSrc();
2697  Ipv4Address nextHop = mb.GetNextHop();
2698  // Send the data packet out before schedule the next packet transmission
2699  SendPacket(p, source, nextHop, protocol);
2700 
2701  NS_LOG_DEBUG("The packet with dsr header " << dsrP->GetSize());
2702  networkKey.m_ackId = mb.GetAckId();
2703  networkKey.m_ourAdd = mb.GetOurAdd();
2704  networkKey.m_nextHop = mb.GetNextHop();
2705  networkKey.m_source = mb.GetSrc();
2706  networkKey.m_destination = mb.GetDst();
2707  /*
2708  * If a data packet has been attempted SendRetries times at the maximum TTL without
2709  * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2710  * dropped from the send buffer
2711  *
2712  * The maxMaintRexmt also needs to decrease one for the passive ack packet
2713  */
2714  /*
2715  * Check if the send retry time for a certain packet has already passed max maintenance
2716  * retransmission time or not
2717  */
2718 
2719  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment
2720  // option
2722  this);
2723  m_addressForwardTimer[networkKey].Cancel();
2724  m_addressForwardTimer[networkKey].SetArguments(mb, protocol);
2725  NS_LOG_DEBUG("The packet retries time for "
2726  << mb.GetAckId() << " is " << m_sendRetries << " and the delay time is "
2728  // Back-off mechanism
2729  m_addressForwardTimer[networkKey].Schedule(Time(2 * m_sendRetries * m_nodeTraversalTime));
2730  }
2731 }
2732 
2733 void
2735 {
2736  NS_LOG_FUNCTION(this << (uint32_t)protocol);
2737  Ipv4Address nextHop = mb.GetNextHop();
2738  Ptr<const Packet> packet = mb.GetPacket();
2739  SetRoute(nextHop, m_mainAddress);
2740  Ptr<Packet> p = packet->Copy();
2741 
2742  LinkKey lk;
2743  lk.m_source = mb.GetSrc();
2744  lk.m_destination = mb.GetDst();
2745  lk.m_ourAdd = mb.GetOurAdd();
2746  lk.m_nextHop = mb.GetNextHop();
2747 
2748  // Cancel passive ack timer
2749  m_linkAckTimer[lk].Cancel();
2750  if (m_linkAckTimer[lk].IsRunning())
2751  {
2752  NS_LOG_DEBUG("Timer not canceled");
2753  }
2754  m_linkAckTimer.erase(lk);
2755 
2756  // Increase the send retry times
2757  m_linkRetries = m_linkCnt[lk];
2759  {
2760  m_linkCnt[lk] = ++m_linkRetries;
2761  ScheduleLinkPacketRetry(mb, protocol);
2762  }
2763  else
2764  {
2765  NS_LOG_INFO("We need to send error messages now");
2766 
2767  // Delete all the routes including the links
2768  m_routeCache->DeleteAllRoutesIncludeLink(m_mainAddress, nextHop, m_mainAddress);
2769  /*
2770  * here we cancel the packet retransmission time for all the packets have next hop address
2771  * as nextHop Also salvage the packet for the all the packet destined for the nextHop
2772  * address this is also responsible for send unreachable error back to source
2773  */
2774  CancelPacketTimerNextHop(nextHop, protocol);
2775  }
2776 }
2777 
2778 void
2780 {
2781  NS_LOG_FUNCTION(this << (uint32_t)protocol);
2782  Ipv4Address nextHop = mb.GetNextHop();
2783  Ptr<const Packet> packet = mb.GetPacket();
2784  SetRoute(nextHop, m_mainAddress);
2785  Ptr<Packet> p = packet->Copy();
2786 
2787  PassiveKey pk;
2788  pk.m_ackId = 0;
2789  pk.m_source = mb.GetSrc();
2790  pk.m_destination = mb.GetDst();
2791  pk.m_segsLeft = mb.GetSegsLeft();
2792 
2793  // Cancel passive ack timer
2794  m_passiveAckTimer[pk].Cancel();
2795  if (m_passiveAckTimer[pk].IsRunning())
2796  {
2797  NS_LOG_DEBUG("Timer not canceled");
2798  }
2799  m_passiveAckTimer.erase(pk);
2800 
2801  // Increase the send retry times
2804  {
2806  SchedulePassivePacketRetry(mb, protocol);
2807  }
2808  else
2809  {
2810  // This is the first network acknowledgement retry
2811  // Cancel the passive packet timer now and remove maintenance buffer entry for it
2813  ScheduleNetworkPacketRetry(mb, true, protocol);
2814  }
2815 }
2816 
2817 int64_t
2819 {
2820  NS_LOG_FUNCTION(this << stream);
2822  return 1;
2823 }
2824 
2825 void
2827 {
2828  Ptr<Packet> p = mb.GetPacket()->Copy();
2829  Ipv4Address source = mb.GetSrc();
2830  Ipv4Address nextHop = mb.GetNextHop();
2831  Ipv4Address dst = mb.GetDst();
2832 
2833  NetworkKey networkKey;
2834  networkKey.m_ackId = mb.GetAckId();
2835  networkKey.m_ourAdd = mb.GetOurAdd();
2836  networkKey.m_nextHop = nextHop;
2837  networkKey.m_source = source;
2838  networkKey.m_destination = dst;
2839 
2840  // Increase the send retry times
2841  m_sendRetries = m_addressForwardCnt[networkKey];
2842 
2844  {
2845  // Delete all the routes including the links
2846  m_routeCache->DeleteAllRoutesIncludeLink(m_mainAddress, nextHop, m_mainAddress);
2847  /*
2848  * here we cancel the packet retransmission time for all the packets have next hop address
2849  * as nextHop Also salvage the packet for the all the packet destined for the nextHop
2850  * address
2851  */
2852  CancelPacketTimerNextHop(nextHop, protocol);
2853  }
2854  else
2855  {
2856  m_addressForwardCnt[networkKey] = ++m_sendRetries;
2857  ScheduleNetworkPacketRetry(mb, false, protocol);
2858  }
2859 }
2860 
2861 void
2863  DsrOptionSRHeader& sourceRoute,
2864  const Ipv4Header& ipv4Header,
2865  Ipv4Address source,
2866  Ipv4Address nextHop,
2867  Ipv4Address targetAddress,
2868  uint8_t protocol,
2869  Ptr<Ipv4Route> route)
2870 {
2871  NS_LOG_FUNCTION(this << packet << sourceRoute << source << nextHop << targetAddress
2872  << (uint32_t)protocol << route);
2873  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2874 
2875  DsrRoutingHeader dsrRoutingHeader;
2876  dsrRoutingHeader.SetNextHeader(protocol);
2877  dsrRoutingHeader.SetMessageType(2);
2878  dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2879  dsrRoutingHeader.SetDestId(GetIDfromIP(targetAddress));
2880 
2881  // We get the salvage value in sourceRoute header and set it to route error header if triggered
2882  // error
2883  Ptr<Packet> p = packet->Copy();
2884  uint8_t length = sourceRoute.GetLength();
2885  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2886  dsrRoutingHeader.AddDsrOption(sourceRoute);
2887  p->AddHeader(dsrRoutingHeader);
2888 
2889  Ptr<const Packet> mtP = p->Copy();
2890 
2891  DsrMaintainBuffEntry newEntry(/*packet=*/mtP,
2892  /*ourAddress=*/m_mainAddress,
2893  /*nextHop=*/nextHop,
2894  /*src=*/source,
2895  /*dst=*/targetAddress,
2896  /*ackId=*/m_ackId,
2897  /*segsLeft=*/sourceRoute.GetSegmentsLeft(),
2898  /*expire=*/m_maxMaintainTime);
2899  bool result = m_maintainBuffer.Enqueue(newEntry);
2900 
2901  if (result)
2902  {
2903  NetworkKey networkKey;
2904  networkKey.m_ackId = newEntry.GetAckId();
2905  networkKey.m_ourAdd = newEntry.GetOurAdd();
2906  networkKey.m_nextHop = newEntry.GetNextHop();
2907  networkKey.m_source = newEntry.GetSrc();
2908  networkKey.m_destination = newEntry.GetDst();
2909 
2910  PassiveKey passiveKey;
2911  passiveKey.m_ackId = 0;
2912  passiveKey.m_source = newEntry.GetSrc();
2913  passiveKey.m_destination = newEntry.GetDst();
2914  passiveKey.m_segsLeft = newEntry.GetSegsLeft();
2915 
2916  LinkKey linkKey;
2917  linkKey.m_source = newEntry.GetSrc();
2918  linkKey.m_destination = newEntry.GetDst();
2919  linkKey.m_ourAdd = newEntry.GetOurAdd();
2920  linkKey.m_nextHop = newEntry.GetNextHop();
2921 
2922  m_addressForwardCnt[networkKey] = 0;
2923  m_passiveCnt[passiveKey] = 0;
2924  m_linkCnt[linkKey] = 0;
2925 
2926  if (m_linkAck)
2927  {
2928  ScheduleLinkPacketRetry(newEntry, protocol);
2929  }
2930  else
2931  {
2932  NS_LOG_LOGIC("Not using link acknowledgment");
2933  if (nextHop != targetAddress)
2934  {
2935  SchedulePassivePacketRetry(newEntry, protocol);
2936  }
2937  else
2938  {
2939  // This is the first network retry
2940  ScheduleNetworkPacketRetry(newEntry, true, protocol);
2941  }
2942  }
2943  }
2944 }
2945 
2946 void
2947 DsrRouting::SendInitialRequest(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
2948 {
2949  NS_LOG_FUNCTION(this << source << destination << (uint32_t)protocol);
2950  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2951  Ptr<Packet> packet = Create<Packet>();
2952  // Create an empty Ipv4 route ptr
2953  Ptr<Ipv4Route> route;
2954  /*
2955  * Construct the route request option header
2956  */
2957  DsrRoutingHeader dsrRoutingHeader;
2958  dsrRoutingHeader.SetNextHeader(protocol);
2959  dsrRoutingHeader.SetMessageType(1);
2960  dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
2961  dsrRoutingHeader.SetDestId(255);
2962 
2963  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2964  rreqHeader.AddNodeAddress(m_mainAddress); // Add our own address in the header
2965  rreqHeader.SetTarget(destination);
2966  m_requestId =
2967  m_rreqTable->CheckUniqueRreqId(destination); // Check the Id cache for duplicate ones
2968  rreqHeader.SetId(m_requestId);
2969 
2970  dsrRoutingHeader.AddDsrOption(rreqHeader); // Add the rreqHeader to the dsr extension header
2971  uint8_t length = rreqHeader.GetLength();
2972  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
2973  packet->AddHeader(dsrRoutingHeader);
2974 
2975  // Schedule the route requests retry with non-propagation set true
2976  bool nonProp = true;
2977  std::vector<Ipv4Address> address;
2978  address.push_back(source);
2979  address.push_back(destination);
2980  /*
2981  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2982  */
2983  SocketIpTtlTag tag;
2984  tag.SetTtl(0);
2985  Ptr<Packet> nonPropPacket = packet->Copy();
2986  nonPropPacket->AddPacketTag(tag);
2987  // Increase the request count
2988  m_rreqTable->FindAndUpdate(destination);
2989  SendRequest(nonPropPacket, source);
2990  // Schedule the next route request
2991  ScheduleRreqRetry(packet, address, nonProp, m_requestId, protocol);
2992 }
2993 
2994 void
2996 {
2997  NS_LOG_FUNCTION(this << (uint32_t)protocol);
2998  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
2999  uint8_t salvage = rerr.GetSalvage();
3000  Ipv4Address dst = rerr.GetOriginalDst();
3001  NS_LOG_DEBUG("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc()
3002  << " error destination " << rerr.GetErrorDst()
3003  << " error next hop " << rerr.GetUnreachNode()
3004  << " original dst " << rerr.GetOriginalDst());
3005  DsrRouteCacheEntry toDst;
3006  if (m_routeCache->LookupRoute(dst, toDst))
3007  {
3008  /*
3009  * Found a route the dst, construct the source route option header
3010  */
3011  DsrOptionSRHeader sourceRoute;
3012  std::vector<Ipv4Address> ip = toDst.GetVector();
3013  sourceRoute.SetNodesAddress(ip);
3015  if (m_routeCache->IsLinkCache())
3016  {
3017  m_routeCache->UseExtends(ip);
3018  }
3019  sourceRoute.SetSegmentsLeft((ip.size() - 2));
3020  sourceRoute.SetSalvage(salvage);
3021  Ipv4Address nextHop = SearchNextHop(m_mainAddress, ip); // Get the next hop address
3022  NS_LOG_DEBUG("The nextHop address " << nextHop);
3023  Ptr<Packet> packet = Create<Packet>();
3024  if (nextHop == "0.0.0.0")
3025  {
3026  NS_LOG_DEBUG("Error next hop address");
3027  PacketNewRoute(packet, m_mainAddress, dst, protocol);
3028  return;
3029  }
3030  SetRoute(nextHop, m_mainAddress);
3031  CancelRreqTimer(dst, true);
3033  if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(dst))
3034  {
3035  SendPacketFromBuffer(sourceRoute, nextHop, protocol);
3036  }
3037  NS_LOG_LOGIC("Route to " << dst << " found");
3038  return;
3039  }
3040  else
3041  {
3042  NS_LOG_INFO("No route found, initiate route error request");
3043  Ptr<Packet> packet = Create<Packet>();
3044  Ipv4Address originalDst = rerr.GetOriginalDst();
3045  // Create an empty route ptr
3046  Ptr<Ipv4Route> route = nullptr;
3047  /*
3048  * Construct the route request option header
3049  */
3050  DsrRoutingHeader dsrRoutingHeader;
3051  dsrRoutingHeader.SetNextHeader(protocol);
3052  dsrRoutingHeader.SetMessageType(1);
3053  dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
3054  dsrRoutingHeader.SetDestId(255);
3055 
3056  Ptr<Packet> dstP = Create<Packet>();
3057  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
3058  rreqHeader.AddNodeAddress(m_mainAddress); // Add our own address in the header
3059  rreqHeader.SetTarget(originalDst);
3060  m_requestId =
3061  m_rreqTable->CheckUniqueRreqId(originalDst); // Check the Id cache for duplicate ones
3062  rreqHeader.SetId(m_requestId);
3063 
3064  dsrRoutingHeader.AddDsrOption(rreqHeader); // Add the rreqHeader to the dsr extension header
3065  dsrRoutingHeader.AddDsrOption(rerr);
3066  uint8_t length = rreqHeader.GetLength() + rerr.GetLength();
3067  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 4);
3068  dstP->AddHeader(dsrRoutingHeader);
3069  // Schedule the route requests retry, propagate the route request message as it contains
3070  // error
3071  bool nonProp = false;
3072  std::vector<Ipv4Address> address;
3073  address.push_back(m_mainAddress);
3074  address.push_back(originalDst);
3075  /*
3076  * Add the socket ip ttl tag to the packet to limit the scope of route requests
3077  */
3078  SocketIpTtlTag tag;
3079  tag.SetTtl((uint8_t)m_discoveryHopLimit);
3080  Ptr<Packet> propPacket = dstP->Copy();
3081  propPacket->AddPacketTag(tag);
3082 
3083  if ((m_addressReqTimer.find(originalDst) == m_addressReqTimer.end()) &&
3084  (m_nonPropReqTimer.find(originalDst) == m_nonPropReqTimer.end()))
3085  {
3086  NS_LOG_INFO("Only when there is no existing route request time when the initial route "
3087  "request is scheduled");
3088  SendRequest(propPacket, m_mainAddress);
3089  ScheduleRreqRetry(dstP, address, nonProp, m_requestId, protocol);
3090  }
3091  else
3092  {
3093  NS_LOG_INFO("There is existing route request, find the existing route request entry");
3094  /*
3095  * Cancel the route request timer first before scheduling the route request
3096  * in this case, we do not want to remove the route request entry, so the isRemove value
3097  * is false
3098  */
3099  CancelRreqTimer(originalDst, false);
3100  ScheduleRreqRetry(dstP, address, nonProp, m_requestId, protocol);
3101  }
3102  }
3103 }
3104 
3105 void
3107 {
3108  NS_LOG_FUNCTION(this << dst << isRemove);
3109  // Cancel the non propagation request timer if found
3110  if (m_nonPropReqTimer.find(dst) == m_nonPropReqTimer.end())
3111  {
3112  NS_LOG_DEBUG("Did not find the non-propagation timer");
3113  }
3114  else
3115  {
3116  NS_LOG_DEBUG("did find the non-propagation timer");
3117  }
3118  m_nonPropReqTimer[dst].Cancel();
3119 
3120  if (m_nonPropReqTimer[dst].IsRunning())
3121  {
3122  NS_LOG_DEBUG("Timer not canceled");
3123  }
3124  m_nonPropReqTimer.erase(dst);
3125 
3126  // Cancel the address request timer if found
3127  if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
3128  {
3129  NS_LOG_DEBUG("Did not find the propagation timer");
3130  }
3131  else
3132  {
3133  NS_LOG_DEBUG("did find the propagation timer");
3134  }
3135  m_addressReqTimer[dst].Cancel();
3136  if (m_addressReqTimer[dst].IsRunning())
3137  {
3138  NS_LOG_DEBUG("Timer not canceled");
3139  }
3140  m_addressReqTimer.erase(dst);
3141  /*
3142  * If the route request is scheduled to remove the route request entry
3143  * Remove the route request entry with the route retry times done for certain destination
3144  */
3145  if (isRemove)
3146  {
3147  // remove the route request entry from route request table
3148  m_rreqTable->RemoveRreqEntry(dst);
3149  }
3150 }
3151 
3152 void
3154  std::vector<Ipv4Address> address,
3155  bool nonProp,
3156  uint32_t requestId,
3157  uint8_t protocol)
3158 {
3159  NS_LOG_FUNCTION(this << packet << nonProp << requestId << (uint32_t)protocol);
3160  Ipv4Address source = address[0];
3161  Ipv4Address dst = address[1];
3162  if (nonProp)
3163  {
3164  // The nonProp route request is only sent out only and is already used
3165  if (m_nonPropReqTimer.find(dst) == m_nonPropReqTimer.end())
3166  {
3168  m_nonPropReqTimer[dst] = timer;
3169  }
3170  std::vector<Ipv4Address> address;
3171  address.push_back(source);
3172  address.push_back(dst);
3173  m_nonPropReqTimer[dst].SetFunction(&DsrRouting::RouteRequestTimerExpire, this);
3174  m_nonPropReqTimer[dst].Cancel();
3175  m_nonPropReqTimer[dst].SetArguments(packet, address, requestId, protocol);
3177  }
3178  else
3179  {
3180  // Cancel the non propagation request timer if found
3181  m_nonPropReqTimer[dst].Cancel();
3182  if (m_nonPropReqTimer[dst].IsRunning())
3183  {
3184  NS_LOG_DEBUG("Timer not canceled");
3185  }
3186  m_nonPropReqTimer.erase(dst);
3187 
3188  if (m_addressReqTimer.find(dst) == m_addressReqTimer.end())
3189  {
3191  m_addressReqTimer[dst] = timer;
3192  }
3193  std::vector<Ipv4Address> address;
3194  address.push_back(source);
3195  address.push_back(dst);
3196  m_addressReqTimer[dst].SetFunction(&DsrRouting::RouteRequestTimerExpire, this);
3197  m_addressReqTimer[dst].Cancel();
3198  m_addressReqTimer[dst].SetArguments(packet, address, requestId, protocol);
3199  Time rreqDelay;
3200  // back off mechanism for sending route requests
3201  if (m_rreqTable->GetRreqCnt(dst))
3202  {
3203  // When the route request count is larger than 0
3204  // This is the exponential back-off mechanism for route request
3205  rreqDelay = Time(std::pow(static_cast<double>(m_rreqTable->GetRreqCnt(dst)), 2.0) *
3206  m_requestPeriod);
3207  }
3208  else
3209  {
3210  // This is the first route request retry
3211  rreqDelay = m_requestPeriod;
3212  }
3213  NS_LOG_LOGIC("Request count for " << dst << " " << m_rreqTable->GetRreqCnt(dst)
3214  << " with delay time " << rreqDelay.As(Time::S));
3215  if (rreqDelay > m_maxRequestPeriod)
3216  {
3217  // use the max request period
3218  NS_LOG_LOGIC("The max request delay time " << m_maxRequestPeriod.As(Time::S));
3219  m_addressReqTimer[dst].Schedule(m_maxRequestPeriod);
3220  }
3221  else
3222  {
3223  NS_LOG_LOGIC("The request delay time " << rreqDelay.As(Time::S));
3224  m_addressReqTimer[dst].Schedule(rreqDelay);
3225  }
3226  }
3227 }
3228 
3229 void
3231  std::vector<Ipv4Address> address,
3232  uint32_t requestId,
3233  uint8_t protocol)
3234 {
3235  NS_LOG_FUNCTION(this << packet << requestId << (uint32_t)protocol);
3236  // Get a clean packet without dsr header
3237  Ptr<Packet> dsrP = packet->Copy();
3238  DsrRoutingHeader dsrRoutingHeader;
3239  dsrP->RemoveHeader(dsrRoutingHeader); // Remove the dsr header in whole
3240 
3241  Ipv4Address source = address[0];
3242  Ipv4Address dst = address[1];
3243  DsrRouteCacheEntry toDst;
3244  if (m_routeCache->LookupRoute(dst, toDst))
3245  {
3246  /*
3247  * Found a route the dst, construct the source route option header
3248  */
3249  DsrOptionSRHeader sourceRoute;
3250  std::vector<Ipv4Address> ip = toDst.GetVector();
3251  sourceRoute.SetNodesAddress(ip);
3252  // When we found the route and use it, UseExtends for the link cache
3253  if (m_routeCache->IsLinkCache())
3254  {
3255  m_routeCache->UseExtends(ip);
3256  }
3257  sourceRoute.SetSegmentsLeft((ip.size() - 2));
3259  sourceRoute.SetSalvage(0);
3260  Ipv4Address nextHop = SearchNextHop(m_mainAddress, ip); // Get the next hop address
3261  NS_LOG_INFO("The nextHop address is " << nextHop);
3262  if (nextHop == "0.0.0.0")
3263  {
3264  NS_LOG_DEBUG("Error next hop address");
3265  PacketNewRoute(dsrP, source, dst, protocol);
3266  return;
3267  }
3268  SetRoute(nextHop, m_mainAddress);
3269  CancelRreqTimer(dst, true);
3271  if (m_sendBuffer.GetSize() != 0 && m_sendBuffer.Find(dst))
3272  {
3273  SendPacketFromBuffer(sourceRoute, nextHop, protocol);
3274  }
3275  NS_LOG_LOGIC("Route to " << dst << " found");
3276  return;
3277  }
3278  /*
3279  * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
3280  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
3281  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the
3282  * application.
3283  */
3284  NS_LOG_LOGIC("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt(dst)
3285  << " the max " << m_rreqRetries);
3286  if (m_rreqTable->GetRreqCnt(dst) >= m_rreqRetries)
3287  {
3288  NS_LOG_LOGIC("Route discovery to " << dst << " has been attempted " << m_rreqRetries
3289  << " times");
3290  CancelRreqTimer(dst, true);
3291  NS_LOG_DEBUG("Route not found. Drop packet with dst " << dst);
3293  }
3294  else
3295  {
3296  SocketIpTtlTag tag;
3297  tag.SetTtl((uint8_t)m_discoveryHopLimit);
3298  Ptr<Packet> propPacket = packet->Copy();
3299  propPacket->AddPacketTag(tag);
3300  // Increase the request count
3301  m_rreqTable->FindAndUpdate(dst);
3302  SendRequest(propPacket, source);
3303  NS_LOG_DEBUG("Check the route request entry " << source << " " << dst);
3304  ScheduleRreqRetry(packet, address, false, requestId, protocol);
3305  }
3306 }
3307 
3308 void
3310 {
3311  NS_LOG_FUNCTION(this << packet << source);
3312 
3313  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3314  /*
3315  * The destination address here is directed broadcast address
3316  */
3317  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
3318  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
3319  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3320  NS_LOG_LOGIC("Inserting into priority queue number: " << priority);
3321 
3322  // m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
3323 
3325  DsrNetworkQueueEntry newEntry(packet, source, m_broadcast, Simulator::Now(), nullptr);
3326  if (dsrNetworkQueue->Enqueue(newEntry))
3327  {
3328  Scheduler(priority);
3329  }
3330  else
3331  {
3332  NS_LOG_INFO("Packet dropped as dsr network queue is full");
3333  }
3334 }
3335 
3336 void
3338 {
3339  NS_LOG_FUNCTION(this << packet);
3340  /*
3341  * This is a forwarding case when sending route requests, a random delay time [0,
3342  * m_broadcastJitter] used before forwarding as link-layer broadcast
3343  */
3346  this,
3347  packet,
3348  m_mainAddress);
3349 }
3350 
3351 void
3353  Ipv4Address srcAddress,
3354  std::vector<Ipv4Address>& nodeList,
3355  uint8_t protocol)
3356 {
3357  NS_LOG_FUNCTION(this << source << srcAddress << (uint32_t)protocol);
3358  if (!(m_graReply.FindAndUpdate(source,
3359  srcAddress,
3360  m_gratReplyHoldoff))) // Find the gratuitous reply entry
3361  {
3362  NS_LOG_LOGIC("Update gratuitous reply " << source);
3363  GraReplyEntry graReplyEntry(source, srcAddress, m_gratReplyHoldoff + Simulator::Now());
3364  m_graReply.AddEntry(graReplyEntry);
3365  /*
3366  * Automatic route shortening
3367  */
3368  m_finalRoute.clear(); // Clear the final route vector
3372  std::vector<Ipv4Address>::iterator before =
3373  find(nodeList.begin(), nodeList.end(), srcAddress);
3374  for (std::vector<Ipv4Address>::iterator i = nodeList.begin(); i != before; ++i)
3375  {
3376  m_finalRoute.push_back(*i);
3377  }
3378  m_finalRoute.push_back(srcAddress);
3379  std::vector<Ipv4Address>::iterator after =
3380  find(nodeList.begin(), nodeList.end(), m_mainAddress);
3381  for (std::vector<Ipv4Address>::iterator j = after; j != nodeList.end(); ++j)
3382  {
3383  m_finalRoute.push_back(*j);
3384  }
3385  DsrOptionRrepHeader rrep;
3386  rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
3387  // Get the real reply source and destination
3388  Ipv4Address replySrc = m_finalRoute.back();
3389  Ipv4Address replyDst = m_finalRoute.front();
3390  /*
3391  * Set the route and use it in send back route reply
3392  */
3393  m_ipv4Route = SetRoute(srcAddress, m_mainAddress);
3394  /*
3395  * This part adds DSR header to the packet and send reply
3396  */
3397  DsrRoutingHeader dsrRoutingHeader;
3398  dsrRoutingHeader.SetNextHeader(protocol);
3399  dsrRoutingHeader.SetMessageType(1);
3400  dsrRoutingHeader.SetSourceId(GetIDfromIP(replySrc));
3401  dsrRoutingHeader.SetDestId(GetIDfromIP(replyDst));
3402 
3403  uint8_t length =
3404  rrep.GetLength(); // Get the length of the rrep header excluding the type header
3405  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
3406  dsrRoutingHeader.AddDsrOption(rrep);
3407  Ptr<Packet> newPacket = Create<Packet>();
3408  newPacket->AddHeader(dsrRoutingHeader);
3409  /*
3410  * Send gratuitous reply
3411  */
3412  NS_LOG_INFO("Send back gratuitous route reply");
3413  SendReply(newPacket, m_mainAddress, srcAddress, m_ipv4Route);
3414  }
3415  else
3416  {
3417  NS_LOG_INFO("The same gratuitous route reply has already sent");
3418  }
3419 }
3420 
3421 void
3423  Ipv4Address source,
3424  Ipv4Address nextHop,
3425  Ptr<Ipv4Route> route)
3426 {
3427  NS_LOG_FUNCTION(this << packet << source << nextHop);
3428  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3429 
3430  Ptr<NetDevice> dev = m_ipv4->GetNetDevice(m_ipv4->GetInterfaceForAddress(m_mainAddress));
3431  route->SetOutputDevice(dev);
3432  NS_LOG_INFO("The output device " << dev << " packet is: " << *packet);
3433 
3434  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
3435  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
3436  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3437  NS_LOG_INFO("Inserting into priority queue number: " << priority);
3438 
3439  // m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3440 
3442  DsrNetworkQueueEntry newEntry(packet, source, nextHop, Simulator::Now(), route);
3443  if (dsrNetworkQueue->Enqueue(newEntry))
3444  {
3445  Scheduler(priority);
3446  }
3447  else
3448  {
3449  NS_LOG_INFO("Packet dropped as dsr network queue is full");
3450  }
3451 }
3452 
3453 void
3455  Ipv4Address source,
3456  Ipv4Address nextHop,
3457  Ptr<Ipv4Route> route)
3458 {
3459  NS_LOG_FUNCTION(this << packet << source << nextHop);
3460  Simulator::ScheduleNow(&DsrRouting::SendReply, this, packet, source, nextHop, route);
3461 }
3462 
3463 void
3465  Ipv4Address source,
3466  Ipv4Address destination,
3467  Ptr<Ipv4Route> route,
3468  double hops)
3469 {
3470  NS_LOG_FUNCTION(this << packet << source << destination);
3472  Time(2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue(0, 1))),
3474  this,
3475  packet,
3476  source,
3477  destination,
3478  route);
3479 }
3480 
3481 void
3482 DsrRouting::SendAck(uint16_t ackId,
3483  Ipv4Address destination,
3484  Ipv4Address realSrc,
3485  Ipv4Address realDst,
3486  uint8_t protocol,
3487  Ptr<Ipv4Route> route)
3488 {
3489  NS_LOG_FUNCTION(this << ackId << destination << realSrc << realDst << (uint32_t)protocol
3490  << route);
3491  NS_ASSERT_MSG(!m_downTarget.IsNull(), "Error, DsrRouting cannot send downward");
3492 
3493  // This is a route reply option header
3494  DsrRoutingHeader dsrRoutingHeader;
3495  dsrRoutingHeader.SetNextHeader(protocol);
3496  dsrRoutingHeader.SetMessageType(1);
3497  dsrRoutingHeader.SetSourceId(GetIDfromIP(m_mainAddress));
3498  dsrRoutingHeader.SetDestId(GetIDfromIP(destination));
3499 
3500  DsrOptionAckHeader ack;
3501  /*
3502  * Set the ack Id and set the ack source address and destination address
3503  */
3504  ack.SetAckId(ackId);
3505  ack.SetRealSrc(realSrc);
3506  ack.SetRealDst(realDst);
3507 
3508  uint8_t length = ack.GetLength();
3509  dsrRoutingHeader.SetPayloadLength(uint16_t(length) + 2);
3510  dsrRoutingHeader.AddDsrOption(ack);
3511 
3512  Ptr<Packet> packet = Create<Packet>();
3513  packet->AddHeader(dsrRoutingHeader);
3514  Ptr<NetDevice> dev = m_ip->GetNetDevice(m_ip->GetInterfaceForAddress(m_mainAddress));
3515  route->SetOutputDevice(dev);
3516 
3517  uint32_t priority = GetPriority(DSR_CONTROL_PACKET);
3518  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue>>::iterator i = m_priorityQueue.find(priority);
3519  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3520 
3521  NS_LOG_LOGIC("Will be inserting into priority queue " << dsrNetworkQueue
3522  << " number: " << priority);
3523 
3524  // m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
3525 
3527  DsrNetworkQueueEntry newEntry(packet, m_mainAddress, destination, Simulator::Now(), route);
3528  if (dsrNetworkQueue->Enqueue(newEntry))
3529  {
3530  Scheduler(priority);
3531  }
3532  else
3533  {
3534  NS_LOG_INFO("Packet dropped as dsr network queue is full");
3535  }
3536 }
3537 
3539 DsrRouting::Receive(Ptr<Packet> p, const Ipv4Header& ip, Ptr<Ipv4Interface> incomingInterface)
3540 {
3541  NS_LOG_FUNCTION(this << p << ip << incomingInterface);
3542 
3543  NS_LOG_INFO("Our own IP address " << m_mainAddress << " The incoming interface address "
3544  << incomingInterface);
3545  m_node = GetNode(); // Get the node
3546  Ptr<Packet> packet = p->Copy(); // Save a copy of the received packet
3547  /*
3548  * When forwarding or local deliver packets, this one should be used always!!
3549  */
3550  DsrRoutingHeader dsrRoutingHeader;
3551  packet->RemoveHeader(dsrRoutingHeader); // Remove the DSR header in whole
3552  Ptr<Packet> copy = packet->Copy();
3553 
3554  uint8_t protocol = dsrRoutingHeader.GetNextHeader();
3555  uint32_t sourceId = dsrRoutingHeader.GetSourceId();
3556  Ipv4Address source = GetIPfromID(sourceId);
3557  NS_LOG_INFO("The source address " << source << " with source id " << sourceId);
3558  /*
3559  * Get the IP source and destination address
3560  */
3561  Ipv4Address src = ip.GetSource();
3562 
3563  bool isPromisc = false;
3564  uint32_t offset =
3565  dsrRoutingHeader
3566  .GetDsrOptionsOffset(); // Get the offset for option header, 8 bytes in this case
3567 
3568  // This packet is used to peek option type
3569  p->RemoveAtStart(offset);
3570 
3571  Ptr<dsr::DsrOptions> dsrOption;
3572  DsrOptionHeader dsrOptionHeader;
3573  /*
3574  * Peek data to get the option type as well as length and segmentsLeft field
3575  */
3576  uint32_t size = p->GetSize();
3577  uint8_t* data = new uint8_t[size];
3578  p->CopyData(data, size);
3579 
3580  uint8_t optionType = 0;
3581  uint8_t optionLength = 0;
3582  uint8_t segmentsLeft = 0;
3583 
3584  optionType = *(data);
3585  NS_LOG_LOGIC("The option type value " << (uint32_t)optionType << " with packet id "
3586  << p->GetUid());
3587  dsrOption =
3588  GetOption(optionType); // Get the relative dsr option and demux to the process function
3589  Ipv4Address promiscSource;
3590  if (optionType == 1) // This is the request option
3591  {
3592  BlackList* blackList = m_rreqTable->FindUnidirectional(src);
3593  if (blackList)
3594  {
3595  NS_LOG_INFO("Discard this packet due to unidirectional link");
3596  m_dropTrace(p);
3597  }
3598 
3599  dsrOption = GetOption(optionType);
3600  optionLength =
3601  dsrOption
3602  ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3603 
3604  if (optionLength == 0)
3605  {
3606  NS_LOG_INFO("Discard this packet");
3607  m_dropTrace(p);
3608  }
3609  }
3610  else if (optionType == 2)
3611  {
3612  dsrOption = GetOption(optionType);
3613  optionLength =
3614  dsrOption
3615  ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3616 
3617  if (optionLength == 0)
3618  {
3619  NS_LOG_INFO("Discard this packet");
3620  m_dropTrace(p);
3621  }
3622  }
3623 
3624  else if (optionType == 32) // This is the ACK option
3625  {
3626  NS_LOG_INFO("This is the ack option");
3627  dsrOption = GetOption(optionType);
3628  optionLength =
3629  dsrOption
3630  ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3631 
3632  if (optionLength == 0)
3633  {
3634  NS_LOG_INFO("Discard this packet");
3635  m_dropTrace(p);
3636  }
3637  }
3638 
3639  else if (optionType == 3) // This is a route error header
3640  {
3641  // populate this route error
3642  NS_LOG_INFO("The option type value " << (uint32_t)optionType);
3643 
3644  dsrOption = GetOption(optionType);
3645  optionLength =
3646  dsrOption
3647  ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3648 
3649  if (optionLength == 0)
3650  {
3651  NS_LOG_INFO("Discard this packet");
3652  m_dropTrace(p);
3653  }
3654  NS_LOG_INFO("The option Length " << (uint32_t)optionLength);
3655  }
3656 
3657  else if (optionType == 96) // This is the source route option
3658  {
3659  dsrOption = GetOption(optionType);
3660  optionLength =
3661  dsrOption
3662  ->Process(p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3663  segmentsLeft = *(data + 3);
3664  if (optionLength == 0)
3665  {
3666  NS_LOG_INFO("Discard this packet");
3667  m_dropTrace(p);
3668  }
3669  else
3670  {
3671  if (segmentsLeft == 0)
3672  {
3673  // / Get the next header
3674  uint8_t nextHeader = dsrRoutingHeader.GetNextHeader();
3675  Ptr<Ipv4L3Protocol> l3proto = m_node->GetObject<Ipv4L3Protocol>();
3676  Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol(nextHeader);
3677  if (nextProto)
3678  {
3679  // we need to make a copy in the unlikely event we hit the
3680  // RX_ENDPOINT_UNREACH code path
3681  // Here we can use the packet that has been get off whole DSR header
3682  enum IpL4Protocol::RxStatus status =
3683  nextProto->Receive(copy, ip, incomingInterface);
3684  NS_LOG_DEBUG("The receive status " << status);
3685  switch (status)
3686  {
3687  case IpL4Protocol::RX_OK:
3688  // fall through
3690  // fall through
3692  break;
3694  if (ip.GetDestination().IsBroadcast() == true ||
3695  ip.GetDestination().IsMulticast() == true)
3696  {
3697  break; // Do not reply to broadcast or multicast
3698  }
3699  // Another case to suppress ICMP is a subnet-directed broadcast
3700  }
3701  return status;
3702  }
3703  else
3704  {
3705  NS_FATAL_ERROR("Should not have 0 next protocol value");
3706  }
3707  }
3708  else
3709  {
3710  NS_LOG_INFO("This is not the final destination, the packet has already been "
3711  "forward to next hop");
3712  }
3713  }
3714  }
3715  else
3716  {
3717  NS_LOG_LOGIC("Unknown Option. Drop!");
3718  /*
3719  * Initialize the salvage value to 0
3720  */
3721  uint8_t salvage = 0;
3722 
3723  DsrOptionRerrUnsupportHeader rerrUnsupportHeader;
3724  rerrUnsupportHeader.SetErrorType(3); // The error type 3 means Option not supported
3725  rerrUnsupportHeader.SetErrorSrc(
3726  m_mainAddress); // The error source address is our own address
3727  rerrUnsupportHeader.SetUnsupported(optionType); // The unsupported option type number
3728  rerrUnsupportHeader.SetErrorDst(
3729  src); // Error destination address is the destination of the data packet
3730  rerrUnsupportHeader.SetSalvage(
3731  salvage); // Set the value about whether to salvage a packet or not
3732 
3733  /*
3734  * The unknown option error is not supported currently in this implementation, and it's also
3735  * not likely to happen in simulations
3736  */
3737  // SendError (rerrUnsupportHeader, 0, protocol); // Send the error packet
3738  }
3739  return IpL4Protocol::RX_OK;
3740 }
3741 
3743 DsrRouting::Receive(Ptr<Packet> p, const Ipv6Header& ip, Ptr<Ipv6Interface> incomingInterface)
3744 {
3745  NS_LOG_FUNCTION(this << p << ip.GetSource() << ip.GetDestination() << incomingInterface);
3747 }
3748 
3749 void
3751 {
3752  m_downTarget = callback;
3753 }
3754 
3755 void
3757 {
3758  NS_FATAL_ERROR("Unimplemented");
3759 }
3760 
3763 {
3764  return m_downTarget;
3765 }
3766 
3769 {
3770  NS_FATAL_ERROR("Unimplemented");
3771  return MakeNullCallback<void, Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route>>();
3772 }
3773 
3774 void
3776 {
3777  m_options.push_back(option);
3778 }
3779 
3781 DsrRouting::GetOption(int optionNumber)
3782 {
3783  for (DsrOptionList_t::iterator i = m_options.begin(); i != m_options.end(); ++i)
3784  {
3785  if ((*i)->GetOptionNumber() == optionNumber)
3786  {
3787  return *i;
3788  }
3789  }
3790  return nullptr;
3791 }
3792 } /* namespace dsr */
3793 } /* namespace ns3 */
a polymophic address class
Definition: address.h:100
Wifi MAC high model for an ad-hoc Wifi MAC.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
L4 Protocol abstract base class.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
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:79
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:50
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:332
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
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:863
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:979
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:78
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:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
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:602
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:417
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1423
A simple virtual Timer class.
Definition: timer.h:74
void SetFunction(FN fn)
Definition: timer.h:278
@ 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:112
bool IsSuspended() const
Definition: timer.cc:140
void Schedule()
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:166
void Resume()
Restart the timer to expire within the amount of time left saved during Suspend.
Definition: timer.cc:202
bool IsRunning() const
Definition: timer.cc:133
void Suspend()
Pause the timer and save the amount of time left until it was set to expire.
Definition: timer.cc:185
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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 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:627
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:869
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:593
void SendBuffTimerExpire()
The send buffer timer expire.
Definition: dsr-routing.cc:858
void SetPassiveBuffer(Ptr< dsr::DsrPassiveBuffer > r)
Set the node.
Definition: dsr-routing.cc:634
std::vector< std::string > GetElementsFromContext(std::string context)
Get the elements from the tracing context.
Definition: dsr-routing.cc:549
void UseExtends(DsrRouteCacheEntry::IP_VECTOR rt)
Extends the lifetime of a route cache entry.
Definition: dsr-routing.cc:672
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:740
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.
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:684
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:813
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:537
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:715
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:641
Ipv4Address GetIPfromMAC(Mac48Address address)
Get the Ip address from mac address.
Definition: dsr-routing.cc:721
Ptr< dsr::DsrRouteCache > GetRouteCache() const
Get the route cache.
Definition: dsr-routing.cc:613
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:620
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:845
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:701
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
enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > incomingInterface) override
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:666
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:795
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:678
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:761
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:648
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:709
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:599
Ipv4Address GetIPfromID(uint16_t id)
Get the ip address from id.
Definition: dsr-routing.cc:829
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:692
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:565
int GetProtocolNumber() const override
Get the dsr protocol number.
Definition: dsr-routing.cc:806
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:606
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:231
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: string.h:57
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#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:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:40
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
mac
Definition: third.py:85
wifi
Definition: third.py:88
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