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.GetSeconds ());
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 {
833  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
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 ().GetSeconds () <<
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  {
1157  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1158  << "s " << 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  {
1165  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1166  << "s 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  {
1297  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1298  << "s " << 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  {
1309  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1310  << "s 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  {
1441  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1442  << "s " << 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  {
1449  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1450  << "s 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  m_linkAckTimer[linkKey].Remove ();
2088  if (m_linkAckTimer[linkKey].IsRunning ())
2089  {
2090  NS_LOG_INFO ("Timer not canceled");
2091  }
2092  m_linkAckTimer.erase (linkKey);
2093  }
2094 
2095  // Erase the maintenance entry
2096  // yet this does not check the segments left value here
2097  NS_LOG_DEBUG ("The link buffer size " << m_maintainBuffer.GetSize ());
2098  if (m_maintainBuffer.LinkEqual (mb))
2099  {
2100  NS_LOG_INFO ("Link acknowledgment received, remove same maintenance buffer entry");
2101  }
2102 }
2103 
2104 void
2106 {
2107  NS_LOG_FUNCTION (this);
2108  NetworkKey networkKey;
2109  networkKey.m_ackId = mb.GetAckId ();
2110  networkKey.m_ourAdd = mb.GetOurAdd ();
2111  networkKey.m_nextHop = mb.GetNextHop ();
2112  networkKey.m_source = mb.GetSrc ();
2113  networkKey.m_destination = mb.GetDst ();
2114  /*
2115  * Here we have found the entry for send retries, so we get the value and increase it by one
2116  */
2117  m_addressForwardCnt[networkKey] = 0;
2118  m_addressForwardCnt.erase (networkKey);
2119 
2120  NS_LOG_INFO ("ackId " << mb.GetAckId () << " ourAdd " << mb.GetOurAdd () << " nextHop " << mb.GetNextHop ()
2121  << " source " << mb.GetSrc () << " destination " << mb.GetDst ()
2122  << " segsLeft " << (uint32_t)mb.GetSegsLeft ()
2123  );
2124  // Find the network acknowledgment timer
2125  std::map<NetworkKey, Timer>::const_iterator i =
2126  m_addressForwardTimer.find (networkKey);
2127  if (i == m_addressForwardTimer.end ())
2128  {
2129  NS_LOG_INFO ("did not find the packet timer");
2130  }
2131  else
2132  {
2133  NS_LOG_INFO ("did find the packet timer");
2134  /*
2135  * Schedule the packet retry
2136  * Push back the nextHop, source, destination address
2137  */
2138  m_addressForwardTimer[networkKey].Cancel ();
2139  m_addressForwardTimer[networkKey].Remove ();
2140  if (m_addressForwardTimer[networkKey].IsRunning ())
2141  {
2142  NS_LOG_INFO ("Timer not canceled");
2143  }
2144  m_addressForwardTimer.erase (networkKey);
2145  }
2146  // Erase the maintenance entry
2147  // yet this does not check the segments left value here
2148  if (m_maintainBuffer.NetworkEqual (mb))
2149  {
2150  NS_LOG_INFO ("Remove same maintenance buffer entry based on network acknowledgment");
2151  }
2152 }
2153 
2154 void
2156 {
2157  NS_LOG_FUNCTION (this);
2158  PassiveKey passiveKey;
2159  passiveKey.m_ackId = 0;
2160  passiveKey.m_source = mb.GetSrc ();
2161  passiveKey.m_destination = mb.GetDst ();
2162  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2163 
2164  m_passiveCnt[passiveKey] = 0;
2165  m_passiveCnt.erase (passiveKey);
2166 
2167  // Find the passive acknowledgment timer
2168  std::map<PassiveKey, Timer>::const_iterator j =
2169  m_passiveAckTimer.find (passiveKey);
2170  if (j == m_passiveAckTimer.end ())
2171  {
2172  NS_LOG_INFO ("did not find the passive timer");
2173  }
2174  else
2175  {
2176  NS_LOG_INFO ("find the passive timer");
2177  /*
2178  * Cancel passive acknowledgment timer
2179  */
2180  m_passiveAckTimer[passiveKey].Cancel ();
2181  m_passiveAckTimer[passiveKey].Remove ();
2182  if (m_passiveAckTimer[passiveKey].IsRunning ())
2183  {
2184  NS_LOG_INFO ("Timer not canceled");
2185  }
2186  m_passiveAckTimer.erase (passiveKey);
2187  }
2188 }
2189 
2190 void
2192 {
2193  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
2194 
2195  DsrMaintainBuffEntry entry;
2196  std::vector<Ipv4Address> previousErrorDst;
2197  if (m_maintainBuffer.Dequeue (nextHop, entry))
2198  {
2199  Ipv4Address source = entry.GetSrc ();
2200  Ipv4Address destination = entry.GetDst ();
2201 
2202  Ptr<Packet> dsrP = entry.GetPacket ()->Copy ();
2203  Ptr<Packet> p = dsrP->Copy ();
2204  Ptr<Packet> packet = dsrP->Copy ();
2205  DsrRoutingHeader dsrRoutingHeader;
2206  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
2207  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2208  p->RemoveAtStart (offset);
2209 
2210  // Get the number of routers' address field
2211  uint8_t buf[2];
2212  p->CopyData (buf, sizeof(buf));
2213  uint8_t numberAddress = (buf[1] - 2) / 4;
2214  NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
2215  DsrOptionSRHeader sourceRoute;
2216  sourceRoute.SetNumberAddress (numberAddress);
2217  p->RemoveHeader (sourceRoute);
2218  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
2219  uint8_t salvage = sourceRoute.GetSalvage ();
2220  Ipv4Address address1 = nodeList[1];
2221  PrintVector (nodeList);
2222 
2223  /*
2224  * If the salvage is not 0, use the first address in the route as the error dst in error header
2225  * otherwise use the source of packet as the error destination
2226  */
2227  Ipv4Address errorDst;
2228  if (salvage)
2229  {
2230  errorDst = address1;
2231  }
2232  else
2233  {
2234  errorDst = source;
2235  }
2237  if (std::find (previousErrorDst.begin (), previousErrorDst.end (), destination) == previousErrorDst.end ())
2238  {
2239  NS_LOG_DEBUG ("have not seen this dst before " << errorDst << " in " << previousErrorDst.size ());
2240  SendUnreachError (nextHop, errorDst, destination, salvage, protocol);
2241  previousErrorDst.push_back (errorDst);
2242  }
2243 
2244  /*
2245  * Cancel the packet timer and then salvage the data packet
2246  */
2247 
2248  CancelPacketAllTimer (entry);
2249  SalvagePacket (packet, source, destination, protocol);
2250 
2251  if (m_maintainBuffer.GetSize () && m_maintainBuffer.Find (nextHop))
2252  {
2253  NS_LOG_INFO ("Cancel the packet timer for next maintenance entry");
2255  &DsrRouting::CancelPacketTimerNextHop,this,nextHop,protocol);
2256  }
2257  }
2258  else
2259  {
2260  NS_LOG_INFO ("Maintenance buffer entry not found");
2261  }
2263 }
2264 
2265 void
2267 {
2268  NS_LOG_FUNCTION (this << packet << source << dst << (uint32_t)protocol);
2269  // Create two copies of packet
2270  Ptr<Packet> p = packet->Copy ();
2271  Ptr<Packet> newPacket = packet->Copy ();
2272  // Remove the routing header in a whole to get a clean packet
2273  DsrRoutingHeader dsrRoutingHeader;
2274  p->RemoveHeader (dsrRoutingHeader);
2275  // Remove offset of dsr routing header
2276  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2277  newPacket->RemoveAtStart (offset);
2278 
2279  // Get the number of routers' address field
2280  uint8_t buf[2];
2281  newPacket->CopyData (buf, sizeof(buf));
2282  uint8_t numberAddress = (buf[1] - 2) / 4;
2283 
2284  DsrOptionSRHeader sourceRoute;
2285  sourceRoute.SetNumberAddress (numberAddress);
2286  newPacket->RemoveHeader (sourceRoute);
2287  uint8_t salvage = sourceRoute.GetSalvage ();
2288  /*
2289  * Look in the route cache for other routes for this destination
2290  */
2291  DsrRouteCacheEntry toDst;
2292  bool findRoute = m_routeCache->LookupRoute (dst, toDst);
2293  if (findRoute && (salvage < m_maxSalvageCount))
2294  {
2295  NS_LOG_DEBUG ("We have found a route for the packet");
2296  DsrRoutingHeader newDsrRoutingHeader;
2297  newDsrRoutingHeader.SetNextHeader (protocol);
2298  newDsrRoutingHeader.SetMessageType (2);
2299  newDsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2300  newDsrRoutingHeader.SetDestId (GetIDfromIP (dst));
2301 
2302  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
2303  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
2304  if (nextHop == "0.0.0.0")
2305  {
2306  PacketNewRoute (p, source, dst, protocol);
2307  return;
2308  }
2309  // Increase the salvage count by 1
2310  salvage++;
2311  DsrOptionSRHeader sourceRoute;
2312  sourceRoute.SetSalvage (salvage);
2313  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
2314  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
2316  if (m_routeCache->IsLinkCache ())
2317  {
2318  m_routeCache->UseExtends (nodeList);
2319  }
2320  uint8_t length = sourceRoute.GetLength ();
2321  NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ()));
2322  newDsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2323  newDsrRoutingHeader.AddDsrOption (sourceRoute);
2324  p->AddHeader (newDsrRoutingHeader);
2325 
2326  SetRoute (nextHop, m_mainAddress);
2327  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
2329 
2330  // Send out the data packet
2331  uint32_t priority = GetPriority (DSR_DATA_PACKET);
2332  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2333  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2334  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2335 
2336  //m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
2337 
2339  DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
2340 
2341  if (dsrNetworkQueue->Enqueue (newEntry))
2342  {
2343  Scheduler (priority);
2344  }
2345  else
2346  {
2347  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2348  }
2349 
2350  /*
2351  * Mark the next hop address in blacklist
2352  */
2353 // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2354 // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2355  }
2356  else
2357  {
2358  NS_LOG_DEBUG ("Will not salvage this packet, silently drop");
2359  }
2360 }
2361 
2362 void
2364  uint8_t protocol)
2365 {
2366  NS_LOG_FUNCTION (this << (uint32_t) protocol);
2367 
2368  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2369  Ipv4Address source = mb.GetSrc ();
2370  Ipv4Address nextHop = mb.GetNextHop ();
2371 
2372  // Send the data packet out before schedule the next packet transmission
2373  SendPacket (p, source, nextHop, protocol);
2374 
2375  LinkKey linkKey;
2376  linkKey.m_source = mb.GetSrc ();
2377  linkKey.m_destination = mb.GetDst ();
2378  linkKey.m_ourAdd = mb.GetOurAdd ();
2379  linkKey.m_nextHop = mb.GetNextHop ();
2380 
2381  if (m_linkAckTimer.find (linkKey) == m_linkAckTimer.end ())
2382  {
2384  m_linkAckTimer[linkKey] = timer;
2385  }
2386  m_linkAckTimer[linkKey].SetFunction (&DsrRouting::LinkScheduleTimerExpire, this);
2387  m_linkAckTimer[linkKey].Remove ();
2388  m_linkAckTimer[linkKey].SetArguments (mb, protocol);
2389  m_linkAckTimer[linkKey].Schedule (m_linkAckTimeout);
2390 }
2391 
2392 void
2394  uint8_t protocol)
2395 {
2396  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2397 
2398  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2399  Ipv4Address source = mb.GetSrc ();
2400  Ipv4Address nextHop = mb.GetNextHop ();
2401 
2402  // Send the data packet out before schedule the next packet transmission
2403  SendPacket (p, source, nextHop, protocol);
2404 
2405  PassiveKey passiveKey;
2406  passiveKey.m_ackId = 0;
2407  passiveKey.m_source = mb.GetSrc ();
2408  passiveKey.m_destination = mb.GetDst ();
2409  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2410 
2411  if (m_passiveAckTimer.find (passiveKey) == m_passiveAckTimer.end ())
2412  {
2414  m_passiveAckTimer[passiveKey] = timer;
2415  }
2416  NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
2417  m_passiveAckTimer[passiveKey].SetFunction (&DsrRouting::PassiveScheduleTimerExpire, this);
2418  m_passiveAckTimer[passiveKey].Remove ();
2419  m_passiveAckTimer[passiveKey].SetArguments (mb, protocol);
2420  m_passiveAckTimer[passiveKey].Schedule (m_passiveAckTimeout);
2421 }
2422 
2423 void
2425  bool isFirst,
2426  uint8_t protocol)
2427 {
2428  Ptr<Packet> p = Create<Packet> ();
2429  Ptr<Packet> dsrP = Create<Packet> ();
2430  // The new entry will be used for retransmission
2431  NetworkKey networkKey;
2432  Ipv4Address nextHop = mb.GetNextHop ();
2433  NS_LOG_DEBUG ("is the first retry or not " << isFirst);
2434  if (isFirst)
2435  {
2436  // This is the very first network packet retry
2437  p = mb.GetPacket ()->Copy ();
2438  // Here we add the ack request header to the data packet for network acknowledgement
2439  uint16_t ackId = AddAckReqHeader (p, nextHop);
2440 
2441  Ipv4Address source = mb.GetSrc ();
2442  Ipv4Address nextHop = mb.GetNextHop ();
2443  // Send the data packet out before schedule the next packet transmission
2444  SendPacket (p, source, nextHop, protocol);
2445 
2446  dsrP = p->Copy ();
2447  DsrMaintainBuffEntry newEntry = mb;
2448  // The function AllEqual will find the exact entry and delete it if found
2450  newEntry.SetPacket (dsrP);
2451  newEntry.SetAckId (ackId);
2452  newEntry.SetExpireTime (m_maxMaintainTime);
2453 
2454  networkKey.m_ackId = newEntry.GetAckId ();
2455  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2456  networkKey.m_nextHop = newEntry.GetNextHop ();
2457  networkKey.m_source = newEntry.GetSrc ();
2458  networkKey.m_destination = newEntry.GetDst ();
2459 
2460  m_addressForwardCnt[networkKey] = 0;
2461  if (!m_maintainBuffer.Enqueue (newEntry))
2462  {
2463  NS_LOG_ERROR ("Failed to enqueue packet retry");
2464  }
2465 
2466  if (m_addressForwardTimer.find (networkKey) == m_addressForwardTimer.end ())
2467  {
2469  m_addressForwardTimer[networkKey] = timer;
2470  }
2471 
2472  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2473  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2474  m_addressForwardTimer[networkKey].Remove ();
2475  m_addressForwardTimer[networkKey].SetArguments (newEntry, protocol);
2476  NS_LOG_DEBUG ("The packet retries time for " << newEntry.GetAckId () << " is " << m_sendRetries
2477  << " and the delay time is " << Time (2 * m_nodeTraversalTime).GetSeconds ());
2478  // Back-off mechanism
2479  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_nodeTraversalTime));
2480  }
2481  else
2482  {
2483  networkKey.m_ackId = mb.GetAckId ();
2484  networkKey.m_ourAdd = mb.GetOurAdd ();
2485  networkKey.m_nextHop = mb.GetNextHop ();
2486  networkKey.m_source = mb.GetSrc ();
2487  networkKey.m_destination = mb.GetDst ();
2488  /*
2489  * Here we have found the entry for send retries, so we get the value and increase it by one
2490  */
2491  m_sendRetries = m_addressForwardCnt[networkKey];
2492  NS_LOG_DEBUG ("The packet retry we have done " << m_sendRetries);
2493 
2494  p = mb.GetPacket ()->Copy ();
2495  dsrP = mb.GetPacket ()->Copy ();
2496 
2497  Ipv4Address source = mb.GetSrc ();
2498  Ipv4Address nextHop = mb.GetNextHop ();
2499  // Send the data packet out before schedule the next packet transmission
2500  SendPacket (p, source, nextHop, protocol);
2501 
2502  NS_LOG_DEBUG ("The packet with dsr header " << dsrP->GetSize ());
2503  networkKey.m_ackId = mb.GetAckId ();
2504  networkKey.m_ourAdd = mb.GetOurAdd ();
2505  networkKey.m_nextHop = mb.GetNextHop ();
2506  networkKey.m_source = mb.GetSrc ();
2507  networkKey.m_destination = mb.GetDst ();
2508  /*
2509  * If a data packet has been attempted SendRetries times at the maximum TTL without
2510  * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2511  * dropped from the send buffer
2512  *
2513  * The maxMaintRexmt also needs to decrease one for the passive ack packet
2514  */
2515  /*
2516  * Check if the send retry time for a certain packet has already passed max maintenance retransmission
2517  * time or not
2518  */
2519 
2520  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2521  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2522  m_addressForwardTimer[networkKey].Remove ();
2523  m_addressForwardTimer[networkKey].SetArguments (mb, protocol);
2524  NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId () << " is " << m_sendRetries
2525  << " and the delay time is " << Time (2 * m_sendRetries * m_nodeTraversalTime).GetSeconds ());
2526  // Back-off mechanism
2527  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries * m_nodeTraversalTime));
2528  }
2529 }
2530 
2531 void
2533  uint8_t protocol)
2534 {
2535  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2536  Ipv4Address nextHop = mb.GetNextHop ();
2537  Ptr<const Packet> packet = mb.GetPacket ();
2538  SetRoute (nextHop, m_mainAddress);
2539  Ptr<Packet> p = packet->Copy ();
2540 
2541  LinkKey lk;
2542  lk.m_source = mb.GetSrc ();
2543  lk.m_destination = mb.GetDst ();
2544  lk.m_ourAdd = mb.GetOurAdd ();
2545  lk.m_nextHop = mb.GetNextHop ();
2546 
2547  // Cancel passive ack timer
2548  m_linkAckTimer[lk].Cancel ();
2549  m_linkAckTimer[lk].Remove ();
2550  if (m_linkAckTimer[lk].IsRunning ())
2551  {
2552  NS_LOG_DEBUG ("Timer not canceled");
2553  }
2554  m_linkAckTimer.erase (lk);
2555 
2556  // Increase the send retry times
2557  m_linkRetries = m_linkCnt[lk];
2559  {
2560  m_linkCnt[lk] = ++m_linkRetries;
2561  ScheduleLinkPacketRetry (mb, protocol);
2562  }
2563  else
2564  {
2565  NS_LOG_INFO ("We need to send error messages now");
2566 
2567  // Delete all the routes including the links
2568  m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
2569  /*
2570  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2571  * Also salvage the packet for the all the packet destined for the nextHop address
2572  * this is also responsible for send unreachable error back to source
2573  */
2574  CancelPacketTimerNextHop (nextHop, protocol);
2575  }
2576 }
2577 
2578 void
2580  uint8_t protocol)
2581 {
2582  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2583  Ipv4Address nextHop = mb.GetNextHop ();
2584  Ptr<const Packet> packet = mb.GetPacket ();
2585  SetRoute (nextHop, m_mainAddress);
2586  Ptr<Packet> p = packet->Copy ();
2587 
2588  PassiveKey pk;
2589  pk.m_ackId = 0;
2590  pk.m_source = mb.GetSrc ();
2591  pk.m_destination = mb.GetDst ();
2592  pk.m_segsLeft = mb.GetSegsLeft ();
2593 
2594  // Cancel passive ack timer
2595  m_passiveAckTimer[pk].Cancel ();
2596  m_passiveAckTimer[pk].Remove ();
2597  if (m_passiveAckTimer[pk].IsRunning ())
2598  {
2599  NS_LOG_DEBUG ("Timer not canceled");
2600  }
2601  m_passiveAckTimer.erase (pk);
2602 
2603  // Increase the send retry times
2606  {
2608  SchedulePassivePacketRetry (mb, protocol);
2609  }
2610  else
2611  {
2612  // This is the first network acknowledgement retry
2613  // Cancel the passive packet timer now and remove maintenance buffer entry for it
2615  ScheduleNetworkPacketRetry (mb, true, protocol);
2616  }
2617 }
2618 
2619 int64_t
2621 {
2622  NS_LOG_FUNCTION (this << stream);
2624  return 1;
2625 }
2626 
2627 void
2629  uint8_t protocol)
2630 {
2631  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2632  Ipv4Address source = mb.GetSrc ();
2633  Ipv4Address nextHop = mb.GetNextHop ();
2634  Ipv4Address dst = mb.GetDst ();
2635 
2636  NetworkKey networkKey;
2637  networkKey.m_ackId = mb.GetAckId ();
2638  networkKey.m_ourAdd = mb.GetOurAdd ();
2639  networkKey.m_nextHop = nextHop;
2640  networkKey.m_source = source;
2641  networkKey.m_destination = dst;
2642 
2643  // Increase the send retry times
2644  m_sendRetries = m_addressForwardCnt[networkKey];
2645 
2647  {
2648  // Delete all the routes including the links
2649  m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
2650  /*
2651  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2652  * Also salvage the packet for the all the packet destined for the nextHop address
2653  */
2654  CancelPacketTimerNextHop (nextHop, protocol);
2655  }
2656  else
2657  {
2658  m_addressForwardCnt[networkKey] = ++m_sendRetries;
2659  ScheduleNetworkPacketRetry (mb, false, protocol);
2660  }
2661 }
2662 
2663 void
2665  DsrOptionSRHeader &sourceRoute,
2666  Ipv4Header const& ipv4Header,
2667  Ipv4Address source,
2668  Ipv4Address nextHop,
2669  Ipv4Address targetAddress,
2670  uint8_t protocol,
2671  Ptr<Ipv4Route> route)
2672 {
2673  NS_LOG_FUNCTION (this << packet << sourceRoute << source << nextHop << targetAddress << (uint32_t)protocol << route);
2674  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2675 
2676  DsrRoutingHeader dsrRoutingHeader;
2677  dsrRoutingHeader.SetNextHeader (protocol);
2678  dsrRoutingHeader.SetMessageType (2);
2679  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2680  dsrRoutingHeader.SetDestId (GetIDfromIP (targetAddress));
2681 
2682  // We get the salvage value in sourceRoute header and set it to route error header if triggered error
2683  Ptr<Packet> p = packet->Copy ();
2684  uint8_t length = sourceRoute.GetLength ();
2685  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2686  dsrRoutingHeader.AddDsrOption (sourceRoute);
2687  p->AddHeader (dsrRoutingHeader);
2688 
2689  Ptr<const Packet> mtP = p->Copy ();
2690 
2691  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
2692  /*source=*/ source, /*destination=*/ targetAddress, /*ackId=*/ m_ackId,
2693  /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
2694  bool result = m_maintainBuffer.Enqueue (newEntry);
2695 
2696  if (result)
2697  {
2698  NetworkKey networkKey;
2699  networkKey.m_ackId = newEntry.GetAckId ();
2700  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2701  networkKey.m_nextHop = newEntry.GetNextHop ();
2702  networkKey.m_source = newEntry.GetSrc ();
2703  networkKey.m_destination = newEntry.GetDst ();
2704 
2705  PassiveKey passiveKey;
2706  passiveKey.m_ackId = 0;
2707  passiveKey.m_source = newEntry.GetSrc ();
2708  passiveKey.m_destination = newEntry.GetDst ();
2709  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
2710 
2711  LinkKey linkKey;
2712  linkKey.m_source = newEntry.GetSrc ();
2713  linkKey.m_destination = newEntry.GetDst ();
2714  linkKey.m_ourAdd = newEntry.GetOurAdd ();
2715  linkKey.m_nextHop = newEntry.GetNextHop ();
2716 
2717  m_addressForwardCnt[networkKey] = 0;
2718  m_passiveCnt[passiveKey] = 0;
2719  m_linkCnt[linkKey] = 0;
2720 
2721  if (m_linkAck)
2722  {
2723  ScheduleLinkPacketRetry (newEntry, protocol);
2724  }
2725  else
2726  {
2727  NS_LOG_LOGIC ("Not using link acknowledgment");
2728  if (nextHop != targetAddress)
2729  {
2730  SchedulePassivePacketRetry (newEntry, protocol);
2731  }
2732  else
2733  {
2734  // This is the first network retry
2735  ScheduleNetworkPacketRetry (newEntry, true, protocol);
2736  }
2737  }
2738  }
2739 }
2740 
2741 void
2743  Ipv4Address destination,
2744  uint8_t protocol)
2745 {
2746  NS_LOG_FUNCTION (this << source << destination << (uint32_t)protocol);
2747  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2748  Ptr<Packet> packet = Create<Packet> ();
2749  // Create an empty Ipv4 route ptr
2750  Ptr<Ipv4Route> route;
2751  /*
2752  * Construct the route request option header
2753  */
2754  DsrRoutingHeader dsrRoutingHeader;
2755  dsrRoutingHeader.SetNextHeader (protocol);
2756  dsrRoutingHeader.SetMessageType (1);
2757  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2758  dsrRoutingHeader.SetDestId (255);
2759 
2760  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2761  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2762  rreqHeader.SetTarget (destination);
2763  m_requestId = m_rreqTable->CheckUniqueRreqId (destination); // Check the Id cache for duplicate ones
2764  rreqHeader.SetId (m_requestId);
2765 
2766  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2767  uint8_t length = rreqHeader.GetLength ();
2768  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2769  packet->AddHeader (dsrRoutingHeader);
2770 
2771  // Schedule the route requests retry with non-propagation set true
2772  bool nonProp = true;
2773  std::vector<Ipv4Address> address;
2774  address.push_back (source);
2775  address.push_back (destination);
2776  /*
2777  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2778  */
2779  SocketIpTtlTag tag;
2780  tag.SetTtl (0);
2781  Ptr<Packet> nonPropPacket = packet->Copy ();
2782  nonPropPacket->AddPacketTag (tag);
2783  // Increase the request count
2784  m_rreqTable->FindAndUpdate (destination);
2785  SendRequest (nonPropPacket, source);
2786  // Schedule the next route request
2787  ScheduleRreqRetry (packet, address, nonProp, m_requestId, protocol);
2788 }
2789 
2790 void
2792 {
2793  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2794  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2795  uint8_t salvage = rerr.GetSalvage ();
2796  Ipv4Address dst = rerr.GetOriginalDst ();
2797  NS_LOG_DEBUG ("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc () << " error destination " << rerr.GetErrorDst ()
2798  << " error next hop " << rerr.GetUnreachNode () << " original dst " << rerr.GetOriginalDst ()
2799  );
2800  DsrRouteCacheEntry toDst;
2801  if (m_routeCache->LookupRoute (dst, toDst))
2802  {
2803  /*
2804  * Found a route the dst, construct the source route option header
2805  */
2806  DsrOptionSRHeader sourceRoute;
2807  std::vector<Ipv4Address> ip = toDst.GetVector ();
2808  sourceRoute.SetNodesAddress (ip);
2810  if (m_routeCache->IsLinkCache ())
2811  {
2812  m_routeCache->UseExtends (ip);
2813  }
2814  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
2815  sourceRoute.SetSalvage (salvage);
2816  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
2817  NS_LOG_DEBUG ("The nextHop address " << nextHop);
2818  Ptr<Packet> packet = Create<Packet> ();
2819  if (nextHop == "0.0.0.0")
2820  {
2821  NS_LOG_DEBUG ("Error next hop address");
2822  PacketNewRoute (packet, m_mainAddress, dst, protocol);
2823  return;
2824  }
2825  SetRoute (nextHop, m_mainAddress);
2826  CancelRreqTimer (dst, true);
2828  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
2829  {
2830  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
2831  }
2832  NS_LOG_LOGIC ("Route to " << dst << " found");
2833  return;
2834  }
2835  else
2836  {
2837  NS_LOG_INFO ("No route found, initiate route error request");
2838  Ptr<Packet> packet = Create<Packet> ();
2839  Ipv4Address originalDst = rerr.GetOriginalDst ();
2840  // Create an empty route ptr
2841  Ptr<Ipv4Route> route = 0;
2842  /*
2843  * Construct the route request option header
2844  */
2845  DsrRoutingHeader dsrRoutingHeader;
2846  dsrRoutingHeader.SetNextHeader (protocol);
2847  dsrRoutingHeader.SetMessageType (1);
2848  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
2849  dsrRoutingHeader.SetDestId (255);
2850 
2851  Ptr<Packet> dstP = Create<Packet> ();
2852  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2853  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2854  rreqHeader.SetTarget (originalDst);
2855  m_requestId = m_rreqTable->CheckUniqueRreqId (originalDst); // Check the Id cache for duplicate ones
2856  rreqHeader.SetId (m_requestId);
2857 
2858  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2859  dsrRoutingHeader.AddDsrOption (rerr);
2860  uint8_t length = rreqHeader.GetLength () + rerr.GetLength ();
2861  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
2862  dstP->AddHeader (dsrRoutingHeader);
2863  // Schedule the route requests retry, propagate the route request message as it contains error
2864  bool nonProp = false;
2865  std::vector<Ipv4Address> address;
2866  address.push_back (m_mainAddress);
2867  address.push_back (originalDst);
2868  /*
2869  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2870  */
2871  SocketIpTtlTag tag;
2872  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
2873  Ptr<Packet> propPacket = dstP->Copy ();
2874  propPacket->AddPacketTag (tag);
2875 
2876  if ((m_addressReqTimer.find (originalDst) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (originalDst) == m_nonPropReqTimer.end ()))
2877  {
2878  NS_LOG_INFO ("Only when there is no existing route request time when the initial route request is scheduled");
2879  SendRequest (propPacket, m_mainAddress);
2880  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2881  }
2882  else
2883  {
2884  NS_LOG_INFO ("There is existing route request, find the existing route request entry");
2885  /*
2886  * Cancel the route request timer first before scheduling the route request
2887  * in this case, we do not want to remove the route request entry, so the isRemove value is false
2888  */
2889  CancelRreqTimer (originalDst, false);
2890  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2891  }
2892  }
2893 }
2894 
2895 void
2897 {
2898  NS_LOG_FUNCTION (this << dst << isRemove);
2899  // Cancel the non propagation request timer if found
2900  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2901  {
2902  NS_LOG_DEBUG ("Did not find the non-propagation timer");
2903  }
2904  else
2905  {
2906  NS_LOG_DEBUG ("did find the non-propagation timer");
2907  }
2908  m_nonPropReqTimer[dst].Cancel ();
2909  m_nonPropReqTimer[dst].Remove ();
2910 
2911  if (m_nonPropReqTimer[dst].IsRunning ())
2912  {
2913  NS_LOG_DEBUG ("Timer not canceled");
2914  }
2915  m_nonPropReqTimer.erase (dst);
2916 
2917  // Cancel the address request timer if found
2918  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2919  {
2920  NS_LOG_DEBUG ("Did not find the propagation timer");
2921  }
2922  else
2923  {
2924  NS_LOG_DEBUG ("did find the propagation timer");
2925  }
2926  m_addressReqTimer[dst].Cancel ();
2927  m_addressReqTimer[dst].Remove ();
2928  if (m_addressReqTimer[dst].IsRunning ())
2929  {
2930  NS_LOG_DEBUG ("Timer not canceled");
2931  }
2932  m_addressReqTimer.erase (dst);
2933  /*
2934  * If the route request is scheduled to remove the route request entry
2935  * Remove the route request entry with the route retry times done for certain destination
2936  */
2937  if (isRemove)
2938  {
2939  // remove the route request entry from route request table
2940  m_rreqTable->RemoveRreqEntry (dst);
2941  }
2942 }
2943 
2944 void
2945 DsrRouting::ScheduleRreqRetry (Ptr<Packet> packet, std::vector<Ipv4Address> address, bool nonProp, uint32_t requestId, uint8_t protocol)
2946 {
2947  NS_LOG_FUNCTION (this << packet << nonProp << requestId << (uint32_t)protocol);
2948  Ipv4Address source = address[0];
2949  Ipv4Address dst = address[1];
2950  if (nonProp)
2951  {
2952  // The nonProp route request is only sent out only and is already used
2953  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2954  {
2956  m_nonPropReqTimer[dst] = timer;
2957  }
2958  std::vector<Ipv4Address> address;
2959  address.push_back (source);
2960  address.push_back (dst);
2961  m_nonPropReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2962  m_nonPropReqTimer[dst].Remove ();
2963  m_nonPropReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2965  }
2966  else
2967  {
2968  // Cancel the non propagation request timer if found
2969  m_nonPropReqTimer[dst].Cancel ();
2970  m_nonPropReqTimer[dst].Remove ();
2971  if (m_nonPropReqTimer[dst].IsRunning ())
2972  {
2973  NS_LOG_DEBUG ("Timer not canceled");
2974  }
2975  m_nonPropReqTimer.erase (dst);
2976 
2977  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2978  {
2980  m_addressReqTimer[dst] = timer;
2981  }
2982  std::vector<Ipv4Address> address;
2983  address.push_back (source);
2984  address.push_back (dst);
2985  m_addressReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2986  m_addressReqTimer[dst].Remove ();
2987  m_addressReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2988  Time rreqDelay;
2989  // back off mechanism for sending route requests
2990  if (m_rreqTable->GetRreqCnt (dst))
2991  {
2992  // When the route request count is larger than 0
2993  // This is the exponential back-off mechanism for route request
2994  rreqDelay = Time (std::pow (static_cast<double> (m_rreqTable->GetRreqCnt (dst)), 2.0) * m_requestPeriod);
2995  }
2996  else
2997  {
2998  // This is the first route request retry
2999  rreqDelay = m_requestPeriod;
3000  }
3001  NS_LOG_LOGIC ("Request count for " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with delay time " << rreqDelay.GetSeconds () << " second");
3002  if (rreqDelay > m_maxRequestPeriod)
3003  {
3004  // use the max request period
3005  NS_LOG_LOGIC ("The max request delay time " << m_maxRequestPeriod.GetSeconds ());
3006  m_addressReqTimer[dst].Schedule (m_maxRequestPeriod);
3007  }
3008  else
3009  {
3010  NS_LOG_LOGIC ("The request delay time " << rreqDelay.GetSeconds () << " second");
3011  m_addressReqTimer[dst].Schedule (rreqDelay);
3012  }
3013  }
3014 }
3015 
3016 void
3017 DsrRouting::RouteRequestTimerExpire (Ptr<Packet> packet, std::vector<Ipv4Address> address, uint32_t requestId, uint8_t protocol)
3018 {
3019  NS_LOG_FUNCTION (this << packet << requestId << (uint32_t)protocol);
3020  // Get a clean packet without dsr header
3021  Ptr<Packet> dsrP = packet->Copy ();
3022  DsrRoutingHeader dsrRoutingHeader;
3023  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
3024 
3025  Ipv4Address source = address[0];
3026  Ipv4Address dst = address[1];
3027  DsrRouteCacheEntry toDst;
3028  if (m_routeCache->LookupRoute (dst, toDst))
3029  {
3030  /*
3031  * Found a route the dst, construct the source route option header
3032  */
3033  DsrOptionSRHeader sourceRoute;
3034  std::vector<Ipv4Address> ip = toDst.GetVector ();
3035  sourceRoute.SetNodesAddress (ip);
3036  // When we found the route and use it, UseExtends for the link cache
3037  if (m_routeCache->IsLinkCache ())
3038  {
3039  m_routeCache->UseExtends (ip);
3040  }
3041  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
3043  sourceRoute.SetSalvage (0);
3044  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
3045  NS_LOG_INFO ("The nextHop address is " << nextHop);
3046  if (nextHop == "0.0.0.0")
3047  {
3048  NS_LOG_DEBUG ("Error next hop address");
3049  PacketNewRoute (dsrP, source, dst, protocol);
3050  return;
3051  }
3052  SetRoute (nextHop, m_mainAddress);
3053  CancelRreqTimer (dst, true);
3055  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
3056  {
3057  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
3058  }
3059  NS_LOG_LOGIC ("Route to " << dst << " found");
3060  return;
3061  }
3062  /*
3063  * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
3064  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
3065  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
3066  */
3067  NS_LOG_LOGIC ("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt (dst) << " the max " << m_rreqRetries);
3068  if (m_rreqTable->GetRreqCnt (dst) >= m_rreqRetries)
3069  {
3070  NS_LOG_LOGIC ("Route discovery to " << dst << " has been attempted " << m_rreqRetries << " times");
3071  CancelRreqTimer (dst, true);
3072  NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
3074  }
3075  else
3076  {
3077  SocketIpTtlTag tag;
3078  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
3079  Ptr<Packet> propPacket = packet->Copy ();
3080  propPacket->AddPacketTag (tag);
3081  // Increase the request count
3082  m_rreqTable->FindAndUpdate (dst);
3083  SendRequest (propPacket, source);
3084  NS_LOG_DEBUG ("Check the route request entry " << source << " " << dst);
3085  ScheduleRreqRetry (packet, address, false, requestId, protocol);
3086  }
3087  return;
3088 }
3089 
3090 void
3092  Ipv4Address source)
3093 {
3094  NS_LOG_FUNCTION (this << packet << source);
3095 
3096  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3097  /*
3098  * The destination address here is directed broadcast address
3099  */
3100  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3101  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3102  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3103  NS_LOG_LOGIC ("Inserting into priority queue number: " << priority);
3104 
3105  //m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
3106 
3108  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
3109  if (dsrNetworkQueue->Enqueue (newEntry))
3110  {
3111  Scheduler (priority);
3112  }
3113  else
3114  {
3115  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3116  }
3117 }
3118 
3119 void
3121 {
3122  NS_LOG_FUNCTION (this << packet);
3123  /*
3124  * This is a forwarding case when sending route requests, a random delay time [0, m_broadcastJitter]
3125  * used before forwarding as link-layer broadcast
3126  */
3128  packet, m_mainAddress);
3129 }
3130 
3131 void
3132 DsrRouting::SendGratuitousReply (Ipv4Address source, Ipv4Address srcAddress, std::vector<Ipv4Address> &nodeList, uint8_t protocol)
3133 {
3134  NS_LOG_FUNCTION (this << source << srcAddress << (uint32_t)protocol);
3135  if (!(m_graReply.FindAndUpdate (source, srcAddress, m_gratReplyHoldoff))) // Find the gratuitous reply entry
3136  {
3137  NS_LOG_LOGIC ("Update gratuitous reply " << source);
3138  GraReplyEntry graReplyEntry (source, srcAddress, m_gratReplyHoldoff + Simulator::Now ());
3139  m_graReply.AddEntry (graReplyEntry);
3140  /*
3141  * Automatic route shortening
3142  */
3143  m_finalRoute.clear (); // Clear the final route vector
3147  std::vector<Ipv4Address>::iterator before = find (nodeList.begin (), nodeList.end (), srcAddress);
3148  for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != before; ++i)
3149  {
3150  m_finalRoute.push_back (*i);
3151  }
3152  m_finalRoute.push_back (srcAddress);
3153  std::vector<Ipv4Address>::iterator after = find (nodeList.begin (), nodeList.end (), m_mainAddress);
3154  for (std::vector<Ipv4Address>::iterator j = after; j != nodeList.end (); ++j)
3155  {
3156  m_finalRoute.push_back (*j);
3157  }
3158  DsrOptionRrepHeader rrep;
3159  rrep.SetNodesAddress (m_finalRoute); // Set the node addresses in the route reply header
3160  // Get the real reply source and destination
3161  Ipv4Address replySrc = m_finalRoute.back ();
3162  Ipv4Address replyDst = m_finalRoute.front ();
3163  /*
3164  * Set the route and use it in send back route reply
3165  */
3166  m_ipv4Route = SetRoute (srcAddress, m_mainAddress);
3167  /*
3168  * This part adds DSR header to the packet and send reply
3169  */
3170  DsrRoutingHeader dsrRoutingHeader;
3171  dsrRoutingHeader.SetNextHeader (protocol);
3172  dsrRoutingHeader.SetMessageType (1);
3173  dsrRoutingHeader.SetSourceId (GetIDfromIP (replySrc));
3174  dsrRoutingHeader.SetDestId (GetIDfromIP (replyDst));
3175 
3176  uint8_t length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
3177  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
3178  dsrRoutingHeader.AddDsrOption (rrep);
3179  Ptr<Packet> newPacket = Create<Packet> ();
3180  newPacket->AddHeader (dsrRoutingHeader);
3181  /*
3182  * Send gratuitous reply
3183  */
3184  NS_LOG_INFO ("Send back gratuitous route reply");
3185  SendReply (newPacket, m_mainAddress, srcAddress, m_ipv4Route);
3186  }
3187  else
3188  {
3189  NS_LOG_INFO ("The same gratuitous route reply has already sent");
3190  }
3191 }
3192 
3193 void
3195  Ipv4Address source,
3196  Ipv4Address nextHop,
3197  Ptr<Ipv4Route> route)
3198 {
3199  NS_LOG_FUNCTION (this << packet << source << nextHop);
3200  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3201 
3202  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (m_mainAddress));
3203  route->SetOutputDevice (dev);
3204  NS_LOG_INFO ("The output device " << dev << " packet is: " << *packet);
3205 
3206  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3207  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3208  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3209  NS_LOG_INFO ("Inserting into priority queue number: " << priority);
3210 
3211  //m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3212 
3214  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
3215  if (dsrNetworkQueue->Enqueue (newEntry))
3216  {
3217  Scheduler (priority);
3218  }
3219  else
3220  {
3221  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3222  }
3223 }
3224 
3225 void
3227  Ipv4Address source,
3228  Ipv4Address nextHop,
3229  Ptr<Ipv4Route> route)
3230 {
3231  NS_LOG_FUNCTION (this << packet << source << nextHop);
3233  packet, source, nextHop, route);
3234 }
3235 
3236 void
3238  Ipv4Address source,
3239  Ipv4Address destination,
3240  Ptr<Ipv4Route> route,
3241  double hops)
3242 {
3243  NS_LOG_FUNCTION (this << packet << source << destination);
3244  Simulator::Schedule (Time (2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue (0,1))), &DsrRouting::SendReply, this, packet, source, destination, route);
3245 }
3246 
3247 void
3248 DsrRouting::SendAck (uint16_t ackId,
3249  Ipv4Address destination,
3250  Ipv4Address realSrc,
3251  Ipv4Address realDst,
3252  uint8_t protocol,
3253  Ptr<Ipv4Route> route)
3254 {
3255  NS_LOG_FUNCTION (this << ackId << destination << realSrc << realDst << (uint32_t)protocol << route);
3256  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3257 
3258  // This is a route reply option header
3259  DsrRoutingHeader dsrRoutingHeader;
3260  dsrRoutingHeader.SetNextHeader (protocol);
3261  dsrRoutingHeader.SetMessageType (1);
3262  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
3263  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
3264 
3265  DsrOptionAckHeader ack;
3266  /*
3267  * Set the ack Id and set the ack source address and destination address
3268  */
3269  ack.SetAckId (ackId);
3270  ack.SetRealSrc (realSrc);
3271  ack.SetRealDst (realDst);
3272 
3273  uint8_t length = ack.GetLength ();
3274  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
3275  dsrRoutingHeader.AddDsrOption (ack);
3276 
3277  Ptr<Packet> packet = Create<Packet> ();
3278  packet->AddHeader (dsrRoutingHeader);
3279  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
3280  route->SetOutputDevice (dev);
3281 
3282  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3283  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3284  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3285 
3286  NS_LOG_LOGIC ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
3287 
3288  //m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
3289 
3291  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
3292  if (dsrNetworkQueue->Enqueue (newEntry))
3293  {
3294  Scheduler (priority);
3295  }
3296  else
3297  {
3298  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3299  }
3300 }
3301 
3304  Ipv4Header const &ip,
3305  Ptr<Ipv4Interface> incomingInterface)
3306 {
3307  NS_LOG_FUNCTION (this << p << ip << incomingInterface);
3308 
3309  NS_LOG_INFO ("Our own IP address " << m_mainAddress << " The incoming interface address " << incomingInterface);
3310  m_node = GetNode (); // Get the node
3311  Ptr<Packet> packet = p->Copy (); // Save a copy of the received packet
3312  /*
3313  * When forwarding or local deliver packets, this one should be used always!!
3314  */
3315  DsrRoutingHeader dsrRoutingHeader;
3316  packet->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
3317  Ptr<Packet> copy = packet->Copy ();
3318 
3319  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
3320  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
3321  Ipv4Address source = GetIPfromID (sourceId);
3322  NS_LOG_INFO ("The source address " << source << " with source id " << sourceId);
3323  /*
3324  * Get the IP source and destination address
3325  */
3326  Ipv4Address src = ip.GetSource ();
3327 
3328  bool isPromisc = false;
3329  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset (); // Get the offset for option header, 8 bytes in this case
3330 
3331  // This packet is used to peek option type
3332  p->RemoveAtStart (offset);
3333 
3334  Ptr<dsr::DsrOptions> dsrOption;
3335  DsrOptionHeader dsrOptionHeader;
3336  /*
3337  * Peek data to get the option type as well as length and segmentsLeft field
3338  */
3339  uint32_t size = p->GetSize ();
3340  uint8_t *data = new uint8_t[size];
3341  p->CopyData (data, size);
3342 
3343  uint8_t optionType = 0;
3344  uint8_t optionLength = 0;
3345  uint8_t segmentsLeft = 0;
3346 
3347  optionType = *(data);
3348  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet id " << p->GetUid ());
3349  dsrOption = GetOption (optionType); // Get the relative dsr option and demux to the process function
3350  Ipv4Address promiscSource;
3351  if (optionType == 1) // This is the request option
3352  {
3353  BlackList *blackList = m_rreqTable->FindUnidirectional (src);
3354  if (blackList)
3355  {
3356  NS_LOG_INFO ("Discard this packet due to unidirectional link");
3357  m_dropTrace (p);
3358  }
3359 
3360  dsrOption = GetOption (optionType);
3361  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3362 
3363  if (optionLength == 0)
3364  {
3365  NS_LOG_INFO ("Discard this packet");
3366  m_dropTrace (p);
3367  }
3368  }
3369  else if (optionType == 2)
3370  {
3371  dsrOption = GetOption (optionType);
3372  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3373 
3374  if (optionLength == 0)
3375  {
3376  NS_LOG_INFO ("Discard this packet");
3377  m_dropTrace (p);
3378  }
3379  }
3380 
3381  else if (optionType == 32) // This is the ACK option
3382  {
3383  NS_LOG_INFO ("This is the ack option");
3384  dsrOption = GetOption (optionType);
3385  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3386 
3387  if (optionLength == 0)
3388  {
3389  NS_LOG_INFO ("Discard this packet");
3390  m_dropTrace (p);
3391  }
3392  }
3393 
3394  else if (optionType == 3) // This is a route error header
3395  {
3396  // populate this route error
3397  NS_LOG_INFO ("The option type value " << (uint32_t)optionType);
3398 
3399  dsrOption = GetOption (optionType);
3400  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3401 
3402  if (optionLength == 0)
3403  {
3404  NS_LOG_INFO ("Discard this packet");
3405  m_dropTrace (p);
3406  }
3407  NS_LOG_INFO ("The option Length " << (uint32_t)optionLength);
3408  }
3409 
3410  else if (optionType == 96) // This is the source route option
3411  {
3412  dsrOption = GetOption (optionType);
3413  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3414  segmentsLeft = *(data + 3);
3415  if (optionLength == 0)
3416  {
3417  NS_LOG_INFO ("Discard this packet");
3418  m_dropTrace (p);
3419  }
3420  else
3421  {
3422  if (segmentsLeft == 0)
3423  {
3424  // / Get the next header
3425  uint8_t nextHeader = dsrRoutingHeader.GetNextHeader ();
3427  Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol (nextHeader);
3428  if (nextProto != 0)
3429  {
3430  // we need to make a copy in the unlikely event we hit the
3431  // RX_ENDPOINT_UNREACH code path
3432  // Here we can use the packet that has been get off whole DSR header
3433  enum IpL4Protocol::RxStatus status =
3434  nextProto->Receive (copy, ip, incomingInterface);
3435  NS_LOG_DEBUG ("The receive status " << status);
3436  switch (status)
3437  {
3438  case IpL4Protocol::RX_OK:
3439  // fall through
3441  // fall through
3443  break;
3445  if (ip.GetDestination ().IsBroadcast () == true
3446  || ip.GetDestination ().IsMulticast () == true)
3447  {
3448  break; // Do not reply to broadcast or multicast
3449  }
3450  // Another case to suppress ICMP is a subnet-directed broadcast
3451  }
3452  return status;
3453  }
3454  else
3455  {
3456  NS_FATAL_ERROR ("Should not have 0 next protocol value");
3457  }
3458  }
3459  else
3460  {
3461  NS_LOG_INFO ("This is not the final destination, the packet has already been forward to next hop");
3462  }
3463  }
3464  }
3465  else
3466  {
3467  NS_LOG_LOGIC ("Unknown Option. Drop!");
3468  /*
3469  * Initialize the salvage value to 0
3470  */
3471  uint8_t salvage = 0;
3472 
3473  DsrOptionRerrUnsupportHeader rerrUnsupportHeader;
3474  rerrUnsupportHeader.SetErrorType (3); // The error type 3 means Option not supported
3475  rerrUnsupportHeader.SetErrorSrc (m_mainAddress); // The error source address is our own address
3476  rerrUnsupportHeader.SetUnsupported (optionType); // The unsupported option type number
3477  rerrUnsupportHeader.SetErrorDst (src); // Error destination address is the destination of the data packet
3478  rerrUnsupportHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
3479 
3480  /*
3481  * The unknown option error is not supported currently in this implementation, and it's also not likely to
3482  * happen in simulations
3483  */
3484 // SendError (rerrUnsupportHeader, 0, protocol); // Send the error packet
3485  }
3486  return IpL4Protocol::RX_OK;
3487 }
3488 
3491  Ipv6Header const &ip,
3492  Ptr<Ipv6Interface> incomingInterface)
3493 {
3494  NS_LOG_FUNCTION (this << p << ip.GetSourceAddress () << ip.GetDestinationAddress () << incomingInterface);
3496 }
3497 
3498 void
3500 {
3501  m_downTarget = callback;
3502 }
3503 
3504 void
3506 {
3507  NS_FATAL_ERROR ("Unimplemented");
3508 }
3509 
3510 
3513 {
3514  return m_downTarget;
3515 }
3516 
3519 {
3520  NS_FATAL_ERROR ("Unimplemented");
3521  return MakeNullCallback<void,Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route> > ();
3522 }
3523 
3525 {
3526  m_options.push_back (option);
3527 }
3528 
3530 {
3531  for (DsrOptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
3532  {
3533  if ((*i)->GetOptionNumber () == optionNumber)
3534  {
3535  return *i;
3536  }
3537  }
3538  return 0;
3539 }
3540 } /* namespace dsr */
3541 } /* namespace ns3 */
virtual Ipv4Address GetErrorSrc() const
Get the route error source address.
uint32_t m_sendRetries
of retries have been sent for network acknowledgment
Definition: dsr-routing.h:712
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.
Ptr< const AttributeChecker > MakeStringChecker(void)
Definition: string.cc:30
void SetDownTarget(IpL4Protocol::DownTargetCallback callback)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
uint32_t GetSize()
Returns the number of entries in the queue.
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:102
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
A simple 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
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
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:84
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.
uint32_t m_linkRetries
of retries have been sent for link acknowledgment
Definition: dsr-routing.h:716
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
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:204
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
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:280
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
void CancelPacketAllTimer(DsrMaintainBuffEntry &mb)
Cancel all the packet timers.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:743
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.
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
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.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
std::vector< Ipv4Address > m_finalRoute
The route cache.
Definition: dsr-routing.h: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
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.
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
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:220
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
DsrGraReply m_graReply
The gratuitous route reply.
Definition: dsr-routing.h:828
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:1124
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:309
void SendUnreachError(Ipv4Address unreachNode, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
This function is responsible for sending error packets in case of break link to next hop...
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:92
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.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
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
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:459
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 to verify that the event has already e...
Definition: timer.h:86
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:37
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...
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
uint32_t m_passiveRetries
of retries have been sent for passive acknowledgment
Definition: dsr-routing.h: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:187
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
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1578
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:1125
BlackList description.
L4 Protocol abstract base class.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
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.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
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.
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:89
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:40
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:863
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...
Introspection did not find any typical Config paths.
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:272
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:1062
Route Error (RERR) Unreachable node address option Message Format.
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
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)
Cancel the timer and save the amount of time left until it was set to expire.
Definition: timer.cc:177
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
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
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:1078
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:256
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
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:1270
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
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:915
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
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