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  pos2 = context.npos;
545  }
546  return elements;
547 }
548 
549 void
551 {
553  m_node = 0;
554  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
555  {
556  // Disable layer 2 link state monitoring (if possible)
557  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (i);
558  Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
559  if (wifi != 0)
560  {
561  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
562  if (mac != 0)
563  {
564  mac->TraceDisconnectWithoutContext ("TxErrHeader",
565  m_routeCache->GetTxErrorCallback ());
566  m_routeCache->DelArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
567  }
568  }
569  }
571 }
572 
573 void
575 {
576  m_node = node;
577 }
578 
579 Ptr<Node>
581 {
583  return m_node;
584 }
585 
587 {
588  // / Set the route cache to use
589  m_routeCache = r;
590 }
591 
594 {
595  // / Get the route cache to use
596  return m_routeCache;
597 }
598 
600 {
601  // / Set the request table to use
602  m_rreqTable = q;
603 }
604 
607 {
608  // / Get the request table to use
609  return m_rreqTable;
610 }
611 
613 {
614  // / Set the request table to use
615  m_passiveBuffer = p;
616 }
617 
620 {
621  // / Get the request table to use
622  return m_passiveBuffer;
623 }
624 
625 Ptr<Node>
627 {
628  NS_LOG_FUNCTION (this << ipv4Address);
629  int32_t nNodes = NodeList::GetNNodes ();
630  for (int32_t i = 0; i < nNodes; ++i)
631  {
632  Ptr<Node> node = NodeList::GetNode (i);
633  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
634  int32_t ifIndex = ipv4->GetInterfaceForAddress (ipv4Address);
635  if (ifIndex != -1)
636  {
637  return node;
638  }
639  }
640  return 0;
641 }
642 
644 {
645  return m_routeCache->IsLinkCache ();
646 }
647 
649 {
650  m_routeCache->UseExtends (rt);
651 }
652 
654 {
655  return m_routeCache->LookupRoute (id, rt);
656 }
657 
659 {
660  Ipv4Address nextHop = SearchNextHop (source, nodelist);
661  m_errorBuffer.DropPacketForErrLink (source, nextHop);
662  return m_routeCache->AddRoute_Link (nodelist, source);
663 }
664 
666 {
667  std::vector<Ipv4Address> nodelist = rt.GetVector ();
668  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodelist);
670  return m_routeCache->AddRoute (rt);
671 }
672 
674 {
675  m_routeCache->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, node);
676 }
677 
679 {
680  return m_routeCache->UpdateRouteEntry (dst);
681 }
682 
684 {
685  return m_rreqTable->FindSourceEntry (src, dst, id);
686 }
687 
690 {
691  NS_LOG_FUNCTION (this << address);
692  int32_t nNodes = NodeList::GetNNodes ();
693  for (int32_t i = 0; i < nNodes; ++i)
694  {
695  Ptr<Node> node = NodeList::GetNode (i);
696  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
697  Ptr<NetDevice> netDevice = ipv4->GetNetDevice (1);
698 
699  if (netDevice->GetAddress () == address)
700  {
701  return ipv4->GetAddress (1, 0).GetLocal ();
702  }
703  }
704  return 0;
705 }
706 
707 void DsrRouting::PrintVector (std::vector<Ipv4Address>& vec)
708 {
709  NS_LOG_FUNCTION (this);
710  /*
711  * Check elements in a route vector
712  */
713  if (!vec.size ())
714  {
715  NS_LOG_DEBUG ("The vector is empty");
716  }
717  else
718  {
719  NS_LOG_DEBUG ("Print all the elements in a vector");
720  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
721  {
722  NS_LOG_DEBUG ("The ip address " << *i);
723  }
724  }
725 }
726 
727 Ipv4Address DsrRouting::SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
728 {
729  NS_LOG_FUNCTION (this << ipv4Address);
730  Ipv4Address nextHop;
731  NS_LOG_DEBUG ("the vector size " << vec.size ());
732  if (vec.size () == 2)
733  {
734  NS_LOG_DEBUG ("The two nodes are neighbors");
735  nextHop = vec[1];
736  return nextHop;
737  }
738  else
739  {
740  if (ipv4Address == vec.back ())
741  {
742  NS_LOG_DEBUG ("We have reached to the final destination " << ipv4Address << " " << vec.back ());
743  return ipv4Address;
744  }
745  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
746  {
747  if (ipv4Address == (*i))
748  {
749  nextHop = *(++i);
750  return nextHop;
751  }
752  }
753  }
754  NS_LOG_DEBUG ("Next hop address not found");
755  Ipv4Address none = "0.0.0.0";
756  return none;
757 }
758 
761 {
762  NS_LOG_FUNCTION (this << nextHop << srcAddress);
763  m_ipv4Route = Create<Ipv4Route> ();
764  m_ipv4Route->SetDestination (nextHop);
765  m_ipv4Route->SetGateway (nextHop);
766  m_ipv4Route->SetSource (srcAddress);
767  return m_ipv4Route;
768 }
769 
770 int
772 {
773  // / This is the protocol number for DSR which is 48
774  return PROT_NUMBER;
775 }
776 
777 uint16_t
779 {
780  int32_t nNodes = NodeList::GetNNodes ();
781  for (int32_t i = 0; i < nNodes; ++i)
782  {
783  Ptr<Node> node = NodeList::GetNode (i);
784  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
785  if (ipv4->GetAddress (1, 0).GetLocal () == address)
786  {
787  return uint16_t (i);
788  }
789  }
790  return 256;
791 }
792 
795 {
796  if (id >= 256)
797  {
798  NS_LOG_DEBUG ("Exceed the node range");
799  return "0.0.0.0";
800  }
801  else
802  {
803  Ptr<Node> node = NodeList::GetNode (uint32_t (id));
804  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
805  return ipv4->GetAddress (1, 0).GetLocal ();
806  }
807 }
808 
809 uint32_t
811 {
812  if (messageType == DSR_CONTROL_PACKET)
813  {
814  return 0;
815  }
816  else
817  {
818  return 1;
819  }
820 }
821 
823 {
824  if (m_sendBuffTimer.IsRunning ())
825  {
827  }
829  CheckSendBuffer ();
830 }
831 
833 {
834  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
835  << " Checking send buffer at " << m_mainAddress << " with size " << m_sendBuffer.GetSize ());
836 
837  for (std::vector<DsrSendBuffEntry>::iterator i = m_sendBuffer.GetBuffer ().begin (); i != m_sendBuffer.GetBuffer ().end (); )
838  {
839  NS_LOG_DEBUG ("Here we try to find the data packet in the send buffer");
840  Ipv4Address destination = i->GetDestination ();
841  DsrRouteCacheEntry toDst;
842  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
843  if (findRoute)
844  {
845  NS_LOG_INFO ("We have found a route for the packet");
846  Ptr<const Packet> packet = i->GetPacket ();
847  Ptr<Packet> cleanP = packet->Copy ();
848  uint8_t protocol = i->GetProtocol ();
849 
850  i = m_sendBuffer.GetBuffer ().erase (i);
851 
852  DsrRoutingHeader dsrRoutingHeader;
853  Ptr<Packet> copyP = packet->Copy ();
854  Ptr<Packet> dsrPacket = packet->Copy ();
855  dsrPacket->RemoveHeader (dsrRoutingHeader);
856  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
857  copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
858  // The packet to get ipv4 header
859  Ptr<Packet> ipv4P = copyP->Copy ();
860  /*
861  * Peek data to get the option type as well as length and segmentsLeft field
862  */
863  uint32_t size = copyP->GetSize ();
864  uint8_t *data = new uint8_t[size];
865  copyP->CopyData (data, size);
866 
867  uint8_t optionType = 0;
868  optionType = *(data);
869 
870  if (optionType == 3)
871  {
872  Ptr<dsr::DsrOptions> dsrOption;
873  DsrOptionHeader dsrOptionHeader;
874  uint8_t errorType = *(data + 2);
875 
876  if (errorType == 1) // This is the Route Error Option
877  {
879  copyP->RemoveHeader (rerr);
880  NS_ASSERT (copyP->GetSize () == 0);
881 
882  DsrOptionRerrUnreachHeader newUnreach;
883  newUnreach.SetErrorType (1);
884  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
885  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
886  newUnreach.SetErrorDst (rerr.GetErrorDst ());
887  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
888 
889  DsrOptionSRHeader sourceRoute;
890  std::vector<Ipv4Address> errorRoute = toDst.GetVector ();
891  sourceRoute.SetNodesAddress (errorRoute);
893  if (m_routeCache->IsLinkCache ())
894  {
895  m_routeCache->UseExtends (errorRoute);
896  }
897  sourceRoute.SetSegmentsLeft ((errorRoute.size () - 2));
898  uint8_t salvage = 0;
899  sourceRoute.SetSalvage (salvage);
900  Ipv4Address nextHop = SearchNextHop (m_mainAddress, errorRoute); // Get the next hop address
901 
902  if (nextHop == "0.0.0.0")
903  {
904  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
905  return;
906  }
907 
908  SetRoute (nextHop, m_mainAddress);
909  uint8_t length = (sourceRoute.GetLength () + newUnreach.GetLength ());
910  dsrRoutingHeader.SetNextHeader (protocol);
911  dsrRoutingHeader.SetMessageType (1);
912  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
913  dsrRoutingHeader.SetDestId (255);
914  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
915  dsrRoutingHeader.AddDsrOption (newUnreach);
916  dsrRoutingHeader.AddDsrOption (sourceRoute);
917 
918  Ptr<Packet> newPacket = Create<Packet> ();
919  newPacket->AddHeader (dsrRoutingHeader); // Add the routing header with rerr and sourceRoute attached to it
920  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
922 
923  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
924  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
925  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
926  NS_LOG_LOGIC ("Will be inserting into priority queue number: " << priority);
927 
928  //m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
929 
931  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
932 
933  if (dsrNetworkQueue->Enqueue (newEntry))
934  {
935  Scheduler (priority);
936  }
937  else
938  {
939  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
940  }
941  }
942  }
943  else
944  {
945  dsrRoutingHeader.SetNextHeader (protocol);
946  dsrRoutingHeader.SetMessageType (2);
947  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
948  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
949 
950  DsrOptionSRHeader sourceRoute;
951  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
952  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
953  if (nextHop == "0.0.0.0")
954  {
955  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
956  return;
957  }
958  uint8_t salvage = 0;
959  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
960  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
961  sourceRoute.SetSalvage (salvage);
963  if (m_routeCache->IsLinkCache ())
964  {
965  m_routeCache->UseExtends (nodeList);
966  }
967  uint8_t length = sourceRoute.GetLength ();
968  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
969  dsrRoutingHeader.AddDsrOption (sourceRoute);
970  cleanP->AddHeader (dsrRoutingHeader);
971  Ptr<const Packet> mtP = cleanP->Copy ();
972  // Put the data packet in the maintenance queue for data packet retransmission
973  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
974  /*source=*/ m_mainAddress, /*destination=*/ destination, /*ackId=*/ 0,
975  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
976  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
977  if (result)
978  {
979  NetworkKey networkKey;
980  networkKey.m_ackId = newEntry.GetAckId ();
981  networkKey.m_ourAdd = newEntry.GetOurAdd ();
982  networkKey.m_nextHop = newEntry.GetNextHop ();
983  networkKey.m_source = newEntry.GetSrc ();
984  networkKey.m_destination = newEntry.GetDst ();
985 
986  PassiveKey passiveKey;
987  passiveKey.m_ackId = 0;
988  passiveKey.m_source = newEntry.GetSrc ();
989  passiveKey.m_destination = newEntry.GetDst ();
990  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
991 
992  LinkKey linkKey;
993  linkKey.m_source = newEntry.GetSrc ();
994  linkKey.m_destination = newEntry.GetDst ();
995  linkKey.m_ourAdd = newEntry.GetOurAdd ();
996  linkKey.m_nextHop = newEntry.GetNextHop ();
997 
998  m_addressForwardCnt[networkKey] = 0;
999  m_passiveCnt[passiveKey] = 0;
1000  m_linkCnt[linkKey] = 0;
1001 
1002  if (m_linkAck)
1003  {
1004  ScheduleLinkPacketRetry (newEntry, protocol);
1005  }
1006  else
1007  {
1008  NS_LOG_LOGIC ("Not using link acknowledgment");
1009  if (nextHop != destination)
1010  {
1011  SchedulePassivePacketRetry (newEntry, protocol);
1012  }
1013  else
1014  {
1015  // This is the first network retry
1016  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1017  }
1018  }
1019  }
1020  // we need to suspend the normal timer that checks the send buffer
1021  // until we are done sending packets
1022  if (!m_sendBuffTimer.IsSuspended ())
1023  {
1025  }
1027  return;
1028  }
1029  }
1030  else
1031  {
1032  ++i;
1033  }
1034  }
1035  //after going through the entire send buffer and send all packets found route,
1036  //we need to resume the timer if it has been suspended
1038  {
1039  NS_LOG_DEBUG ("Resume the send buffer timer");
1041  }
1042 }
1043 
1044 bool DsrRouting::PromiscReceive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &from,
1045  const Address &to, NetDevice::PacketType packetType)
1046 {
1047 
1048  if (protocol != Ipv4L3Protocol::PROT_NUMBER)
1049  {
1050  return false;
1051  }
1052  // Remove the ipv4 header here
1053  Ptr<Packet> pktMinusIpHdr = packet->Copy ();
1054  Ipv4Header ipv4Header;
1055  pktMinusIpHdr->RemoveHeader(ipv4Header);
1056 
1057  if (ipv4Header.GetProtocol () != DsrRouting::PROT_NUMBER)
1058  {
1059  return false;
1060  }
1061  // Remove the dsr routing header here
1062  Ptr<Packet> pktMinusDsrHdr = pktMinusIpHdr->Copy ();
1063  DsrRoutingHeader dsrRouting;
1064  pktMinusDsrHdr->RemoveHeader (dsrRouting);
1065 
1066  /*
1067  * Message type 2 means the data packet, we will further process the data
1068  * packet for delivery notification, safely ignore control packet
1069  * Another check here is our own address, if this is the data destinated for us,
1070  * process it further, otherwise, just ignore it
1071  */
1072  Ipv4Address ourAddress = m_ipv4->GetAddress (1, 0).GetLocal ();
1073  // check if the message type is 2 and if the ipv4 address matches
1074  if (dsrRouting.GetMessageType () == 2 && ourAddress == m_mainAddress)
1075  {
1076  NS_LOG_DEBUG ("data packet receives " << packet->GetUid ());
1077  Ipv4Address sourceIp = GetIPfromID (dsrRouting.GetSourceId ());
1078  Ipv4Address destinationIp = GetIPfromID ( dsrRouting.GetDestId ());
1080  Ipv4Address previousHop = GetIPfromMAC (Mac48Address::ConvertFrom (from));
1081 
1082  Ptr<Packet> p = Create<Packet> ();
1083  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
1084  DsrMaintainBuffEntry newEntry;
1085  newEntry.SetPacket (p);
1086  newEntry.SetSrc (sourceIp);
1087  newEntry.SetDst (destinationIp);
1089  newEntry.SetOurAdd (previousHop);
1090  newEntry.SetNextHop (ourAddress);
1092  Ptr<Node> node = GetNodeWithAddress (previousHop);
1093  NS_LOG_DEBUG ("The previous node " << previousHop);
1094 
1096  dsr->CancelLinkPacketTimer (newEntry);
1097  }
1098 
1099  // Receive only IP packets and packets destined for other hosts
1100  if (packetType == NetDevice::PACKET_OTHERHOST)
1101  {
1102  //just to minimize debug output
1103  NS_LOG_INFO (this << from << to << packetType << *pktMinusIpHdr);
1104 
1105  uint8_t offset = dsrRouting.GetDsrOptionsOffset (); // Get the offset for option header, 4 bytes in this case
1106  uint8_t nextHeader = dsrRouting.GetNextHeader ();
1107  uint32_t sourceId = dsrRouting.GetSourceId ();
1108  Ipv4Address source = GetIPfromID (sourceId);
1109 
1110  // This packet is used to peek option type
1111  pktMinusIpHdr->RemoveAtStart (offset);
1112  /*
1113  * Peek data to get the option type as well as length and segmentsLeft field
1114  */
1115  uint32_t size = pktMinusIpHdr->GetSize ();
1116  uint8_t *data = new uint8_t[size];
1117  pktMinusIpHdr->CopyData (data, size);
1118  uint8_t optionType = 0;
1119  optionType = *(data);
1120 
1121  Ptr<dsr::DsrOptions> dsrOption;
1122 
1123  if (optionType == 96) // This is the source route option
1124  {
1125  Ipv4Address promiscSource = GetIPfromMAC (Mac48Address::ConvertFrom (from));
1126  dsrOption = GetOption (optionType); // Get the relative DSR option and demux to the process function
1127  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () <<
1128  " DSR node " << m_mainAddress <<
1129  " overhearing packet PID: " << pktMinusIpHdr->GetUid () <<
1130  " from " << promiscSource <<
1131  " to " << GetIPfromMAC (Mac48Address::ConvertFrom (to)) <<
1132  " with source IP " << ipv4Header.GetSource () <<
1133  " and destination IP " << ipv4Header.GetDestination () <<
1134  " and packet : " << *pktMinusDsrHdr);
1135 
1136  bool isPromisc = true; // Set the boolean value isPromisc as true
1137  dsrOption->Process (pktMinusIpHdr, pktMinusDsrHdr, m_mainAddress, source, ipv4Header, nextHeader, isPromisc, promiscSource);
1138  return true;
1139 
1140  }
1141  }
1142  return false;
1143 }
1144 
1145 void
1147  Ipv4Address source,
1148  Ipv4Address destination,
1149  uint8_t protocol)
1150 {
1151  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol);
1152  // Look up routes for the specific destination
1153  DsrRouteCacheEntry toDst;
1154  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1155  // Queue the packet if there is no route pre-existing
1156  if (!findRoute)
1157  {
1158  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1159  << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
1160 
1161  Ptr<Packet> p = packet->Copy ();
1162  DsrSendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol); // Create a new entry for send buffer
1163  bool result = m_sendBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1164  if (result)
1165  {
1166  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1167  << "s Add packet PID: " << packet->GetUid () << " to queue. Packet: " << *packet);
1168 
1169  NS_LOG_LOGIC ("Send RREQ to" << destination);
1170  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1171  {
1172  /*
1173  * Call the send request function, it will update the request table entry and ttl there
1174  */
1175  SendInitialRequest (source, destination, protocol);
1176  }
1177  }
1178  }
1179  else
1180  {
1181  Ptr<Packet> cleanP = packet->Copy ();
1182  DsrRoutingHeader dsrRoutingHeader;
1183  dsrRoutingHeader.SetNextHeader (protocol);
1184  dsrRoutingHeader.SetMessageType (2);
1185  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1186  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1187 
1188  DsrOptionSRHeader sourceRoute;
1189  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1190  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1191  if (nextHop == "0.0.0.0")
1192  {
1193  PacketNewRoute (cleanP, source, destination, protocol);
1194  return;
1195  }
1196  uint8_t salvage = 0;
1197  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
1199  if (m_routeCache->IsLinkCache ())
1200  {
1201  m_routeCache->UseExtends (nodeList);
1202  }
1203  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
1204  sourceRoute.SetSalvage (salvage);
1205 
1206  uint8_t length = sourceRoute.GetLength ();
1207  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1208  dsrRoutingHeader.AddDsrOption (sourceRoute);
1209  cleanP->AddHeader (dsrRoutingHeader);
1210  Ptr<const Packet> mtP = cleanP->Copy ();
1211  SetRoute (nextHop, m_mainAddress);
1212  // Put the data packet in the maintenance queue for data packet retransmission
1213  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
1214  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1215  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1216  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1217 
1218  if (result)
1219  {
1220  NetworkKey networkKey;
1221  networkKey.m_ackId = newEntry.GetAckId ();
1222  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1223  networkKey.m_nextHop = newEntry.GetNextHop ();
1224  networkKey.m_source = newEntry.GetSrc ();
1225  networkKey.m_destination = newEntry.GetDst ();
1226 
1227  PassiveKey passiveKey;
1228  passiveKey.m_ackId = 0;
1229  passiveKey.m_source = newEntry.GetSrc ();
1230  passiveKey.m_destination = newEntry.GetDst ();
1231  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1232 
1233  LinkKey linkKey;
1234  linkKey.m_source = newEntry.GetSrc ();
1235  linkKey.m_destination = newEntry.GetDst ();
1236  linkKey.m_ourAdd = newEntry.GetOurAdd ();
1237  linkKey.m_nextHop = newEntry.GetNextHop ();
1238 
1239  m_addressForwardCnt[networkKey] = 0;
1240  m_passiveCnt[passiveKey] = 0;
1241  m_linkCnt[linkKey] = 0;
1242 
1243  if (m_linkAck)
1244  {
1245  ScheduleLinkPacketRetry (newEntry, protocol);
1246  }
1247  else
1248  {
1249  NS_LOG_LOGIC ("Not using link acknowledgment");
1250  if (nextHop != destination)
1251  {
1252  SchedulePassivePacketRetry (newEntry, protocol);
1253  }
1254  else
1255  {
1256  // This is the first network retry
1257  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1258  }
1259  }
1260  }
1261  }
1262 }
1263 
1264 void
1265 DsrRouting::SendUnreachError (Ipv4Address unreachNode, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
1266 {
1267  NS_LOG_FUNCTION (this << unreachNode << destination << originalDst << (uint32_t)salvage << (uint32_t)protocol);
1268  DsrRoutingHeader dsrRoutingHeader;
1269  dsrRoutingHeader.SetNextHeader (protocol);
1270  dsrRoutingHeader.SetMessageType (1);
1271  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
1272  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1273 
1274  DsrOptionRerrUnreachHeader rerrUnreachHeader;
1275  rerrUnreachHeader.SetErrorType (1);
1276  rerrUnreachHeader.SetErrorSrc (m_mainAddress);
1277  rerrUnreachHeader.SetUnreachNode (unreachNode);
1278  rerrUnreachHeader.SetErrorDst (destination);
1279  rerrUnreachHeader.SetOriginalDst (originalDst);
1280  rerrUnreachHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
1281  uint8_t rerrLength = rerrUnreachHeader.GetLength ();
1282 
1283 
1284  DsrRouteCacheEntry toDst;
1285  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1286  // Queue the packet if there is no route pre-existing
1287  Ptr<Packet> newPacket = Create<Packet> ();
1288  if (!findRoute)
1289  {
1290  if (destination == m_mainAddress)
1291  {
1292  NS_LOG_INFO ("We are the error source, send request to original dst " << originalDst);
1293  // Send error request message if we are the source node
1294  SendErrorRequest (rerrUnreachHeader, protocol);
1295  }
1296  else
1297  {
1298  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1299  << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
1300 
1301  dsrRoutingHeader.SetPayloadLength (rerrLength + 2);
1302  dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
1303  newPacket->AddHeader (dsrRoutingHeader);
1304  Ptr<Packet> p = newPacket->Copy ();
1305  // Save the error packet in the error buffer
1306  DsrErrorBuffEntry newEntry (p, destination, m_mainAddress, unreachNode, m_sendBufferTimeout, protocol);
1307  bool result = m_errorBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1308  if (result)
1309  {
1310  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1311  << "s Add packet PID: " << p->GetUid () << " to queue. Packet: " << *p);
1312  NS_LOG_LOGIC ("Send RREQ to" << destination);
1313  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1314  {
1315  NS_LOG_DEBUG ("When there is no existing route request for " << destination << ", initialize one");
1316  /*
1317  * Call the send request function, it will update the request table entry and ttl there
1318  */
1319  SendInitialRequest (m_mainAddress, destination, protocol);
1320  }
1321  }
1322  }
1323  }
1324  else
1325  {
1326  std::vector<Ipv4Address> nodeList = toDst.GetVector ();
1327  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);
1328  if (nextHop == "0.0.0.0")
1329  {
1330  NS_LOG_DEBUG ("The route is not right");
1331  PacketNewRoute (newPacket, m_mainAddress, destination, protocol);
1332  return;
1333  }
1334  DsrOptionSRHeader sourceRoute;
1335  sourceRoute.SetNodesAddress (nodeList);
1337  if (m_routeCache->IsLinkCache ())
1338  {
1339  m_routeCache->UseExtends (nodeList);
1340  }
1341  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));
1342  uint8_t srLength = sourceRoute.GetLength ();
1343  uint8_t length = (srLength + rerrLength);
1344 
1345  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1346  dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
1347  dsrRoutingHeader.AddDsrOption (sourceRoute);
1348  newPacket->AddHeader (dsrRoutingHeader);
1349 
1350  SetRoute (nextHop, m_mainAddress);
1351  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1353  NS_LOG_INFO ("Send the packet to the next hop address " << nextHop << " from " << m_mainAddress << " with the size " << newPacket->GetSize ());
1354 
1355  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1356  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1357  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1358  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1359 
1360  //m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1361 
1363  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
1364 
1365  if (dsrNetworkQueue->Enqueue (newEntry))
1366  {
1367  Scheduler (priority);
1368  }
1369  else
1370  {
1371  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1372  }
1373  }
1374 }
1375 
1376 void
1378  DsrOptionSRHeader &sourceRoute,
1379  Ipv4Address nextHop,
1380  uint8_t protocol,
1381  Ptr<Ipv4Route> route)
1382 {
1383  NS_LOG_FUNCTION (this << rerr << sourceRoute << nextHop << (uint32_t)protocol << route);
1384  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1385  DsrRoutingHeader dsrRoutingHeader;
1386  dsrRoutingHeader.SetNextHeader (protocol);
1387  dsrRoutingHeader.SetMessageType (1);
1388  dsrRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
1389  dsrRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
1390 
1391  uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
1392  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1393  dsrRoutingHeader.AddDsrOption (rerr);
1394  dsrRoutingHeader.AddDsrOption (sourceRoute);
1395  Ptr<Packet> packet = Create<Packet> ();
1396  packet->AddHeader (dsrRoutingHeader);
1397  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1398  route->SetOutputDevice (dev);
1399 
1400  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1401  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1402  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1403  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1404 
1405  //m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
1406 
1408  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, nextHop, Simulator::Now (), route);
1409 
1410  if (dsrNetworkQueue->Enqueue (newEntry))
1411  {
1412  Scheduler (priority);
1413  }
1414  else
1415  {
1416  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1417  }
1418 }
1419 
1420 void
1422  Ipv4Address source,
1423  Ipv4Address destination,
1424  uint8_t protocol,
1425  Ptr<Ipv4Route> route)
1426 {
1427  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
1428  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1429 
1430  if (protocol == 1)
1431  {
1432  NS_LOG_INFO ("Drop packet. Not handling ICMP packet for now");
1433  }
1434  else
1435  {
1436  // Look up routes for the specific destination
1437  DsrRouteCacheEntry toDst;
1438  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1439  // Queue the packet if there is no route pre-existing
1440  if (!findRoute)
1441  {
1442  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1443  << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
1444 
1445  Ptr<Packet> p = packet->Copy ();
1446  DsrSendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol); // Create a new entry for send buffer
1447  bool result = m_sendBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1448  if (result)
1449  {
1450  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1451  << "s Add packet PID: " << packet->GetUid () << " to send buffer. Packet: " << *packet);
1452  // Only when there is no existing route request timer when new route request is scheduled
1453  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1454  {
1455  /*
1456  * Call the send request function, it will update the request table entry and ttl value
1457  */
1458  NS_LOG_LOGIC ("Send initial RREQ to " << destination);
1459  SendInitialRequest (source, destination, protocol);
1460  }
1461  else
1462  {
1463  NS_LOG_LOGIC ("There is existing route request timer with request count " << m_rreqTable->GetRreqCnt (destination));
1464  }
1465  }
1466  }
1467  else
1468  {
1469  Ptr<Packet> cleanP = packet->Copy ();
1470  DsrRoutingHeader dsrRoutingHeader;
1471  dsrRoutingHeader.SetNextHeader (protocol);
1472  dsrRoutingHeader.SetMessageType (2);
1473  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1474  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1475 
1476  DsrOptionSRHeader sourceRoute;
1477  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1478  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1479  if (nextHop == "0.0.0.0")
1480  {
1481  PacketNewRoute (cleanP, source, destination, protocol);
1482  return;
1483  }
1484  uint8_t salvage = 0;
1485  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
1487  if (m_routeCache->IsLinkCache ())
1488  {
1489  m_routeCache->UseExtends (nodeList);
1490  }
1491  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
1492  sourceRoute.SetSalvage (salvage);
1493 
1494  uint8_t length = sourceRoute.GetLength ();
1495 
1496  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1497  dsrRoutingHeader.AddDsrOption (sourceRoute);
1498  cleanP->AddHeader (dsrRoutingHeader);
1499 
1500  Ptr<const Packet> mtP = cleanP->Copy ();
1501  NS_LOG_DEBUG ("maintain packet size " << cleanP->GetSize ());
1502  // Put the data packet in the maintenance queue for data packet retransmission
1503  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
1504  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1505  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1506  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1507  if (result)
1508  {
1509  NetworkKey networkKey;
1510  networkKey.m_ackId = newEntry.GetAckId ();
1511  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1512  networkKey.m_nextHop = newEntry.GetNextHop ();
1513  networkKey.m_source = newEntry.GetSrc ();
1514  networkKey.m_destination = newEntry.GetDst ();
1515 
1516  PassiveKey passiveKey;
1517  passiveKey.m_ackId = 0;
1518  passiveKey.m_source = newEntry.GetSrc ();
1519  passiveKey.m_destination = newEntry.GetDst ();
1520  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1521 
1522  LinkKey linkKey;
1523  linkKey.m_source = newEntry.GetSrc ();
1524  linkKey.m_destination = newEntry.GetDst ();
1525  linkKey.m_ourAdd = newEntry.GetOurAdd ();
1526  linkKey.m_nextHop = newEntry.GetNextHop ();
1527 
1528  m_addressForwardCnt[networkKey] = 0;
1529  m_passiveCnt[passiveKey] = 0;
1530  m_linkCnt[linkKey] = 0;
1531 
1532  if (m_linkAck)
1533  {
1534  ScheduleLinkPacketRetry (newEntry, protocol);
1535  }
1536  else
1537  {
1538  NS_LOG_LOGIC ("Not using link acknowledgment");
1539  if (nextHop != destination)
1540  {
1541  SchedulePassivePacketRetry (newEntry, protocol);
1542  }
1543  else
1544  {
1545  // This is the first network retry
1546  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1547  }
1548  }
1549  }
1550 
1551  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
1552  {
1553  // Try to send packet from *previously* queued entries from send buffer if any
1555  &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
1556  }
1557  }
1558  }
1559 }
1560 
1561 uint16_t
1563 {
1564  NS_LOG_FUNCTION (this << packet << nextHop);
1565  // This packet is used to peek option type
1566  Ptr<Packet> dsrP = packet->Copy ();
1567  Ptr<Packet> tmpP = packet->Copy ();
1568 
1569  DsrRoutingHeader dsrRoutingHeader;
1570  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
1571  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
1572  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
1573  uint32_t destinationId = dsrRoutingHeader.GetDestId ();
1574  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1575  tmpP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1576 
1577  // Get the number of routers' address field
1578  uint8_t buf[2];
1579  tmpP->CopyData (buf, sizeof(buf));
1580  uint8_t numberAddress = (buf[1] - 2) / 4;
1581  DsrOptionSRHeader sourceRoute;
1582  sourceRoute.SetNumberAddress (numberAddress);
1583  tmpP->RemoveHeader (sourceRoute); // this is a clean packet without any dsr involved headers
1584 
1585  DsrOptionAckReqHeader ackReq;
1586  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
1587  ackReq.SetAckId (m_ackId);
1588  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
1589  DsrRoutingHeader newDsrRoutingHeader;
1590  newDsrRoutingHeader.SetNextHeader (protocol);
1591  newDsrRoutingHeader.SetMessageType (2);
1592  newDsrRoutingHeader.SetSourceId (sourceId);
1593  newDsrRoutingHeader.SetDestId (destinationId);
1594  newDsrRoutingHeader.SetPayloadLength (length + 4);
1595  newDsrRoutingHeader.AddDsrOption (sourceRoute);
1596  newDsrRoutingHeader.AddDsrOption (ackReq);
1597  dsrP->AddHeader (newDsrRoutingHeader);
1598  // give the dsrP value to packet and then return
1599  packet = dsrP;
1600  return m_ackId;
1601 }
1602 
1603 void
1604 DsrRouting::SendPacket (Ptr<Packet> packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol)
1605 {
1606  NS_LOG_FUNCTION (this << packet << source << nextHop << (uint32_t)protocol);
1607  // Send out the data packet
1608  m_ipv4Route = SetRoute (nextHop, m_mainAddress);
1609  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1611 
1612  uint32_t priority = GetPriority (DSR_DATA_PACKET);
1613  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1614  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1615  NS_LOG_INFO ("Will be inserting into priority queue number: " << priority);
1616 
1617  //m_downTarget (packet, source, nextHop, GetProtocolNumber (), m_ipv4Route);
1618 
1620  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), m_ipv4Route);
1621 
1622  if (dsrNetworkQueue->Enqueue (newEntry))
1623  {
1624  Scheduler (priority);
1625  }
1626  else
1627  {
1628  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1629  }
1630 }
1631 
1632 void
1633 DsrRouting::Scheduler (uint32_t priority)
1634 {
1635  NS_LOG_FUNCTION (this);
1636  PriorityScheduler (priority, true);
1637 }
1638 
1639 void
1640 DsrRouting::PriorityScheduler (uint32_t priority, bool continueWithFirst)
1641 {
1642  NS_LOG_FUNCTION (this << priority << continueWithFirst);
1643  uint32_t numPriorities;
1644  if (continueWithFirst)
1645  {
1646  numPriorities = 0;
1647  }
1648  else
1649  {
1650  numPriorities = priority;
1651  }
1652  // priorities ranging from 0 to m_numPriorityQueues, with 0 as the highest priority
1653  for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
1654  {
1655  std::map<uint32_t, Ptr<DsrNetworkQueue> >::iterator q = m_priorityQueue.find (i);
1656  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
1657  uint32_t queueSize = dsrNetworkQueue->GetSize ();
1658  if (queueSize == 0)
1659  {
1660  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1661  {
1662  i = 0;
1663  }
1664  else
1665  {
1666  i++;
1667  }
1668  }
1669  else
1670  {
1671  uint32_t totalQueueSize = 0;
1672  for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator j = m_priorityQueue.begin (); j != m_priorityQueue.end (); j++)
1673  {
1674  NS_LOG_INFO ("The size of the network queue for " << j->first << " is " << j->second->GetSize ());
1675  totalQueueSize += j->second->GetSize ();
1676  NS_LOG_INFO ("The total network queue size is " << totalQueueSize);
1677  }
1678  if (totalQueueSize > 5)
1679  {
1680  // Here the queue size is larger than 5, we need to increase the retransmission timer for each packet in the network queue
1682  }
1683  DsrNetworkQueueEntry newEntry;
1684  dsrNetworkQueue->Dequeue (newEntry);
1685  if (SendRealDown (newEntry))
1686  {
1687  NS_LOG_LOGIC ("Packet sent by Dsr. Calling PriorityScheduler after some time");
1688  // packet was successfully sent down. call scheduler after some time
1690  &DsrRouting::PriorityScheduler,this, i, false);
1691  }
1692  else
1693  {
1694  // packet was dropped by Dsr. Call scheduler immediately so that we can
1695  // send another packet immediately.
1696  NS_LOG_LOGIC ("Packet dropped by Dsr. Calling PriorityScheduler immediately");
1698  }
1699 
1700  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1701  {
1702  i = 0;
1703  }
1704  else
1705  {
1706  i++;
1707  }
1708  }
1709  }
1710 }
1711 
1712 void
1714 {
1715  NS_LOG_FUNCTION (this);
1716  // We may want to get the queue first and then we need to save a vector of the entries here and then find
1717  uint32_t priority = GetPriority (DSR_DATA_PACKET);
1718  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1719  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1720 
1721  std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue ();
1722  for (std::vector<DsrNetworkQueueEntry>::iterator i = newNetworkQueue.begin (); i != newNetworkQueue.end (); i++)
1723  {
1724  Ipv4Address nextHop = i->GetNextHopAddress ();
1725  for (std::map<NetworkKey, Timer>::iterator j = m_addressForwardTimer.begin (); j != m_addressForwardTimer.end (); j++)
1726  {
1727  if (nextHop == j->first.m_nextHop)
1728  {
1729  NS_LOG_DEBUG ("The network delay left is " << j->second.GetDelayLeft ());
1730  j->second.SetDelay (j->second.GetDelayLeft () + m_retransIncr);
1731  }
1732  }
1733  }
1734 }
1735 
1736 bool
1738 {
1739  NS_LOG_FUNCTION (this);
1740  Ipv4Address source = newEntry.GetSourceAddress ();
1741  Ipv4Address nextHop = newEntry.GetNextHopAddress ();
1742  Ptr<Packet> packet = newEntry.GetPacket ()->Copy ();
1743  Ptr<Ipv4Route> route = newEntry.GetIpv4Route ();
1744  m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
1745  return true;
1746 }
1747 
1748 void
1749 DsrRouting::SendPacketFromBuffer (DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop, uint8_t protocol)
1750 {
1751  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
1752  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1753 
1754  // Reconstruct the route and Retransmit the data packet
1755  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1756  Ipv4Address destination = nodeList.back ();
1757  Ipv4Address source = nodeList.front (); // Get the source address
1758  NS_LOG_INFO ("The nexthop address " << nextHop << " the source " << source << " the destination " << destination);
1759  /*
1760  * Here we try to find data packet from send buffer, if packet with this destination found, send it out
1761  */
1762  if (m_sendBuffer.Find (destination))
1763  {
1764  NS_LOG_DEBUG ("destination over here " << destination);
1765 
1767  if (m_routeCache->IsLinkCache ())
1768  {
1769  m_routeCache->UseExtends (nodeList);
1770  }
1771  DsrSendBuffEntry entry;
1772  if (m_sendBuffer.Dequeue (destination, entry))
1773  {
1774  Ptr<Packet> packet = entry.GetPacket ()->Copy ();
1775  Ptr<Packet> p = packet->Copy (); // get a copy of the packet
1776  // Set the source route option
1777  DsrRoutingHeader dsrRoutingHeader;
1778  dsrRoutingHeader.SetNextHeader (protocol);
1779  dsrRoutingHeader.SetMessageType (2);
1780  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1781  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1782 
1783  uint8_t length = sourceRoute.GetLength ();
1784  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1785  dsrRoutingHeader.AddDsrOption (sourceRoute);
1786 
1787  p->AddHeader (dsrRoutingHeader);
1788 
1789  Ptr<const Packet> mtP = p->Copy ();
1790  // Put the data packet in the maintenance queue for data packet retransmission
1791  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
1792  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1793  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1794  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1795 
1796  if (result)
1797  {
1798  NetworkKey networkKey;
1799  networkKey.m_ackId = newEntry.GetAckId ();
1800  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1801  networkKey.m_nextHop = newEntry.GetNextHop ();
1802  networkKey.m_source = newEntry.GetSrc ();
1803  networkKey.m_destination = newEntry.GetDst ();
1804 
1805  PassiveKey passiveKey;
1806  passiveKey.m_ackId = 0;
1807  passiveKey.m_source = newEntry.GetSrc ();
1808  passiveKey.m_destination = newEntry.GetDst ();
1809  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1810 
1811  LinkKey linkKey;
1812  linkKey.m_source = newEntry.GetSrc ();
1813  linkKey.m_destination = newEntry.GetDst ();
1814  linkKey.m_ourAdd = newEntry.GetOurAdd ();
1815  linkKey.m_nextHop = newEntry.GetNextHop ();
1816 
1817  m_addressForwardCnt[networkKey] = 0;
1818  m_passiveCnt[passiveKey] = 0;
1819  m_linkCnt[linkKey] = 0;
1820 
1821  if (m_linkAck)
1822  {
1823  ScheduleLinkPacketRetry (newEntry, protocol);
1824  }
1825  else
1826  {
1827  NS_LOG_LOGIC ("Not using link acknowledgment");
1828  if (nextHop != destination)
1829  {
1830  SchedulePassivePacketRetry (newEntry, protocol);
1831  }
1832  else
1833  {
1834  // This is the first network retry
1835  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1836  }
1837  }
1838  }
1839 
1840  NS_LOG_DEBUG ("send buffer size here and the destination " << m_sendBuffer.GetSize() << " " << destination);
1841  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
1842  {
1843  NS_LOG_LOGIC ("Schedule sending the next packet in send buffer");
1845  &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
1846  }
1847  }
1848  else
1849  {
1850  NS_LOG_LOGIC ("All queued packets are out-dated for the destination in send buffer");
1851  }
1852  }
1853  /*
1854  * Here we try to find data packet from send buffer, if packet with this destiantion found, send it out
1855  */
1856  else if (m_errorBuffer.Find (destination))
1857  {
1858  DsrErrorBuffEntry entry;
1859  if (m_errorBuffer.Dequeue (destination, entry))
1860  {
1861  Ptr<Packet> packet = entry.GetPacket ()->Copy ();
1862  NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
1863 
1864  DsrRoutingHeader dsrRoutingHeader;
1865  Ptr<Packet> copyP = packet->Copy ();
1866  Ptr<Packet> dsrPacket = packet->Copy ();
1867  dsrPacket->RemoveHeader (dsrRoutingHeader);
1868  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1869  copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1870  /*
1871  * Peek data to get the option type as well as length and segmentsLeft field
1872  */
1873  uint32_t size = copyP->GetSize ();
1874  uint8_t *data = new uint8_t[size];
1875  copyP->CopyData (data, size);
1876 
1877  uint8_t optionType = 0;
1878  optionType = *(data);
1879  NS_LOG_DEBUG ("The option type value in send packet " << (uint32_t)optionType);
1880  if (optionType == 3)
1881  {
1882  NS_LOG_DEBUG ("The packet is error packet");
1883  Ptr<dsr::DsrOptions> dsrOption;
1884  DsrOptionHeader dsrOptionHeader;
1885 
1886  uint8_t errorType = *(data + 2);
1887  NS_LOG_DEBUG ("The error type");
1888  if (errorType == 1)
1889  {
1890  NS_LOG_DEBUG ("The packet is route error unreach packet");
1892  copyP->RemoveHeader (rerr);
1893  NS_ASSERT (copyP->GetSize () == 0);
1894  uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
1895 
1896  DsrOptionRerrUnreachHeader newUnreach;
1897  newUnreach.SetErrorType (1);
1898  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
1899  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
1900  newUnreach.SetErrorDst (rerr.GetErrorDst ());
1901  newUnreach.SetOriginalDst (rerr.GetOriginalDst ());
1902  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
1903 
1904  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1905  DsrRoutingHeader newRoutingHeader;
1906  newRoutingHeader.SetNextHeader (protocol);
1907  newRoutingHeader.SetMessageType (1);
1908  newRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
1909  newRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
1910  newRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1911  newRoutingHeader.AddDsrOption (newUnreach);
1912  newRoutingHeader.AddDsrOption (sourceRoute);
1914  if (m_routeCache->IsLinkCache ())
1915  {
1916  m_routeCache->UseExtends (nodeList);
1917  }
1918  SetRoute (nextHop, m_mainAddress);
1919  Ptr<Packet> newPacket = Create<Packet> ();
1920  newPacket->AddHeader (newRoutingHeader); // Add the extension header with rerr and sourceRoute attached to it
1921  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
1923 
1924  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1925  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1926  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1927  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1928 
1929  //m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
1930 
1932  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
1933 
1934  if (dsrNetworkQueue->Enqueue (newEntry))
1935  {
1936  Scheduler (priority);
1937  }
1938  else
1939  {
1940  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1941  }
1942  }
1943  }
1944 
1945  if (m_errorBuffer.GetSize () != 0 && m_errorBuffer.Find (destination))
1946  {
1947  NS_LOG_LOGIC ("Schedule sending the next packet in error buffer");
1949  &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
1950  }
1951  }
1952  }
1953  else
1954  {
1955  NS_LOG_DEBUG ("Packet not found in either the send or error buffer");
1956  }
1957 }
1958 
1959 bool
1960 DsrRouting::PassiveEntryCheck (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft,
1961  uint16_t fragmentOffset, uint16_t identification, bool saveEntry)
1962 {
1963  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
1964 
1965  Ptr<Packet> p = packet->Copy ();
1966  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
1967  DsrPassiveBuffEntry newEntry;
1968  newEntry.SetPacket (p);
1969  newEntry.SetSource (source);
1970  newEntry.SetDestination (destination);
1971  newEntry.SetIdentification (identification);
1972  newEntry.SetFragmentOffset (fragmentOffset);
1973  newEntry.SetSegsLeft (segsLeft); // We try to make sure the segments left is larger for 1
1974 
1975 
1976  NS_LOG_DEBUG ("The passive buffer size " << m_passiveBuffer->GetSize());
1977 
1978  if (m_passiveBuffer->AllEqual (newEntry) && (!saveEntry))
1979  {
1980  // The PromiscEqual function will remove the maintain buffer entry if equal value found
1981  // It only compares the source and destination address, ackId, and the segments left value
1982  NS_LOG_DEBUG ("We get the all equal for passive buffer here");
1983 
1984  DsrMaintainBuffEntry mbEntry;
1985  mbEntry.SetPacket (p);
1986  mbEntry.SetSrc (source);
1987  mbEntry.SetDst (destination);
1988  mbEntry.SetAckId (0);
1989  mbEntry.SetSegsLeft (segsLeft + 1);
1990 
1991  CancelPassivePacketTimer (mbEntry);
1992  return true;
1993  }
1994  if (saveEntry)
1995  {
1997  m_passiveBuffer->Enqueue (newEntry);
1998  }
1999  return false;
2000 }
2001 
2002 bool
2004  uint8_t segsLeft)
2005 {
2006  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
2007 
2008  NS_LOG_DEBUG ("Cancel the passive timer");
2009 
2010  Ptr<Packet> p = packet->Copy ();
2011  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
2012  DsrMaintainBuffEntry newEntry;
2013  newEntry.SetPacket (p);
2014  newEntry.SetSrc (source);
2015  newEntry.SetDst (destination);
2016  newEntry.SetAckId (0);
2017  newEntry.SetSegsLeft (segsLeft + 1);
2018 
2019  if (m_maintainBuffer.PromiscEqual (newEntry))
2020  {
2021  // The PromiscEqual function will remove the maintain buffer entry if equal value found
2022  // It only compares the source and destination address, ackId, and the segments left value
2023  CancelPassivePacketTimer (newEntry);
2024  return true;
2025  }
2026  return false;
2027 }
2028 
2029 void
2030 DsrRouting::CallCancelPacketTimer (uint16_t ackId, Ipv4Header const& ipv4Header, Ipv4Address realSrc, Ipv4Address realDst)
2031 {
2032  NS_LOG_FUNCTION (this << (uint32_t)ackId << ipv4Header << realSrc << realDst);
2033  Ipv4Address sender = ipv4Header.GetDestination ();
2034  Ipv4Address receiver = ipv4Header.GetSource ();
2035  /*
2036  * Create a packet to fill maintenance buffer, not used to compare with maintainance entry
2037  * The reason is ack header doesn't have the original packet copy
2038  */
2039  Ptr<Packet> mainP = Create<Packet> ();
2040  DsrMaintainBuffEntry newEntry (/*Packet=*/ mainP, /*ourAddress=*/ sender, /*nextHop=*/ receiver,
2041  /*source=*/ realSrc, /*destination=*/ realDst, /*ackId=*/ ackId,
2042  /*SegsLeft=*/ 0, /*expire time=*/ Simulator::Now ());
2043  CancelNetworkPacketTimer (newEntry); // Only need to cancel network packet timer
2044 }
2045 
2046 void
2048 {
2049  NS_LOG_FUNCTION (this);
2050  CancelLinkPacketTimer (mb);
2053 }
2054 
2055 void
2057 {
2058  NS_LOG_FUNCTION (this);
2059  LinkKey linkKey;
2060  linkKey.m_ourAdd = mb.GetOurAdd ();
2061  linkKey.m_nextHop = mb.GetNextHop ();
2062  linkKey.m_source = mb.GetSrc ();
2063  linkKey.m_destination = mb.GetDst ();
2064  /*
2065  * Here we have found the entry for send retries, so we get the value and increase it by one
2066  */
2068  m_linkCnt[linkKey] = 0;
2069  m_linkCnt.erase (linkKey);
2070 
2071  // TODO if find the linkkey, we need to remove it
2072 
2073  // Find the network acknowledgment timer
2074  std::map<LinkKey, Timer>::const_iterator i =
2075  m_linkAckTimer.find (linkKey);
2076  if (i == m_linkAckTimer.end ())
2077  {
2078  NS_LOG_INFO ("did not find the link timer");
2079  }
2080  else
2081  {
2082  NS_LOG_INFO ("did find the link timer");
2083  /*
2084  * Schedule the packet retry
2085  * Push back the nextHop, source, destination address
2086  */
2087  m_linkAckTimer[linkKey].Cancel ();
2088  m_linkAckTimer[linkKey].Remove ();
2089  if (m_linkAckTimer[linkKey].IsRunning ())
2090  {
2091  NS_LOG_INFO ("Timer not canceled");
2092  }
2093  m_linkAckTimer.erase (linkKey);
2094  }
2095 
2096  // Erase the maintenance entry
2097  // yet this does not check the segments left value here
2098  NS_LOG_DEBUG ("The link buffer size " << m_maintainBuffer.GetSize());
2099  if (m_maintainBuffer.LinkEqual (mb))
2100  {
2101  NS_LOG_INFO ("Link acknowledgment received, remove same maintenance buffer entry");
2102  }
2103 }
2104 
2105 void
2107 {
2108  NS_LOG_FUNCTION (this);
2109  NetworkKey networkKey;
2110  networkKey.m_ackId = mb.GetAckId ();
2111  networkKey.m_ourAdd = mb.GetOurAdd ();
2112  networkKey.m_nextHop = mb.GetNextHop ();
2113  networkKey.m_source = mb.GetSrc ();
2114  networkKey.m_destination = mb.GetDst ();
2115  /*
2116  * Here we have found the entry for send retries, so we get the value and increase it by one
2117  */
2118  m_addressForwardCnt[networkKey] = 0;
2119  m_addressForwardCnt.erase (networkKey);
2120 
2121  NS_LOG_INFO ("ackId " << mb.GetAckId () << " ourAdd " << mb.GetOurAdd () << " nextHop " << mb.GetNextHop ()
2122  << " source " << mb.GetSrc () << " destination " << mb.GetDst ()
2123  << " segsLeft " << (uint32_t)mb.GetSegsLeft ()
2124  );
2125  // Find the network acknowledgment timer
2126  std::map<NetworkKey, Timer>::const_iterator i =
2127  m_addressForwardTimer.find (networkKey);
2128  if (i == m_addressForwardTimer.end ())
2129  {
2130  NS_LOG_INFO ("did not find the packet timer");
2131  }
2132  else
2133  {
2134  NS_LOG_INFO ("did find the packet timer");
2135  /*
2136  * Schedule the packet retry
2137  * Push back the nextHop, source, destination address
2138  */
2139  m_addressForwardTimer[networkKey].Cancel ();
2140  m_addressForwardTimer[networkKey].Remove ();
2141  if (m_addressForwardTimer[networkKey].IsRunning ())
2142  {
2143  NS_LOG_INFO ("Timer not canceled");
2144  }
2145  m_addressForwardTimer.erase (networkKey);
2146  }
2147  // Erase the maintenance entry
2148  // yet this does not check the segments left value here
2149  if (m_maintainBuffer.NetworkEqual (mb))
2150  {
2151  NS_LOG_INFO ("Remove same maintenance buffer entry based on network acknowledgment");
2152  }
2153 }
2154 
2155 void
2157 {
2158  NS_LOG_FUNCTION (this);
2159  PassiveKey passiveKey;
2160  passiveKey.m_ackId = 0;
2161  passiveKey.m_source = mb.GetSrc ();
2162  passiveKey.m_destination = mb.GetDst ();
2163  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2164 
2165  m_passiveCnt[passiveKey] = 0;
2166  m_passiveCnt.erase (passiveKey);
2167 
2168  // Find the passive acknowledgment timer
2169  std::map<PassiveKey, Timer>::const_iterator j =
2170  m_passiveAckTimer.find (passiveKey);
2171  if (j == m_passiveAckTimer.end ())
2172  {
2173  NS_LOG_INFO ("did not find the passive timer");
2174  }
2175  else
2176  {
2177  NS_LOG_INFO ("find the passive timer");
2178  /*
2179  * Cancel passive acknowledgment timer
2180  */
2181  m_passiveAckTimer[passiveKey].Cancel ();
2182  m_passiveAckTimer[passiveKey].Remove ();
2183  if (m_passiveAckTimer[passiveKey].IsRunning ())
2184  {
2185  NS_LOG_INFO ("Timer not canceled");
2186  }
2187  m_passiveAckTimer.erase (passiveKey);
2188  }
2189 }
2190 
2191 void
2193 {
2194  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
2195 
2196  DsrMaintainBuffEntry entry;
2197  std::vector<Ipv4Address> previousErrorDst;
2198  if (m_maintainBuffer.Dequeue (nextHop, entry))
2199  {
2200  Ipv4Address source = entry.GetSrc ();
2201  Ipv4Address destination = entry.GetDst ();
2202 
2203  Ptr<Packet> dsrP = entry.GetPacket ()->Copy ();
2204  Ptr<Packet> p = dsrP->Copy ();
2205  Ptr<Packet> packet = dsrP->Copy ();
2206  DsrRoutingHeader dsrRoutingHeader;
2207  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
2208  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2209  p->RemoveAtStart (offset);
2210 
2211  // Get the number of routers' address field
2212  uint8_t buf[2];
2213  p->CopyData (buf, sizeof(buf));
2214  uint8_t numberAddress = (buf[1] - 2) / 4;
2215  NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
2216  DsrOptionSRHeader sourceRoute;
2217  sourceRoute.SetNumberAddress (numberAddress);
2218  p->RemoveHeader (sourceRoute);
2219  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
2220  uint8_t salvage = sourceRoute.GetSalvage ();
2221  Ipv4Address address1 = nodeList[1];
2222  PrintVector (nodeList);
2223 
2224  /*
2225  * If the salvage is not 0, use the first address in the route as the error dst in error header
2226  * otherwise use the source of packet as the error destination
2227  */
2228  Ipv4Address errorDst;
2229  if (salvage)
2230  {
2231  errorDst = address1;
2232  }
2233  else
2234  {
2235  errorDst = source;
2236  }
2238  if (std::find(previousErrorDst.begin(), previousErrorDst.end(), destination)==previousErrorDst.end())
2239  {
2240  NS_LOG_DEBUG ("have not seen this dst before " << errorDst << " in " << previousErrorDst.size());
2241  SendUnreachError (nextHop, errorDst, destination, salvage, protocol);
2242  previousErrorDst.push_back(errorDst);
2243  }
2244 
2245  /*
2246  * Cancel the packet timer and then salvage the data packet
2247  */
2248 
2249  CancelPacketAllTimer (entry);
2250  SalvagePacket (packet, source, destination, protocol);
2251 
2252  if (m_maintainBuffer.GetSize () && m_maintainBuffer.Find (nextHop))
2253  {
2254  NS_LOG_INFO ("Cancel the packet timer for next maintenance entry");
2256  &DsrRouting::CancelPacketTimerNextHop,this,nextHop,protocol);
2257  }
2258  }
2259  else
2260  {
2261  NS_LOG_INFO ("Maintenance buffer entry not found");
2262  }
2264 }
2265 
2266 void
2268 {
2269  NS_LOG_FUNCTION (this << packet << source << dst << (uint32_t)protocol);
2270  // Create two copies of packet
2271  Ptr<Packet> p = packet->Copy ();
2272  Ptr<Packet> newPacket = packet->Copy ();
2273  // Remove the routing header in a whole to get a clean packet
2274  DsrRoutingHeader dsrRoutingHeader;
2275  p->RemoveHeader (dsrRoutingHeader);
2276  // Remove offset of dsr routing header
2277  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2278  newPacket->RemoveAtStart (offset);
2279 
2280  // Get the number of routers' address field
2281  uint8_t buf[2];
2282  newPacket->CopyData (buf, sizeof(buf));
2283  uint8_t numberAddress = (buf[1] - 2) / 4;
2284 
2285  DsrOptionSRHeader sourceRoute;
2286  sourceRoute.SetNumberAddress (numberAddress);
2287  newPacket->RemoveHeader (sourceRoute);
2288  uint8_t salvage = sourceRoute.GetSalvage ();
2289  /*
2290  * Look in the route cache for other routes for this destination
2291  */
2292  DsrRouteCacheEntry toDst;
2293  bool findRoute = m_routeCache->LookupRoute (dst, toDst);
2294  if (findRoute && (salvage < m_maxSalvageCount))
2295  {
2296  NS_LOG_DEBUG ("We have found a route for the packet");
2297  DsrRoutingHeader newDsrRoutingHeader;
2298  newDsrRoutingHeader.SetNextHeader (protocol);
2299  newDsrRoutingHeader.SetMessageType (2);
2300  newDsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2301  newDsrRoutingHeader.SetDestId (GetIDfromIP (dst));
2302 
2303  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
2304  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
2305  if (nextHop == "0.0.0.0")
2306  {
2307  PacketNewRoute (p, source, dst, protocol);
2308  return;
2309  }
2310  // Increase the salvage count by 1
2311  salvage++;
2312  DsrOptionSRHeader sourceRoute;
2313  sourceRoute.SetSalvage (salvage);
2314  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
2315  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
2317  if (m_routeCache->IsLinkCache ())
2318  {
2319  m_routeCache->UseExtends (nodeList);
2320  }
2321  uint8_t length = sourceRoute.GetLength ();
2322  NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ()));
2323  newDsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2324  newDsrRoutingHeader.AddDsrOption (sourceRoute);
2325  p->AddHeader (newDsrRoutingHeader);
2326 
2327  SetRoute (nextHop, m_mainAddress);
2328  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
2330 
2331  // Send out the data packet
2332  uint32_t priority = GetPriority (DSR_DATA_PACKET);
2333  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2334  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2335  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2336 
2337  //m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
2338 
2340  DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
2341 
2342  if (dsrNetworkQueue->Enqueue (newEntry))
2343  {
2344  Scheduler (priority);
2345  }
2346  else
2347  {
2348  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2349  }
2350 
2351  /*
2352  * Mark the next hop address in blacklist
2353  */
2354 // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2355 // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2356  }
2357  else
2358  {
2359  NS_LOG_DEBUG ("Will not salvage this packet, silently drop");
2360  }
2361 }
2362 
2363 void
2365  uint8_t protocol)
2366 {
2367  NS_LOG_FUNCTION (this << (uint32_t) protocol);
2368 
2369  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2370  Ipv4Address source = mb.GetSrc ();
2371  Ipv4Address nextHop = mb.GetNextHop ();
2372 
2373  // Send the data packet out before schedule the next packet transmission
2374  SendPacket (p, source, nextHop, protocol);
2375 
2376  LinkKey linkKey;
2377  linkKey.m_source = mb.GetSrc ();
2378  linkKey.m_destination = mb.GetDst ();
2379  linkKey.m_ourAdd = mb.GetOurAdd ();
2380  linkKey.m_nextHop = mb.GetNextHop ();
2381 
2382  if (m_linkAckTimer.find (linkKey) == m_linkAckTimer.end ())
2383  {
2385  m_linkAckTimer[linkKey] = timer;
2386  }
2387  m_linkAckTimer[linkKey].SetFunction (&DsrRouting::LinkScheduleTimerExpire, this);
2388  m_linkAckTimer[linkKey].Remove ();
2389  m_linkAckTimer[linkKey].SetArguments (mb, protocol);
2390  m_linkAckTimer[linkKey].Schedule (m_linkAckTimeout);
2391 }
2392 
2393 void
2395  uint8_t protocol)
2396 {
2397  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2398 
2399  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2400  Ipv4Address source = mb.GetSrc ();
2401  Ipv4Address nextHop = mb.GetNextHop ();
2402 
2403  // Send the data packet out before schedule the next packet transmission
2404  SendPacket (p, source, nextHop, protocol);
2405 
2406  PassiveKey passiveKey;
2407  passiveKey.m_ackId = 0;
2408  passiveKey.m_source = mb.GetSrc ();
2409  passiveKey.m_destination = mb.GetDst ();
2410  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2411 
2412  if (m_passiveAckTimer.find (passiveKey) == m_passiveAckTimer.end ())
2413  {
2415  m_passiveAckTimer[passiveKey] = timer;
2416  }
2417  NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
2418  m_passiveAckTimer[passiveKey].SetFunction (&DsrRouting::PassiveScheduleTimerExpire, this);
2419  m_passiveAckTimer[passiveKey].Remove ();
2420  m_passiveAckTimer[passiveKey].SetArguments (mb, protocol);
2421  m_passiveAckTimer[passiveKey].Schedule (m_passiveAckTimeout);
2422 }
2423 
2424 void
2426  bool isFirst,
2427  uint8_t protocol)
2428 {
2429  Ptr<Packet> p = Create<Packet> ();
2430  Ptr<Packet> dsrP = Create<Packet> ();
2431  // The new entry will be used for retransmission
2432  NetworkKey networkKey;
2433  Ipv4Address nextHop = mb.GetNextHop ();
2434  NS_LOG_DEBUG ("is the first retry or not " << isFirst);
2435  if (isFirst)
2436  {
2437  // This is the very first network packet retry
2438  p = mb.GetPacket ()->Copy ();
2439  // Here we add the ack request header to the data packet for network acknowledgement
2440  uint16_t ackId = AddAckReqHeader (p, nextHop);
2441 
2442  Ipv4Address source = mb.GetSrc ();
2443  Ipv4Address nextHop = mb.GetNextHop ();
2444  // Send the data packet out before schedule the next packet transmission
2445  SendPacket (p, source, nextHop, protocol);
2446 
2447  dsrP = p->Copy ();
2448  DsrMaintainBuffEntry newEntry = mb;
2449  // The function AllEqual will find the exact entry and delete it if found
2451  newEntry.SetPacket (dsrP);
2452  newEntry.SetAckId (ackId);
2453  newEntry.SetExpireTime (m_maxMaintainTime);
2454 
2455  networkKey.m_ackId = newEntry.GetAckId ();
2456  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2457  networkKey.m_nextHop = newEntry.GetNextHop ();
2458  networkKey.m_source = newEntry.GetSrc ();
2459  networkKey.m_destination = newEntry.GetDst ();
2460 
2461  m_addressForwardCnt[networkKey] = 0;
2462  if (! m_maintainBuffer.Enqueue (newEntry))
2463  {
2464  NS_LOG_ERROR ("Failed to enqueue packet retry");
2465  }
2466 
2467  if (m_addressForwardTimer.find (networkKey) == m_addressForwardTimer.end ())
2468  {
2470  m_addressForwardTimer[networkKey] = timer;
2471  }
2472 
2473  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2474  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2475  m_addressForwardTimer[networkKey].Remove ();
2476  m_addressForwardTimer[networkKey].SetArguments (newEntry, protocol);
2477  NS_LOG_DEBUG ("The packet retries time for " << newEntry.GetAckId () << " is " << m_sendRetries
2478  << " and the delay time is " << Time (2 * m_nodeTraversalTime).GetSeconds ());
2479  // Back-off mechanism
2480  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_nodeTraversalTime));
2481  }
2482  else
2483  {
2484  networkKey.m_ackId = mb.GetAckId ();
2485  networkKey.m_ourAdd = mb.GetOurAdd ();
2486  networkKey.m_nextHop = mb.GetNextHop ();
2487  networkKey.m_source = mb.GetSrc ();
2488  networkKey.m_destination = mb.GetDst ();
2489  /*
2490  * Here we have found the entry for send retries, so we get the value and increase it by one
2491  */
2492  m_sendRetries = m_addressForwardCnt[networkKey];
2493  NS_LOG_DEBUG ("The packet retry we have done " << m_sendRetries);
2494 
2495  p = mb.GetPacket ()->Copy ();
2496  dsrP = mb.GetPacket ()->Copy ();
2497 
2498  Ipv4Address source = mb.GetSrc ();
2499  Ipv4Address nextHop = mb.GetNextHop ();
2500  // Send the data packet out before schedule the next packet transmission
2501  SendPacket (p, source, nextHop, protocol);
2502 
2503  NS_LOG_DEBUG ("The packet with dsr header " << dsrP->GetSize ());
2504  networkKey.m_ackId = mb.GetAckId ();
2505  networkKey.m_ourAdd = mb.GetOurAdd ();
2506  networkKey.m_nextHop = mb.GetNextHop ();
2507  networkKey.m_source = mb.GetSrc ();
2508  networkKey.m_destination = mb.GetDst ();
2509  /*
2510  * If a data packet has been attempted SendRetries times at the maximum TTL without
2511  * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2512  * dropped from the send buffer
2513  *
2514  * The maxMaintRexmt also needs to decrease one for the passive ack packet
2515  */
2516  /*
2517  * Check if the send retry time for a certain packet has already passed max maintenance retransmission
2518  * time or not
2519  */
2520 
2521  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2522  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2523  m_addressForwardTimer[networkKey].Remove ();
2524  m_addressForwardTimer[networkKey].SetArguments (mb, protocol);
2525  NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId () << " is " << m_sendRetries
2526  << " and the delay time is " << Time (2 * m_sendRetries * m_nodeTraversalTime).GetSeconds ());
2527  // Back-off mechanism
2528  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries * m_nodeTraversalTime));
2529  }
2530 }
2531 
2532 void
2534  uint8_t protocol)
2535 {
2536  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2537  Ipv4Address nextHop = mb.GetNextHop ();
2538  Ptr<const Packet> packet = mb.GetPacket ();
2539  SetRoute (nextHop, m_mainAddress);
2540  Ptr<Packet> p = packet->Copy ();
2541 
2542  LinkKey lk;
2543  lk.m_source = mb.GetSrc ();
2544  lk.m_destination = mb.GetDst ();
2545  lk.m_ourAdd = mb.GetOurAdd ();
2546  lk.m_nextHop = mb.GetNextHop ();
2547 
2548  // Cancel passive ack timer
2549  m_linkAckTimer[lk].Cancel ();
2550  m_linkAckTimer[lk].Remove ();
2551  if (m_linkAckTimer[lk].IsRunning ())
2552  {
2553  NS_LOG_DEBUG ("Timer not canceled");
2554  }
2555  m_linkAckTimer.erase (lk);
2556 
2557  // Increase the send retry times
2558  m_linkRetries = m_linkCnt[lk];
2560  {
2561  m_linkCnt[lk] = ++m_linkRetries;
2562  ScheduleLinkPacketRetry (mb, protocol);
2563  }
2564  else
2565  {
2566  NS_LOG_INFO ("We need to send error messages now");
2567 
2568  // Delete all the routes including the links
2569  m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
2570  /*
2571  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2572  * Also salvage the packet for the all the packet destined for the nextHop address
2573  * this is also responsible for send unreachable error back to source
2574  */
2575  CancelPacketTimerNextHop (nextHop, protocol);
2576  }
2577 }
2578 
2579 void
2581  uint8_t protocol)
2582 {
2583  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2584  Ipv4Address nextHop = mb.GetNextHop ();
2585  Ptr<const Packet> packet = mb.GetPacket ();
2586  SetRoute (nextHop, m_mainAddress);
2587  Ptr<Packet> p = packet->Copy ();
2588 
2589  PassiveKey pk;
2590  pk.m_ackId = 0;
2591  pk.m_source = mb.GetSrc ();
2592  pk.m_destination = mb.GetDst ();
2593  pk.m_segsLeft = mb.GetSegsLeft ();
2594 
2595  // Cancel passive ack timer
2596  m_passiveAckTimer[pk].Cancel ();
2597  m_passiveAckTimer[pk].Remove ();
2598  if (m_passiveAckTimer[pk].IsRunning ())
2599  {
2600  NS_LOG_DEBUG ("Timer not canceled");
2601  }
2602  m_passiveAckTimer.erase (pk);
2603 
2604  // Increase the send retry times
2607  {
2609  SchedulePassivePacketRetry (mb, protocol);
2610  }
2611  else
2612  {
2613  // This is the first network acknowledgement retry
2614  // Cancel the passive packet timer now and remove maintenance buffer entry for it
2616  ScheduleNetworkPacketRetry (mb, true, protocol);
2617  }
2618 }
2619 
2620 int64_t
2622 {
2623  NS_LOG_FUNCTION (this << stream);
2625  return 1;
2626 }
2627 
2628 void
2630  uint8_t protocol)
2631 {
2632  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2633  Ipv4Address source = mb.GetSrc ();
2634  Ipv4Address nextHop = mb.GetNextHop ();
2635  Ipv4Address dst = mb.GetDst ();
2636 
2637  NetworkKey networkKey;
2638  networkKey.m_ackId = mb.GetAckId ();
2639  networkKey.m_ourAdd = mb.GetOurAdd ();
2640  networkKey.m_nextHop = nextHop;
2641  networkKey.m_source = source;
2642  networkKey.m_destination = dst;
2643 
2644  // Increase the send retry times
2645  m_sendRetries = m_addressForwardCnt[networkKey];
2646 
2648  {
2649  // Delete all the routes including the links
2650  m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
2651  /*
2652  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2653  * Also salvage the packet for the all the packet destined for the nextHop address
2654  */
2655  CancelPacketTimerNextHop (nextHop, protocol);
2656  }
2657  else
2658  {
2659  m_addressForwardCnt[networkKey] = ++m_sendRetries;
2660  ScheduleNetworkPacketRetry (mb, false, protocol);
2661  }
2662 }
2663 
2664 void
2666  DsrOptionSRHeader &sourceRoute,
2667  Ipv4Header const& ipv4Header,
2668  Ipv4Address source,
2669  Ipv4Address nextHop,
2670  Ipv4Address targetAddress,
2671  uint8_t protocol,
2672  Ptr<Ipv4Route> route)
2673 {
2674  NS_LOG_FUNCTION (this << packet << sourceRoute << source << nextHop << targetAddress << (uint32_t)protocol << route);
2675  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2676 
2677  DsrRoutingHeader dsrRoutingHeader;
2678  dsrRoutingHeader.SetNextHeader (protocol);
2679  dsrRoutingHeader.SetMessageType (2);
2680  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2681  dsrRoutingHeader.SetDestId (GetIDfromIP (targetAddress));
2682 
2683  // We get the salvage value in sourceRoute header and set it to route error header if triggered error
2684  Ptr<Packet> p = packet->Copy ();
2685  uint8_t length = sourceRoute.GetLength ();
2686  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2687  dsrRoutingHeader.AddDsrOption (sourceRoute);
2688  p->AddHeader (dsrRoutingHeader);
2689 
2690  Ptr<const Packet> mtP = p->Copy ();
2691 
2692  DsrMaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
2693  /*source=*/ source, /*destination=*/ targetAddress, /*ackId=*/ m_ackId,
2694  /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
2695  bool result = m_maintainBuffer.Enqueue (newEntry);
2696 
2697  if (result)
2698  {
2699  NetworkKey networkKey;
2700  networkKey.m_ackId = newEntry.GetAckId ();
2701  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2702  networkKey.m_nextHop = newEntry.GetNextHop ();
2703  networkKey.m_source = newEntry.GetSrc ();
2704  networkKey.m_destination = newEntry.GetDst ();
2705 
2706  PassiveKey passiveKey;
2707  passiveKey.m_ackId = 0;
2708  passiveKey.m_source = newEntry.GetSrc ();
2709  passiveKey.m_destination = newEntry.GetDst ();
2710  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
2711 
2712  LinkKey linkKey;
2713  linkKey.m_source = newEntry.GetSrc ();
2714  linkKey.m_destination = newEntry.GetDst ();
2715  linkKey.m_ourAdd = newEntry.GetOurAdd ();
2716  linkKey.m_nextHop = newEntry.GetNextHop ();
2717 
2718  m_addressForwardCnt[networkKey] = 0;
2719  m_passiveCnt[passiveKey] = 0;
2720  m_linkCnt[linkKey] = 0;
2721 
2722  if (m_linkAck)
2723  {
2724  ScheduleLinkPacketRetry (newEntry, protocol);
2725  }
2726  else
2727  {
2728  NS_LOG_LOGIC ("Not using link acknowledgment");
2729  if (nextHop != targetAddress)
2730  {
2731  SchedulePassivePacketRetry (newEntry, protocol);
2732  }
2733  else
2734  {
2735  // This is the first network retry
2736  ScheduleNetworkPacketRetry (newEntry, true, protocol);
2737  }
2738  }
2739  }
2740 }
2741 
2742 void
2744  Ipv4Address destination,
2745  uint8_t protocol)
2746 {
2747  NS_LOG_FUNCTION (this << source << destination << (uint32_t)protocol);
2748  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2749  Ptr<Packet> packet = Create<Packet> ();
2750  // Create an empty Ipv4 route ptr
2751  Ptr<Ipv4Route> route;
2752  /*
2753  * Construct the route request option header
2754  */
2755  DsrRoutingHeader dsrRoutingHeader;
2756  dsrRoutingHeader.SetNextHeader (protocol);
2757  dsrRoutingHeader.SetMessageType (1);
2758  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2759  dsrRoutingHeader.SetDestId (255);
2760 
2761  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2762  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2763  rreqHeader.SetTarget (destination);
2764  m_requestId = m_rreqTable->CheckUniqueRreqId (destination); // Check the Id cache for duplicate ones
2765  rreqHeader.SetId (m_requestId);
2766 
2767  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2768  uint8_t length = rreqHeader.GetLength ();
2769  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2770  packet->AddHeader (dsrRoutingHeader);
2771 
2772  // Schedule the route requests retry with non-propagation set true
2773  bool nonProp = true;
2774  std::vector<Ipv4Address> address;
2775  address.push_back (source);
2776  address.push_back (destination);
2777  /*
2778  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2779  */
2780  SocketIpTtlTag tag;
2781  tag.SetTtl (0);
2782  Ptr<Packet> nonPropPacket = packet->Copy ();
2783  nonPropPacket->AddPacketTag (tag);
2784  // Increase the request count
2785  m_rreqTable->FindAndUpdate (destination);
2786  SendRequest (nonPropPacket, source);
2787  // Schedule the next route request
2788  ScheduleRreqRetry (packet, address, nonProp, m_requestId, protocol);
2789 }
2790 
2791 void
2793 {
2794  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2795  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2796  uint8_t salvage = rerr.GetSalvage ();
2797  Ipv4Address dst = rerr.GetOriginalDst ();
2798  NS_LOG_DEBUG ("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc () << " error destination " << rerr.GetErrorDst ()
2799  << " error next hop " << rerr.GetUnreachNode () << " original dst " << rerr.GetOriginalDst ()
2800  );
2801  DsrRouteCacheEntry toDst;
2802  if (m_routeCache->LookupRoute (dst, toDst))
2803  {
2804  /*
2805  * Found a route the dst, construct the source route option header
2806  */
2807  DsrOptionSRHeader sourceRoute;
2808  std::vector<Ipv4Address> ip = toDst.GetVector ();
2809  sourceRoute.SetNodesAddress (ip);
2811  if (m_routeCache->IsLinkCache ())
2812  {
2813  m_routeCache->UseExtends (ip);
2814  }
2815  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
2816  sourceRoute.SetSalvage (salvage);
2817  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
2818  NS_LOG_DEBUG ("The nextHop address " << nextHop);
2819  Ptr<Packet> packet = Create<Packet> ();
2820  if (nextHop == "0.0.0.0")
2821  {
2822  NS_LOG_DEBUG ("Error next hop address");
2823  PacketNewRoute (packet, m_mainAddress, dst, protocol);
2824  return;
2825  }
2826  SetRoute (nextHop, m_mainAddress);
2827  CancelRreqTimer (dst, true);
2829  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
2830  {
2831  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
2832  }
2833  NS_LOG_LOGIC ("Route to " << dst << " found");
2834  return;
2835  }
2836  else
2837  {
2838  NS_LOG_INFO ("No route found, initiate route error request");
2839  Ptr<Packet> packet = Create<Packet> ();
2840  Ipv4Address originalDst = rerr.GetOriginalDst ();
2841  // Create an empty route ptr
2842  Ptr<Ipv4Route> route = 0;
2843  /*
2844  * Construct the route request option header
2845  */
2846  DsrRoutingHeader dsrRoutingHeader;
2847  dsrRoutingHeader.SetNextHeader (protocol);
2848  dsrRoutingHeader.SetMessageType (1);
2849  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
2850  dsrRoutingHeader.SetDestId (255);
2851 
2852  Ptr<Packet> dstP = Create<Packet> ();
2853  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2854  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2855  rreqHeader.SetTarget (originalDst);
2856  m_requestId = m_rreqTable->CheckUniqueRreqId (originalDst); // Check the Id cache for duplicate ones
2857  rreqHeader.SetId (m_requestId);
2858 
2859  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2860  dsrRoutingHeader.AddDsrOption (rerr);
2861  uint8_t length = rreqHeader.GetLength () + rerr.GetLength ();
2862  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
2863  dstP->AddHeader (dsrRoutingHeader);
2864  // Schedule the route requests retry, propagate the route request message as it contains error
2865  bool nonProp = false;
2866  std::vector<Ipv4Address> address;
2867  address.push_back (m_mainAddress);
2868  address.push_back (originalDst);
2869  /*
2870  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2871  */
2872  SocketIpTtlTag tag;
2873  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
2874  Ptr<Packet> propPacket = dstP->Copy ();
2875  propPacket->AddPacketTag (tag);
2876 
2877  if ((m_addressReqTimer.find (originalDst) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (originalDst) == m_nonPropReqTimer.end ()))
2878  {
2879  NS_LOG_INFO ("Only when there is no existing route request time when the initial route request is scheduled");
2880  SendRequest (propPacket, m_mainAddress);
2881  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2882  }
2883  else
2884  {
2885  NS_LOG_INFO ("There is existing route request, find the existing route request entry");
2886  /*
2887  * Cancel the route request timer first before scheduling the route request
2888  * in this case, we do not want to remove the route request entry, so the isRemove value is false
2889  */
2890  CancelRreqTimer (originalDst, false);
2891  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2892  }
2893  }
2894 }
2895 
2896 void
2898 {
2899  NS_LOG_FUNCTION (this << dst << isRemove);
2900  // Cancel the non propagation request timer if found
2901  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2902  {
2903  NS_LOG_DEBUG ("Did not find the non-propagation timer");
2904  }
2905  else
2906  {
2907  NS_LOG_DEBUG ("did find the non-propagation timer");
2908  }
2909  m_nonPropReqTimer[dst].Cancel ();
2910  m_nonPropReqTimer[dst].Remove ();
2911 
2912  if (m_nonPropReqTimer[dst].IsRunning ())
2913  {
2914  NS_LOG_DEBUG ("Timer not canceled");
2915  }
2916  m_nonPropReqTimer.erase (dst);
2917 
2918  // Cancel the address request timer if found
2919  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2920  {
2921  NS_LOG_DEBUG ("Did not find the propagation timer");
2922  }
2923  else
2924  {
2925  NS_LOG_DEBUG ("did find the propagation timer");
2926  }
2927  m_addressReqTimer[dst].Cancel ();
2928  m_addressReqTimer[dst].Remove ();
2929  if (m_addressReqTimer[dst].IsRunning ())
2930  {
2931  NS_LOG_DEBUG ("Timer not canceled");
2932  }
2933  m_addressReqTimer.erase (dst);
2934  /*
2935  * If the route request is scheduled to remove the route request entry
2936  * Remove the route request entry with the route retry times done for certain destination
2937  */
2938  if (isRemove)
2939  {
2940  // remove the route request entry from route request table
2941  m_rreqTable->RemoveRreqEntry (dst);
2942  }
2943 }
2944 
2945 void
2946 DsrRouting::ScheduleRreqRetry (Ptr<Packet> packet, std::vector<Ipv4Address> address, bool nonProp, uint32_t requestId, uint8_t protocol)
2947 {
2948  NS_LOG_FUNCTION (this << packet << nonProp << requestId << (uint32_t)protocol);
2949  Ipv4Address source = address[0];
2950  Ipv4Address dst = address[1];
2951  if (nonProp)
2952  {
2953  // The nonProp route request is only sent out only and is already used
2954  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2955  {
2957  m_nonPropReqTimer[dst] = timer;
2958  }
2959  std::vector<Ipv4Address> address;
2960  address.push_back (source);
2961  address.push_back (dst);
2962  m_nonPropReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2963  m_nonPropReqTimer[dst].Remove ();
2964  m_nonPropReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2966  }
2967  else
2968  {
2969  // Cancel the non propagation request timer if found
2970  m_nonPropReqTimer[dst].Cancel ();
2971  m_nonPropReqTimer[dst].Remove ();
2972  if (m_nonPropReqTimer[dst].IsRunning ())
2973  {
2974  NS_LOG_DEBUG ("Timer not canceled");
2975  }
2976  m_nonPropReqTimer.erase (dst);
2977 
2978  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2979  {
2981  m_addressReqTimer[dst] = timer;
2982  }
2983  std::vector<Ipv4Address> address;
2984  address.push_back (source);
2985  address.push_back (dst);
2986  m_addressReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2987  m_addressReqTimer[dst].Remove ();
2988  m_addressReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2989  Time rreqDelay;
2990  // back off mechanism for sending route requests
2991  if (m_rreqTable->GetRreqCnt (dst))
2992  {
2993  // When the route request count is larger than 0
2994  // This is the exponential back-off mechanism for route request
2995  rreqDelay = Time (std::pow (static_cast<double> (m_rreqTable->GetRreqCnt (dst)), 2.0) * m_requestPeriod);
2996  }
2997  else
2998  {
2999  // This is the first route request retry
3000  rreqDelay = m_requestPeriod;
3001  }
3002  NS_LOG_LOGIC ("Request count for " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with delay time " << rreqDelay.GetSeconds () << " second");
3003  if (rreqDelay > m_maxRequestPeriod)
3004  {
3005  // use the max request period
3006  NS_LOG_LOGIC ("The max request delay time " << m_maxRequestPeriod.GetSeconds ());
3007  m_addressReqTimer[dst].Schedule (m_maxRequestPeriod);
3008  }
3009  else
3010  {
3011  NS_LOG_LOGIC ("The request delay time " << rreqDelay.GetSeconds () << " second");
3012  m_addressReqTimer[dst].Schedule (rreqDelay);
3013  }
3014  }
3015 }
3016 
3017 void
3018 DsrRouting::RouteRequestTimerExpire (Ptr<Packet> packet, std::vector<Ipv4Address> address, uint32_t requestId, uint8_t protocol)
3019 {
3020  NS_LOG_FUNCTION (this << packet << requestId << (uint32_t)protocol);
3021  // Get a clean packet without dsr header
3022  Ptr<Packet> dsrP = packet->Copy ();
3023  DsrRoutingHeader dsrRoutingHeader;
3024  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
3025 
3026  Ipv4Address source = address[0];
3027  Ipv4Address dst = address[1];
3028  DsrRouteCacheEntry toDst;
3029  if (m_routeCache->LookupRoute (dst, toDst))
3030  {
3031  /*
3032  * Found a route the dst, construct the source route option header
3033  */
3034  DsrOptionSRHeader sourceRoute;
3035  std::vector<Ipv4Address> ip = toDst.GetVector ();
3036  sourceRoute.SetNodesAddress (ip);
3037  // When we found the route and use it, UseExtends for the link cache
3038  if (m_routeCache->IsLinkCache ())
3039  {
3040  m_routeCache->UseExtends (ip);
3041  }
3042  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
3044  sourceRoute.SetSalvage (0);
3045  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
3046  NS_LOG_INFO ("The nextHop address is " << nextHop);
3047  if (nextHop == "0.0.0.0")
3048  {
3049  NS_LOG_DEBUG ("Error next hop address");
3050  PacketNewRoute (dsrP, source, dst, protocol);
3051  return;
3052  }
3053  SetRoute (nextHop, m_mainAddress);
3054  CancelRreqTimer (dst, true);
3056  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
3057  {
3058  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
3059  }
3060  NS_LOG_LOGIC ("Route to " << dst << " found");
3061  return;
3062  }
3063  /*
3064  * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
3065  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
3066  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
3067  */
3068  NS_LOG_LOGIC ("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt (dst) << " the max " << m_rreqRetries);
3069  if (m_rreqTable->GetRreqCnt (dst) >= m_rreqRetries)
3070  {
3071  NS_LOG_LOGIC ("Route discovery to " << dst << " has been attempted " << m_rreqRetries << " times");
3072  CancelRreqTimer (dst, true);
3073  NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
3075  }
3076  else
3077  {
3078  SocketIpTtlTag tag;
3079  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
3080  Ptr<Packet> propPacket = packet->Copy ();
3081  propPacket->AddPacketTag (tag);
3082  // Increase the request count
3083  m_rreqTable->FindAndUpdate (dst);
3084  SendRequest (propPacket, source);
3085  NS_LOG_DEBUG ("Check the route request entry " << source << " " << dst);
3086  ScheduleRreqRetry (packet, address, false, requestId, protocol);
3087  }
3088  return;
3089 }
3090 
3091 void
3093  Ipv4Address source)
3094 {
3095  NS_LOG_FUNCTION (this << packet << source);
3096 
3097  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3098  /*
3099  * The destination address here is directed broadcast address
3100  */
3101  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3102  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3103  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3104  NS_LOG_LOGIC ("Inserting into priority queue number: " << priority);
3105 
3106  //m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
3107 
3109  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
3110  if (dsrNetworkQueue->Enqueue (newEntry))
3111  {
3112  Scheduler (priority);
3113  }
3114  else
3115  {
3116  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3117  }
3118 }
3119 
3120 void
3122 {
3123  NS_LOG_FUNCTION (this << packet);
3124  /*
3125  * This is a forwarding case when sending route requests, a random delay time [0, m_broadcastJitter]
3126  * used before forwarding as link-layer broadcast
3127  */
3129  packet, m_mainAddress);
3130 }
3131 
3132 void
3133 DsrRouting::SendGratuitousReply (Ipv4Address source, Ipv4Address srcAddress, std::vector<Ipv4Address> &nodeList, uint8_t protocol)
3134 {
3135  NS_LOG_FUNCTION (this << source << srcAddress << (uint32_t)protocol);
3136  if (!(m_graReply.FindAndUpdate (source, srcAddress, m_gratReplyHoldoff))) // Find the gratuitous reply entry
3137  {
3138  NS_LOG_LOGIC ("Update gratuitous reply " << source);
3139  GraReplyEntry graReplyEntry (source, srcAddress, m_gratReplyHoldoff + Simulator::Now ());
3140  m_graReply.AddEntry (graReplyEntry);
3141  /*
3142  * Automatic route shortening
3143  */
3144  m_finalRoute.clear (); // Clear the final route vector
3148  std::vector<Ipv4Address>::iterator before = find (nodeList.begin (), nodeList.end (), srcAddress);
3149  for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != before; ++i)
3150  {
3151  m_finalRoute.push_back (*i);
3152  }
3153  m_finalRoute.push_back (srcAddress);
3154  std::vector<Ipv4Address>::iterator after = find (nodeList.begin (), nodeList.end (), m_mainAddress);
3155  for (std::vector<Ipv4Address>::iterator j = after; j != nodeList.end (); ++j)
3156  {
3157  m_finalRoute.push_back (*j);
3158  }
3159  DsrOptionRrepHeader rrep;
3160  rrep.SetNodesAddress (m_finalRoute); // Set the node addresses in the route reply header
3161  // Get the real reply source and destination
3162  Ipv4Address replySrc = m_finalRoute.back ();
3163  Ipv4Address replyDst = m_finalRoute.front ();
3164  /*
3165  * Set the route and use it in send back route reply
3166  */
3167  m_ipv4Route = SetRoute (srcAddress, m_mainAddress);
3168  /*
3169  * This part adds DSR header to the packet and send reply
3170  */
3171  DsrRoutingHeader dsrRoutingHeader;
3172  dsrRoutingHeader.SetNextHeader (protocol);
3173  dsrRoutingHeader.SetMessageType (1);
3174  dsrRoutingHeader.SetSourceId (GetIDfromIP (replySrc));
3175  dsrRoutingHeader.SetDestId (GetIDfromIP (replyDst));
3176 
3177  uint8_t length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
3178  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
3179  dsrRoutingHeader.AddDsrOption (rrep);
3180  Ptr<Packet> newPacket = Create<Packet> ();
3181  newPacket->AddHeader (dsrRoutingHeader);
3182  /*
3183  * Send gratuitous reply
3184  */
3185  NS_LOG_INFO ("Send back gratuitous route reply");
3186  SendReply (newPacket, m_mainAddress, srcAddress, m_ipv4Route);
3187  }
3188  else
3189  {
3190  NS_LOG_INFO ("The same gratuitous route reply has already sent");
3191  }
3192 }
3193 
3194 void
3196  Ipv4Address source,
3197  Ipv4Address nextHop,
3198  Ptr<Ipv4Route> route)
3199 {
3200  NS_LOG_FUNCTION (this << packet << source << nextHop);
3201  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3202 
3203  Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (m_mainAddress));
3204  route->SetOutputDevice (dev);
3205  NS_LOG_INFO ("The output device " << dev << " packet is: " << *packet);
3206 
3207  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3208  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3209  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3210  NS_LOG_INFO ("Inserting into priority queue number: " << priority);
3211 
3212  //m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
3213 
3215  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
3216  if (dsrNetworkQueue->Enqueue (newEntry))
3217  {
3218  Scheduler (priority);
3219  }
3220  else
3221  {
3222  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3223  }
3224 }
3225 
3226 void
3228  Ipv4Address source,
3229  Ipv4Address nextHop,
3230  Ptr<Ipv4Route> route)
3231 {
3232  NS_LOG_FUNCTION (this << packet << source << nextHop);
3234  packet, source, nextHop, route);
3235 }
3236 
3237 void
3239  Ipv4Address source,
3240  Ipv4Address destination,
3241  Ptr<Ipv4Route> route,
3242  double hops)
3243 {
3244  NS_LOG_FUNCTION (this << packet << source << destination);
3245  Simulator::Schedule (Time (2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue (0,1))), &DsrRouting::SendReply, this, packet, source, destination, route);
3246 }
3247 
3248 void
3249 DsrRouting::SendAck (uint16_t ackId,
3250  Ipv4Address destination,
3251  Ipv4Address realSrc,
3252  Ipv4Address realDst,
3253  uint8_t protocol,
3254  Ptr<Ipv4Route> route)
3255 {
3256  NS_LOG_FUNCTION (this << ackId << destination << realSrc << realDst << (uint32_t)protocol << route);
3257  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
3258 
3259  // This is a route reply option header
3260  DsrRoutingHeader dsrRoutingHeader;
3261  dsrRoutingHeader.SetNextHeader (protocol);
3262  dsrRoutingHeader.SetMessageType (1);
3263  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
3264  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
3265 
3266  DsrOptionAckHeader ack;
3267  /*
3268  * Set the ack Id and set the ack source address and destination address
3269  */
3270  ack.SetAckId (ackId);
3271  ack.SetRealSrc (realSrc);
3272  ack.SetRealDst (realDst);
3273 
3274  uint8_t length = ack.GetLength ();
3275  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
3276  dsrRoutingHeader.AddDsrOption (ack);
3277 
3278  Ptr<Packet> packet = Create<Packet> ();
3279  packet->AddHeader (dsrRoutingHeader);
3280  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
3281  route->SetOutputDevice (dev);
3282 
3283  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
3284  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
3285  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
3286 
3287  NS_LOG_LOGIC ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
3288 
3289  //m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
3290 
3292  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
3293  if (dsrNetworkQueue->Enqueue (newEntry))
3294  {
3295  Scheduler (priority);
3296  }
3297  else
3298  {
3299  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
3300  }
3301 }
3302 
3305  Ipv4Header const &ip,
3306  Ptr<Ipv4Interface> incomingInterface)
3307 {
3308  NS_LOG_FUNCTION (this << p << ip << incomingInterface);
3309 
3310  NS_LOG_INFO ("Our own IP address " << m_mainAddress << " The incoming interface address " << incomingInterface);
3311  m_node = GetNode (); // Get the node
3312  Ptr<Packet> packet = p->Copy (); // Save a copy of the received packet
3313  /*
3314  * When forwarding or local deliver packets, this one should be used always!!
3315  */
3316  DsrRoutingHeader dsrRoutingHeader;
3317  packet->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
3318  Ptr<Packet> copy = packet->Copy ();
3319 
3320  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
3321  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
3322  Ipv4Address source = GetIPfromID (sourceId);
3323  NS_LOG_INFO ("The source address " << source << " with source id " << sourceId);
3324  /*
3325  * Get the IP source and destination address
3326  */
3327  Ipv4Address src = ip.GetSource ();
3328 
3329  bool isPromisc = false;
3330  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset (); // Get the offset for option header, 8 bytes in this case
3331 
3332  // This packet is used to peek option type
3333  p->RemoveAtStart (offset);
3334 
3335  Ptr<dsr::DsrOptions> dsrOption;
3336  DsrOptionHeader dsrOptionHeader;
3337  /*
3338  * Peek data to get the option type as well as length and segmentsLeft field
3339  */
3340  uint32_t size = p->GetSize ();
3341  uint8_t *data = new uint8_t[size];
3342  p->CopyData (data, size);
3343 
3344  uint8_t optionType = 0;
3345  uint8_t optionLength = 0;
3346  uint8_t segmentsLeft = 0;
3347 
3348  optionType = *(data);
3349  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet id " << p->GetUid());
3350  dsrOption = GetOption (optionType); // Get the relative dsr option and demux to the process function
3351  Ipv4Address promiscSource;
3352  if (optionType == 1) // This is the request option
3353  {
3354  BlackList *blackList = m_rreqTable->FindUnidirectional (src);
3355  if (blackList)
3356  {
3357  NS_LOG_INFO ("Discard this packet due to unidirectional link");
3358  m_dropTrace (p);
3359  }
3360 
3361  dsrOption = GetOption (optionType);
3362  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3363 
3364  if (optionLength == 0)
3365  {
3366  NS_LOG_INFO ("Discard this packet");
3367  m_dropTrace (p);
3368  }
3369  }
3370  else if (optionType == 2)
3371  {
3372  dsrOption = GetOption (optionType);
3373  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3374 
3375  if (optionLength == 0)
3376  {
3377  NS_LOG_INFO ("Discard this packet");
3378  m_dropTrace (p);
3379  }
3380  }
3381 
3382  else if (optionType == 32) // This is the ACK option
3383  {
3384  NS_LOG_INFO ("This is the ack option");
3385  dsrOption = GetOption (optionType);
3386  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3387 
3388  if (optionLength == 0)
3389  {
3390  NS_LOG_INFO ("Discard this packet");
3391  m_dropTrace (p);
3392  }
3393  }
3394 
3395  else if (optionType == 3) // This is a route error header
3396  {
3397  // populate this route error
3398  NS_LOG_INFO ("The option type value " << (uint32_t)optionType);
3399 
3400  dsrOption = GetOption (optionType);
3401  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3402 
3403  if (optionLength == 0)
3404  {
3405  NS_LOG_INFO ("Discard this packet");
3406  m_dropTrace (p);
3407  }
3408  NS_LOG_INFO ("The option Length " << (uint32_t)optionLength);
3409  }
3410 
3411  else if (optionType == 96) // This is the source route option
3412  {
3413  dsrOption = GetOption (optionType);
3414  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
3415  segmentsLeft = *(data + 3);
3416  if (optionLength == 0)
3417  {
3418  NS_LOG_INFO ("Discard this packet");
3419  m_dropTrace (p);
3420  }
3421  else
3422  {
3423  if (segmentsLeft == 0)
3424  {
3425  // / Get the next header
3426  uint8_t nextHeader = dsrRoutingHeader.GetNextHeader ();
3428  Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol (nextHeader);
3429  if (nextProto != 0)
3430  {
3431  // we need to make a copy in the unlikely event we hit the
3432  // RX_ENDPOINT_UNREACH code path
3433  // Here we can use the packet that has been get off whole DSR header
3434  enum IpL4Protocol::RxStatus status =
3435  nextProto->Receive (copy, ip, incomingInterface);
3436  NS_LOG_DEBUG ("The receive status " << status);
3437  switch (status)
3438  {
3439  case IpL4Protocol::RX_OK:
3440  // fall through
3442  // fall through
3444  break;
3446  if (ip.GetDestination ().IsBroadcast () == true
3447  || ip.GetDestination ().IsMulticast () == true)
3448  {
3449  break; // Do not reply to broadcast or multicast
3450  }
3451  // Another case to suppress ICMP is a subnet-directed broadcast
3452  }
3453  return status;
3454  }
3455  else
3456  {
3457  NS_FATAL_ERROR ("Should not have 0 next protocol value");
3458  }
3459  }
3460  else
3461  {
3462  NS_LOG_INFO ("This is not the final destination, the packet has already been forward to next hop");
3463  }
3464  }
3465  }
3466  else
3467  {
3468  NS_LOG_LOGIC ("Unknown Option. Drop!");
3469  /*
3470  * Initialize the salvage value to 0
3471  */
3472  uint8_t salvage = 0;
3473 
3474  DsrOptionRerrUnsupportHeader rerrUnsupportHeader;
3475  rerrUnsupportHeader.SetErrorType (3); // The error type 3 means Option not supported
3476  rerrUnsupportHeader.SetErrorSrc (m_mainAddress); // The error source address is our own address
3477  rerrUnsupportHeader.SetUnsupported (optionType); // The unsupported option type number
3478  rerrUnsupportHeader.SetErrorDst (src); // Error destination address is the destination of the data packet
3479  rerrUnsupportHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
3480 
3481  /*
3482  * The unknow option error is not supported currently in this implementation, and it's also not likely to
3483  * happen in simulations
3484  */
3485 // SendError (rerrUnsupportHeader, 0, protocol); // Send the error packet
3486  }
3487  return IpL4Protocol::RX_OK;
3488 }
3489 
3492  Ipv6Header const &ip,
3493  Ptr<Ipv6Interface> incomingInterface)
3494 {
3495  NS_LOG_FUNCTION (this << p << ip.GetSourceAddress () << ip.GetDestinationAddress () << incomingInterface);
3497 }
3498 
3499 void
3501 {
3502  m_downTarget = callback;
3503 }
3504 
3505 void
3507 {
3508  NS_FATAL_ERROR ("Unimplemented");
3509 }
3510 
3511 
3514 {
3515  return m_downTarget;
3516 }
3517 
3520 {
3521  NS_FATAL_ERROR ("Unimplemented");
3522  return MakeNullCallback<void,Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route> > ();
3523 }
3524 
3526 {
3527  m_options.push_back (option);
3528 }
3529 
3531 {
3532  for (DsrOptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
3533  {
3534  if ((*i)->GetOptionNumber () == optionNumber)
3535  {
3536  return *i;
3537  }
3538  }
3539  return 0;
3540 }
3541 } /* namespace dsr */
3542 } /* namespace ns3 */
uint32_t m_sendRetries
of retries have been sent for network acknowledgment
Definition: dsr-routing.h:631
uint32_t m_stabilityDecrFactor
The initial decrease factor for link cache.
Definition: dsr-routing.h:703
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
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()
Number of entries.
void AddNodeAddress(Ipv4Address ipv4)
Add one node address.
void UseExtends(DsrRouteCacheEntry::IP_VECTOR rt)
functions used to direct to route cache
Definition: dsr-routing.cc:648
void SetRequestTable(Ptr< dsr::DsrRreqTable > r)
Set the node.
Definition: dsr-routing.cc:599
virtual void SetErrorSrc(Ipv4Address errorSrcAddress)
Set the route error source address.
std::string m_cacheType
The type of route cache.
Definition: dsr-routing.h:699
Ptr< dsr::DsrPassiveBuffer > GetPassiveBuffer() const
Get the passive buffer.
Definition: dsr-routing.cc:619
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Definition: dsr-rcache.h:174
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 this RNG stream.
Ipv4Address GetDst() const
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:34
uint8_t GetSegsLeft() const
virtual void DoDispose(void)
Drop trace callback.
Definition: dsr-routing.cc:550
uint32_t m_maxSendBuffLen
The maximum number of packets that we allow a routing protocol to buffer.
Definition: dsr-routing.h:643
Ipv4Address GetOurAdd() const
void ScheduleInterRequest(Ptr< Packet > packet)
Schedule the intermediate route request.
A simple Timer class.
Definition: timer.h:73
uint32_t m_stabilityIncrFactor
The initial increase factor for link cache.
Definition: dsr-routing.h:705
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
bool LookupRoute(Ipv4Address id, DsrRouteCacheEntry &rt)
functions used to direct to route cache
Definition: dsr-routing.cc:653
void SetMaxQueueLen(uint32_t len)
void SendInitialRequest(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
Broadcast the route request packet in subnet.
Ptr< const Packet > GetPacket() const
Definition: dsr-rsendbuff.h:75
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:462
bool FindAndUpdate(Ipv4Address replyTo, Ipv4Address replyFrom, Time gratReplyHoldoff)
Update the route entry if found, create a new one if not.
Hold variables of type string.
Definition: string.h:41
void SendBuffTimerExpire()
The send buffer timer expire.
Definition: dsr-routing.cc:822
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
void Scheduler(uint32_t priority)
This function is called to schedule sending packets from the network queue.
bool NetworkEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for network ack.
DSR Maintain Buffer Entry.
virtual Ipv4Address GetErrorSrc() const
Get the route error source address.
void SalvagePacket(Ptr< const Packet > packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol)
Salvage the packet which has been transmitted for 3 times.
Time m_sendBuffInterval
how often to check send buffer
Definition: dsr-routing.h:691
Time m_passiveAckTimeout
The timeout value for passive acknowledge.
Definition: dsr-routing.h:681
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
Ipv4Address GetSrc() const
uint32_t m_discoveryHopLimit
Maximum hops to go for route request.
Definition: dsr-routing.h:623
uint32_t GetPriority(DsrMessageType messageType)
Set the priority of the packet in network queue.
Definition: dsr-routing.cc:810
Ptr< Ipv4 > m_ip
The ip ptr.
Definition: dsr-routing.h:609
bool Find(Ipv4Address dst)
Finds whether a packet with destination dst exists in the queue.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
uint8_t GetMessageType() const
brief Get the message type of the header.
uint32_t m_linkRetries
of retries have been sent for link acknowledgment
Definition: dsr-routing.h:635
TracedCallback< const DsrOptionSRHeader & > m_txPacketTrace
Definition: dsr-routing.h:575
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:368
void SetNextHeader(uint8_t protocol)
Set the "Next header" field.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void SetDst(Ipv4Address n)
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
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:673
Time m_maxRequestPeriod
The max request period.
Definition: dsr-routing.h:695
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:707
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
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:606
Ptr< dsr::DsrRreqTable > GetRequestTable() const
Get the request table.
Definition: dsr-routing.cc:606
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
IP_VECTOR GetVector() const
Definition: dsr-rcache.h:211
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:903
uint32_t m_maxEntriesEachDst
Max number of route entries to save for each destination.
Definition: dsr-routing.h:661
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
void IncreaseRetransTimer()
This function is called to increase the retransmission timer for data packet in the network queue...
void SetSegmentsLeft(uint8_t segmentsLeft)
bool IsMulticast(void) const
DSR Error Buffer Entry.
Definition: dsr-errorbuff.h:45
Ipv4Address m_mainAddress
Our own Ip address.
Definition: dsr-routing.h:613
bool AllEqual(DsrMaintainBuffEntry &entry)
Verify if all the elements in the maintainence buffer entry is the same.
Ipv4Address SearchNextHop(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Get the next hop of the route.
Definition: dsr-routing.cc:727
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
uint16_t GetAckId() const
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
void CancelPacketAllTimer(DsrMaintainBuffEntry &mb)
Cancel all the packet timers.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:719
bool IsLinkCache()
functions used to direct to route cache
Definition: dsr-routing.cc:643
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:685
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
std::vector< Ipv4Address > GetNodesAddress() const
Get the vector of ipv4 address.
Ipv4Address GetNextHop() const
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:1112
void SetSegsLeft(uint8_t segs)
uint32_t m_requestTableSize
The max size of the request table size.
Definition: dsr-routing.h:669
Source Route (SR) Message Format.
void ScheduleCachedReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, Ptr< Ipv4Route > route, double hops)
Schedule the cached reply to a random start time to avoid possible route reply storm.
void SetDestId(uint16_t destId)
brief Set the dest ID of the header.
uint32_t m_tryLinkAcks
Maximum number of packet transmission using link acknowledgment.
Definition: dsr-routing.h:687
RxStatus
Rx status codes.
uint8_t GetLength() const
Get the option length.
Acknowledgement Request (ACK_RREQ) Message Format.
void ForwardErrPacket(DsrOptionRerrUnreachHeader &rerr, DsrOptionSRHeader &sourceRoute, Ipv4Address nextHop, uint8_t protocol, Ptr< Ipv4Route > route)
This function is responsible for forwarding error packets along the route.
Time m_maxCacheTime
Max time for caching the route cache entry.
Definition: dsr-routing.h:657
Ipv4Address GetUnreachNode() const
Get the unreachable node ip address.
Time m_gratReplyHoldoff
The max gratuitous reply hold off time.
Definition: dsr-routing.h:693
a polymophic address class
Definition: address.h:90
Ptr< const Packet > GetPacket() const
uint32_t m_maxMaintainLen
Max # of entries for maintainance buffer.
Definition: dsr-routing.h:651
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:794
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
bool IsRunning(void) const
Definition: timer.cc:127
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
std::vector< Ipv4Address > m_finalRoute
The route cache.
Definition: dsr-routing.h:717
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:697
bool AddRoute(DsrRouteCacheEntry &rt)
functions used to direct to route cache
Definition: dsr-routing.cc:665
DsrMaintainBuffer m_maintainBuffer
The declaration of maintain buffer.
Definition: dsr-routing.h:663
void SetDestination(Ipv4Address d)
Packet header for IPv4.
Definition: ipv4-header.h:33
Time m_maxNetworkDelay
Maximum network delay.
Definition: dsr-routing.h:621
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
virtual void SetSalvage(uint8_t salvage)
Set the salvage value of the packet.
Route Reply (RREP) Message Format.
uint16_t m_ackId
The ack id assigned to each acknowledge.
Definition: dsr-routing.h:667
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.
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:340
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:1238
DsrGraReply m_graReply
The gratuitous route reply.
Definition: dsr-routing.h:747
void DropPacketForErrLink(Ipv4Address source, Ipv4Address nextHop)
Remove all packets with the error link.
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:610
AttributeValue implementation for Time.
Definition: nstime.h:957
virtual void SetErrorDst(Ipv4Address errorDstAddress)
Set the error destination ip address.
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
void CancelPassivePacketTimer(DsrMaintainBuffEntry &mb)
Cancel the passive packet retransmission timer for a specific maintenance entry.
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)
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:645
int GetProtocolNumber(void) const
Get the dsr protocol number.
Definition: dsr-routing.cc:771
uint8_t data[writeSize]
Ipv4Address m_broadcast
The broadcast IP address.
Definition: dsr-routing.h:677
uint32_t GetSize()
Number of entries.
void SetSendBufferTimeout(Time t)
Set the entry lifetime in the queue.
bool IsBroadcast(void) const
uint32_t m_numPriorityQueues
The number of priority queues used.
Definition: dsr-routing.h:741
Ipv4Address GetOriginalDst() const
Get the unreachable node ip address.
uint32_t m_broadcastJitter
The max time to delay route request broadcast.
Definition: dsr-routing.h:679
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:574
static const uint8_t PROT_NUMBER
Define the dsr protocol number.
Definition: dsr-routing.h:106
uint32_t m_requestId
The id assigned to each route request.
Definition: dsr-routing.h:665
DsrErrorBuffer m_errorBuffer
The error buffer to save the error messages.
Definition: dsr-routing.h:649
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
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 destination 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:605
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:671
bool AddRoute_Link(DsrRouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source)
functions used to direct to route cache
Definition: dsr-routing.cc:658
void SendReply(Ptr< Packet > packet, Ipv4Address source, Ipv4Address nextHop, Ptr< Ipv4Route > route)
Send the route reply back to the request originator with the cumulated route.
DSR Network Queue Entry.
Ptr< const Packet > GetPacket() const
bool UpdateRouteEntry(Ipv4Address dst)
functions used to direct to route cache
Definition: dsr-routing.cc:678
Time m_minLifeTime
The min life time.
Definition: dsr-routing.h:709
void SetFragmentOffset(uint16_t f)
std::vector< Ipv4Address > IP_VECTOR
Define the vector to hold Ip address.
Definition: dsr-rcache.h:177
Time m_useExtends
The use extension of the life time for link cache.
Definition: dsr-routing.h:711
tuple mac
Definition: third.py:92
DSR Passive Buffer Entry.
void SetMaxQueueLen(uint32_t len)
uint16_t GetSourceId() const
brief Get the source ID of the header.
void SchedulePassivePacketRetry(DsrMaintainBuffEntry &mb, uint8_t protocol)
Schedule the packet retransmission based on passive acknowledgment.
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...
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
Time m_blacklistTimeout
The black list time out.
Definition: dsr-routing.h:675
bool Enqueue(DsrErrorBuffEntry &entry)
Push entry in queue, if there is no entry with the same packet and destination address in queue...
std::map< NetworkKey, Timer > m_addressForwardTimer
Map network key + forward timer.
Definition: dsr-routing.h:723
static Mac48Address ConvertFrom(const Address &address)
std::map< Ipv4Address, Timer > m_addressReqTimer
Map IP address + RREQ timer.
Definition: dsr-routing.h:719
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:612
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
void SetRealDst(Ipv4Address realDstAddress)
Set Error source ip address.
bool PromiscEqual(DsrMaintainBuffEntry &entry)
Verify if the maintain buffer entry is the same in every field for promiscuous ack.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
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...
uint8_t m_maxSalvageCount
Maximum # times to salvage a packet.
Definition: dsr-routing.h:625
Ipv4Address GetNextHopAddress() const
Time m_initStability
The initial stability value for link cache.
Definition: dsr-routing.h:707
void SetExpireTime(Time exp)
void SetPayloadLength(uint16_t length)
brief Set the payload length of the header.
Time m_requestPeriod
The base time interval between route requests.
Definition: dsr-routing.h:627
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:778
Hold objects of type Ptr.
Definition: pointer.h:36
Ptr< Node > m_node
The node ptr.
Definition: dsr-routing.h:611
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:633
uint32_t m_maxNetworkSize
Maximum network queue size.
Definition: dsr-routing.h:619
Packet addressed to someone else.
Definition: net-device.h:614
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:760
uint16_t GetDestId() const
brief Get the dest ID of the header.
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
This function is called by higher layer protocol when sending packets.
uint32_t m_tryPassiveAcks
Maximum number of packet transmission using passive acknowledgment.
Definition: dsr-routing.h:683
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)
uint32_t m_maxMaintRexmt
Maximum number of retransmissions of data packets.
Definition: dsr-routing.h:639
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.
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:715
void ForwardPacket(Ptr< const Packet > packet, DsrOptionSRHeader &sourceRoute, Ipv4Header const &ipv4Header, Ipv4Address source, Ipv4Address destination, Ipv4Address targetAddress, uint8_t protocol, Ptr< Ipv4Route > route)
Forward the packet using the route saved in the source route option header.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
uint8_t GetNextHeader() const
Get the next header.
std::map< LinkKey, Timer > m_linkAckTimer
The timer for link acknowledgment.
Definition: dsr-routing.h:733
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1401
virtual Ipv4Address GetErrorDst() const
Get the error destination ip address.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:958
BlackList description.
L4 Protocol abstract base class.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
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.
void SetSegsLeft(uint8_t seg)
void ScheduleRreqRetry(Ptr< Packet > packet, std::vector< Ipv4Address > address, bool nonProp, uint32_t requestId, uint8_t protocol)
Schedule the route request retry.
void SetMessageType(uint8_t messageType)
brief Set the message type of the header.
IpL4Protocol::DownTargetCallback GetDownTarget(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
uint32_t m_maxRreqId
The max number of request ids for a single destination.
Definition: dsr-routing.h:673
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:735
uint32_t m_maxCacheLen
Max # of cache entries for route cache.
Definition: dsr-routing.h:655
void SetSource(Ipv4Address s)
void SetUnreachNode(Ipv4Address unreachNode)
Set the unreachable node ip address.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
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)
void CheckSendBuffer()
Check the send buffer of packets with route when send buffer timer expire.
Definition: dsr-routing.cc:832
std::map< uint32_t, Ptr< dsr::DsrNetworkQueue > > m_priorityQueue
priority queues
Definition: dsr-routing.h:745
Ipv4Address GetSourceAddress() const
Describes an IPv6 address.
Definition: ipv6-address.h:48
std::map< PassiveKey, uint32_t > m_passiveCnt
Map packet key + passive forward counts.
Definition: dsr-routing.h:727
Ptr< Ipv4Route > GetIpv4Route() const
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: dsr-routing.cc:397
TracedCallback< Ptr< const Packet > > m_dropTrace
The trace for drop, receive and send data packets.
Definition: dsr-routing.h:574
void SetMaxQueueLen(uint32_t len)
Set the maximum queue length.
Ptr< const Packet > GetPacket() const
Definition: dsr-errorbuff.h:79
std::map< PassiveKey, Timer > m_passiveAckTimer
The timer for passive acknowledgment.
Definition: dsr-routing.h:729
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.
Ptr< dsr::DsrRouteCache > GetRouteCache() const
Get the route cache.
Definition: dsr-routing.cc:593
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.
Ptr< Ipv4Route > m_ipv4Route
Ipv4 Route.
Definition: dsr-routing.h:607
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:641
void SetPacket(Ptr< const Packet > p)
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
void SetRouteCache(Ptr< dsr::DsrRouteCache > r)
Set the route cache.
Definition: dsr-routing.cc:586
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
bool m_subRoute
Whether to save sub route or not.
Definition: dsr-routing.h:713
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
Route Error (RERR) Unreachable node address option Message Format.
void Cancel(void)
Cancel the currently-running event if there is one.
Definition: timer.cc:109
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:689
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:637
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.
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:689
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:683
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:356
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
Definition: dsr-routing.h:757
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
Ptr< Node > GetNodeWithAddress(Ipv4Address ipv4Address)
Get the node with give ip address.
Definition: dsr-routing.cc:626
tuple wifi
Definition: third.py:89
DsrOptionList_t m_options
List of DSR Options supported.
Definition: dsr-routing.h:603
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.
tuple address
Definition: first.py:37
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: string.h:42
Header of Dsr Routing.
Ptr< Node > GetNode() const
Get the node.
Definition: dsr-routing.cc:580
std::map< LinkKey, uint32_t > m_linkCnt
Map packet key + link forward counts.
Definition: dsr-routing.h:731
bool IsSuspended(void) const
Definition: timer.cc:133
void SetAckId(uint16_t identification)
Set the Ack id number.
void SetIdentification(uint16_t i)
This policy cancels the event from the destructor of the Timer to verify that the event has already e...
Definition: timer.h:86
virtual uint8_t GetSalvage() const
Get the salvage value of the packet.
IpL4Protocol::DownTargetCallback6 GetDownTarget6(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
std::map< NetworkKey, uint32_t > m_addressForwardCnt
Map network key + forward counts.
Definition: dsr-routing.h:725
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
Dsr Routing base.
Definition: dsr-routing.h:95
a unique identifier for an interface.
Definition: type-id.h:58
Time m_nonpropRequestTimeout
The non-propagation request timeout.
Definition: dsr-routing.h:629
void SetSalvage(uint8_t salvage)
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
std::map< Ipv4Address, Timer > m_nonPropReqTimer
Map IP address + RREQ timer.
Definition: dsr-routing.h:721
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:743
std::vector< std::string > GetElementsFromContext(std::string context)
Get the elements from the tracing context.
Definition: dsr-routing.cc:534
void SetOriginalDst(Ipv4Address originalDst)
Set the unreachable node ip address.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Ptr< dsr::DsrRreqTable > m_rreqTable
A "drop-front" queue used by the routing layer to cache route request sent.
Definition: dsr-routing.h:737
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
Ptr< dsr::DsrPassiveBuffer > m_passiveBuffer
A "drop-front" queue used by the routing layer to cache route request sent.
Definition: dsr-routing.h:739
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:617
DsrRouting()
Constructor.
Definition: dsr-routing.cc:356
DsrSendBuffer m_sendBuffer
The send buffer.
Definition: dsr-routing.h:647
void SetSrc(Ipv4Address s)
Time m_maxMaintainTime
Time out for maintainance buffer.
Definition: dsr-routing.h:653
void CancelRreqTimer(Ipv4Address dst, bool isRemove)
Cancel the route request timer.
virtual ~DsrRouting()
Destructor.
Definition: dsr-routing.cc:391