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