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