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