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