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