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