A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
dsr-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Yufei Cheng
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
19  *
20  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
21  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
22  * Information and Telecommunication Technology Center (ITTC)
23  * and Department of Electrical Engineering and Computer Science
24  * The University of Kansas Lawrence, KS USA.
25  *
26  * Work supported in part by NSF FIND (Future Internet Design) Program
27  * under grant CNS-0626918 (Postmodern Internet Architecture),
28  * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
29  * US Department of Defense (DoD), and ITTC at The University of Kansas.
30  */
31 
32 #define NS_LOG_APPEND_CONTEXT \
33  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
34 
35 #include <list>
36 #include <ctime>
37 #include <map>
38 #include <limits>
39 #include <algorithm>
40 #include <iostream>
41 
42 #include "ns3/enum.h"
43 #include "ns3/string.h"
44 #include "ns3/ptr.h"
45 #include "ns3/log.h"
46 #include "ns3/assert.h"
47 #include "ns3/uinteger.h"
48 #include "ns3/packet.h"
49 #include "ns3/boolean.h"
50 #include "ns3/node-list.h"
51 #include "ns3/double.h"
52 #include "ns3/pointer.h"
53 #include "ns3/object-vector.h"
54 #include "ns3/ipv4-address.h"
55 #include "ns3/ipv4-header.h"
56 #include "ns3/ipv4-l3-protocol.h"
57 #include "ns3/ipv4-route.h"
58 #include "ns3/trace-source-accessor.h"
59 #include "ns3/icmpv4-l4-protocol.h"
60 #include "ns3/adhoc-wifi-mac.h"
61 #include "ns3/wifi-net-device.h"
62 #include "ns3/inet-socket-address.h"
63 #include "ns3/udp-l4-protocol.h"
64 #include "ns3/udp-socket-factory.h"
65 #include "ns3/tcp-socket-factory.h"
66 
67 #include "dsr-rreq-table.h"
68 #include "dsr-rcache.h"
69 #include "dsr-routing.h"
70 #include "dsr-fs-header.h"
71 #include "dsr-options.h"
72 
73 NS_LOG_COMPONENT_DEFINE ("DsrRouting");
74 
75 namespace ns3 {
76 namespace dsr {
77 
78 NS_OBJECT_ENSURE_REGISTERED (DsrRouting);
79 
80 /* see http://www.iana.org/assignments/protocol-numbers */
81 const uint8_t DsrRouting::PROT_NUMBER = 48;
82 /*
83  * The extension header is the fixed size dsr header, it is response for recognizing DSR option types
84  * and demux to right options to process the packet.
85  *
86  * The header format with neighboring layers is as follows:
87  *
88  +-+-+-+-+-+-+-+-+-+-+-
89  | Application Header |
90  +-+-+-+-+-+-+-+-+-+-+-+
91  | Transport Header |
92  +-+-+-+-+-+-+-+-+-+-+-+
93  | Fixed DSR Header |
94  +---------------------+
95  | DSR Options |
96  +-+-+-+-+-+-+-+-+-+-+-+
97  | IP Header |
98  +-+-+-+-+-+-+-+-+-+-+-+
99  */
100 
102 {
103  static TypeId tid = TypeId ("ns3::dsr::DsrRouting")
105  .AddConstructor<DsrRouting> ()
106  .AddAttribute ("RouteCache", "The route cache for saving routes from route discovery process.",
107  PointerValue (0),
108  MakePointerAccessor (&DsrRouting::SetRouteCache,
110  MakePointerChecker<RouteCache> ())
111  .AddAttribute ("RreqTable", "The request table to manage route requests.",
112  PointerValue (0),
113  MakePointerAccessor (&DsrRouting::SetRequestTable,
115  MakePointerChecker<RreqTable> ())
116  .AddAttribute ("MaxSendBuffLen","Maximum number of packets that can be stored in send buffer.",
117  UintegerValue (64),
118  MakeUintegerAccessor (&DsrRouting::m_maxSendBuffLen),
119  MakeUintegerChecker<uint32_t> ())
120  .AddAttribute ("MaxSendBuffTime","Maximum time packets can be queued in the send buffer .",
121  TimeValue (Seconds (30)),
122  MakeTimeAccessor (&DsrRouting::m_sendBufferTimeout),
123  MakeTimeChecker ())
124  .AddAttribute ("MaxMaintLen","Maximum number of packets that can be stored in maintenance buffer.",
125  UintegerValue (50),
126  MakeUintegerAccessor (&DsrRouting::m_maxMaintainLen),
127  MakeUintegerChecker<uint32_t> ())
128  .AddAttribute ("MaxMaintTime","Maximum time packets can be queued in maintenance buffer.",
129  TimeValue (Seconds (30)),
130  MakeTimeAccessor (&DsrRouting::m_maxMaintainTime),
131  MakeTimeChecker ())
132  .AddAttribute ("MaxCacheLen","Maximum number of route entries that can be stored in route cache.",
133  UintegerValue (64),
134  MakeUintegerAccessor (&DsrRouting::m_maxCacheLen),
135  MakeUintegerChecker<uint32_t> ())
136  .AddAttribute ("RouteCacheTimeout","Maximum time the route cache can be queued in route cache.",
137  TimeValue (Seconds (300)),
138  MakeTimeAccessor (&DsrRouting::m_maxCacheTime),
139  MakeTimeChecker ())
140  .AddAttribute ("MaxEntriesEachDst","Maximum number of route entries for a single destination to respond.",
141  UintegerValue (20),
142  MakeUintegerAccessor (&DsrRouting::m_maxEntriesEachDst),
143  MakeUintegerChecker<uint32_t> ())
144  .AddAttribute ("SendBuffInterval","How often to check send buffer for packet with route.",
145  TimeValue (Seconds (500)),
146  MakeTimeAccessor (&DsrRouting::m_sendBuffInterval),
147  MakeTimeChecker ())
148  .AddAttribute ("NodeTraversalTime","The time it takes to traverse two neighboring nodes.",
149  TimeValue (MilliSeconds (40)),
150  MakeTimeAccessor (&DsrRouting::m_nodeTraversalTime),
151  MakeTimeChecker ())
152  .AddAttribute ("RreqRetries","Maximum number of retransmissions for request discovery of a route.",
153  UintegerValue (16),
154  MakeUintegerAccessor (&DsrRouting::m_rreqRetries),
155  MakeUintegerChecker<uint32_t> ())
156  .AddAttribute ("MaintenanceRetries","Maximum number of retransmissions for data packets from maintenance buffer.",
157  DoubleValue (2),
158  MakeDoubleAccessor (&DsrRouting::m_maxMaintRexmt),
159  MakeDoubleChecker<uint32_t> ())
160  .AddAttribute ("RequestTableSize","Maximum number of request entries in the request table.",
161  UintegerValue (64),
162  MakeUintegerAccessor (&DsrRouting::m_requestTableSize),
163  MakeUintegerChecker<uint32_t> ())
164  .AddAttribute ("RequestIdSize","Maximum number of request source Ids in the request table.",
165  UintegerValue (16),
166  MakeUintegerAccessor (&DsrRouting::m_requestTableIds),
167  MakeUintegerChecker<uint32_t> ())
168  .AddAttribute ("UniqueRequestIdSize","Maximum number of request Ids in the request table for a single destination.",
169  UintegerValue (256),
170  MakeUintegerAccessor (&DsrRouting::m_maxRreqId),
171  MakeUintegerChecker<uint16_t> ())
172  .AddAttribute ("NonPropRequestTimeout","The timeout value for non-propagation request.",
173  TimeValue (MilliSeconds (30)),
174  MakeTimeAccessor (&DsrRouting::m_nonpropRequestTimeout),
175  MakeTimeChecker ())
176  .AddAttribute ("DiscoveryHopLimit","The max discovery hop limit for route requests.",
177  DoubleValue (255),
178  MakeDoubleAccessor (&DsrRouting::m_discoveryHopLimit),
179  MakeDoubleChecker<uint32_t> ())
180  .AddAttribute ("MaxSalvageCount","The max salvage count for a single data packet.",
181  UintegerValue (15),
182  MakeUintegerAccessor (&DsrRouting::m_maxSalvageCount),
183  MakeUintegerChecker<uint8_t> ())
184  .AddAttribute ("BlacklistTimeout","The time for a neighbor to stay in blacklist.",
185  TimeValue (Seconds (3)),
186  MakeTimeAccessor (&DsrRouting::m_blacklistTimeout),
187  MakeTimeChecker ())
188  .AddAttribute ("GratReplyHoldoff","The time for gratuitous reply entry to expire.",
189  TimeValue (Seconds (1)),
190  MakeTimeAccessor (&DsrRouting::m_gratReplyHoldoff),
191  MakeTimeChecker ())
192  .AddAttribute ("BroadcastJitter","The jitter time to avoid collision for broadcast packets.",
193  UintegerValue (10),
194  MakeUintegerAccessor (&DsrRouting::m_broadcastJitter),
195  MakeUintegerChecker<uint16_t> ())
196  .AddAttribute ("PassiveAckTimeout","The time a packet in maintenance buffer wait for passive acknowledgment.",
197  TimeValue (MilliSeconds (100)),
198  MakeTimeAccessor (&DsrRouting::m_passiveAckTimeout),
199  MakeTimeChecker ())
200  .AddAttribute ("TryPassiveAcks","The number of passive acknowledgment to use.",
201  UintegerValue (1),
202  MakeUintegerAccessor (&DsrRouting::m_tryPassiveAcks),
203  MakeUintegerChecker<uint32_t> ())
204  .AddAttribute ("RequestPeriod","The base time interval between route requests.",
205  TimeValue (MilliSeconds (500)),
206  MakeTimeAccessor (&DsrRouting::m_requestPeriod),
207  MakeTimeChecker ())
208  .AddAttribute ("MaxRequestPeriod","The max time interval between route requests.",
209  TimeValue (Seconds (10)),
210  MakeTimeAccessor (&DsrRouting::m_maxRequestPeriod),
211  MakeTimeChecker ())
212  .AddAttribute ("GraReplyTableSize","The gratuitous reply table size.",
213  UintegerValue (64),
214  MakeUintegerAccessor (&DsrRouting::m_graReplyTableSize),
215  MakeUintegerChecker<uint32_t> ())
216  .AddAttribute ("CacheType","Use Link Cache or use Path Cache",
217  StringValue ("LinkCache"),
218  MakeStringAccessor (&DsrRouting::m_cacheType),
219  MakeStringChecker ())
220  .AddAttribute ("StabilityDecrFactor","The stability decrease factor for link cache",
221  UintegerValue (2),
222  MakeUintegerAccessor (&DsrRouting::m_stabilityDecrFactor),
223  MakeUintegerChecker<uint64_t> ())
224  .AddAttribute ("StabilityIncrFactor","The stability increase factor for link cache",
225  UintegerValue (4),
226  MakeUintegerAccessor (&DsrRouting::m_stabilityIncrFactor),
227  MakeUintegerChecker<uint64_t> ())
228  .AddAttribute ("InitStability","The initial stability factor for link cache",
229  TimeValue (Seconds (25)),
230  MakeTimeAccessor (&DsrRouting::m_initStability),
231  MakeTimeChecker ())
232  .AddAttribute ("MinLifeTime","The minimal life time for link cache",
233  TimeValue (Seconds (1)),
234  MakeTimeAccessor (&DsrRouting::m_minLifeTime),
235  MakeTimeChecker ())
236  .AddAttribute ("UseExtends","The extension time for link cache",
237  TimeValue (Seconds (120)),
238  MakeTimeAccessor (&DsrRouting::m_useExtends),
239  MakeTimeChecker ())
240  .AddAttribute ("EnableSubRoute","Enables saving of sub route when receiving route error messages, only available when using path route cache",
241  BooleanValue (true),
242  MakeBooleanAccessor (&DsrRouting::m_subRoute),
243  MakeBooleanChecker ())
244  .AddAttribute ("RetransIncr","The increase time for retransmission timer when facing network congestion",
245  TimeValue (MilliSeconds (20)),
246  MakeTimeAccessor (&DsrRouting::m_retransIncr),
247  MakeTimeChecker ())
248  .AddAttribute ("MaxNetworkQueueSize","The max number of packet to save in the network queue.",
249  UintegerValue (400),
250  MakeUintegerAccessor (&DsrRouting::m_maxNetworkSize),
251  MakeUintegerChecker<uint32_t> ())
252  .AddAttribute ("MaxNetworkQueueDelay","The max time for a packet to stay in the network queue.",
253  TimeValue (Seconds (30.0)),
254  MakeTimeAccessor (&DsrRouting::m_maxNetworkDelay),
255  MakeTimeChecker ())
256  .AddAttribute ("NumPriorityQueues","The max number of packet to save in the network queue.",
257  UintegerValue (2),
258  MakeUintegerAccessor (&DsrRouting::m_numPriorityQueues),
259  MakeUintegerChecker<uint32_t> ())
260  .AddTraceSource ("Tx", "Send DSR packet.",
262  .AddTraceSource ("Drop", "Drop DSR packet",
264  ;
265  return tid;
266 }
267 
269 {
271 
272  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
273 
274  /*
275  * The following Ptr statements created objects for all the options header for DSR, and each of them have
276  * distinct option number assigned, when DSR Routing received a packet from higher layer, it will find
277  * the following options based on the option number, and pass the packet to the appropriate option to
278  * process it. After the option processing, it will pass the packet back to DSR Routing to send down layer.
279  */
280  Ptr<dsr::DsrOptionPad1> pad1Option = CreateObject<dsr::DsrOptionPad1> ();
281  Ptr<dsr::DsrOptionPadn> padnOption = CreateObject<dsr::DsrOptionPadn> ();
282  Ptr<dsr::DsrOptionRreq> rreqOption = CreateObject<dsr::DsrOptionRreq> ();
283  Ptr<dsr::DsrOptionRrep> rrepOption = CreateObject<dsr::DsrOptionRrep> ();
284  Ptr<dsr::DsrOptionSR> srOption = CreateObject<dsr::DsrOptionSR> ();
285  Ptr<dsr::DsrOptionRerr> rerrOption = CreateObject<dsr::DsrOptionRerr> ();
286  Ptr<dsr::DsrOptionAckReq> ackReq = CreateObject<dsr::DsrOptionAckReq> ();
287  Ptr<dsr::DsrOptionAck> ack = CreateObject<dsr::DsrOptionAck> ();
288 
289  Insert (pad1Option);
290  Insert (padnOption);
291  Insert (rreqOption);
292  Insert (rrepOption);
293  Insert (srOption);
294  Insert (rerrOption);
295  Insert (ackReq);
296  Insert (ack);
297 
298  // Check the send buffer for sending packets
301 }
302 
304 {
306 }
307 
308 void
310 {
311  NS_LOG_FUNCTION (this << "NotifyNewAggregate");
312  if (m_node == 0)
313  {
314  Ptr<Node> node = this->GetObject<Node> ();
315  if (node != 0)
316  {
317  m_ipv4 = this->GetObject<Ipv4L3Protocol> ();
318  if (m_ipv4 != 0)
319  {
320  this->SetNode (node);
321  m_ipv4->Insert (this);
323  }
324 
325  m_ip = node->GetObject<Ipv4> ();
326  if (m_ip != 0)
327  {
328  NS_LOG_DEBUG ("Ipv4 started");
329  }
330  }
331  }
334 }
335 
337 {
338  NS_LOG_FUNCTION (this << "Start DSR Routing protocol");
339  Ptr<dsr::RouteCache> routeCache = CreateObject<dsr::RouteCache> ();
340  // Configure the path cache parameters
341  routeCache->SetCacheType (m_cacheType);
342  routeCache->SetSubRoute (m_subRoute);
343  routeCache->SetMaxCacheLen (m_maxCacheLen);
344  routeCache->SetCacheTimeout (m_maxCacheTime);
346  // Parameters for link cache
349  routeCache->SetInitStability (m_initStability);
350  routeCache->SetMinLifeTime (m_minLifeTime);
351  routeCache->SetUseExtends (m_useExtends);
352  routeCache->ScheduleTimer ();
353  // The call back to handle link error and send error message to appropriate nodes
355  SetRouteCache (routeCache);
356 
357  if (m_mainAddress == Ipv4Address ())
358  {
359  Ipv4Address loopback ("127.0.0.1");
360  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
361  {
362  // Use primary address, if multiple
363  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
365  NS_LOG_DEBUG ("The addr " << addr);
366  if (addr != loopback)
367  {
368  m_mainAddress = addr;
369  NS_LOG_DEBUG ("The node Address " << m_mainAddress);
370 
372 
373  // Allow neighbor manager use this interface for layer 2 feedback if possible
376  if (wifi == 0)
377  {
378  break;
379  }
380  Ptr<WifiMac> mac = wifi->GetMac ();
381  if (mac == 0)
382  {
383  break;
384  }
385 
386  // trace back to link mac drop event to process tx error call back
387  mac->TraceConnectWithoutContext ("TxErrHeader", routeCache->GetTxErrorCallback ());
388  routeCache->AddArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
389  break;
390  }
391  }
393  }
394 
395  NS_LOG_DEBUG ("The number queues " << m_numPriorityQueues);
396  for (uint32_t i = 0; i < m_numPriorityQueues; i++)
397  {
398  // Set the network queue max size and the delay
399  NS_LOG_DEBUG ("The network size " << m_maxNetworkSize << " and the network delay " << m_maxNetworkDelay.GetSeconds ());
400  Ptr<dsr::DsrNetworkQueue> queue_i = CreateObject<dsr::DsrNetworkQueue> (m_maxNetworkSize,m_maxNetworkDelay);
401  std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator, bool> result_i = m_priorityQueue.insert (std::make_pair (i, queue_i));
402  NS_ASSERT_MSG (result_i.second, "Error in creating queues");
403  }
404  Ptr<dsr::RreqTable> rreqTable = CreateObject<dsr::RreqTable> ();
405  // Set the initial hop limit
407  // Configure the request table parameters
409  rreqTable->SetRreqIdSize (m_requestTableIds);
410  rreqTable->SetUniqueRreqIdSize (m_maxRreqId);
411  SetRequestTable (rreqTable);
412  // Set the send buffer parameters
415  // Set the error buffer parameters using just the send buffer parameters
418  // Set the maintenance buffer parameters
421  // Set the gratuitous reply table size
423  NS_LOG_DEBUG ("Starting DSR on node " << m_mainAddress);
424 }
425 
426 void
428 {
430  m_node = 0;
431  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
432  {
433  // Disable layer 2 link state monitoring (if possible)
436  if (wifi != 0)
437  {
438  Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
439  if (mac != 0)
440  {
441  mac->TraceDisconnectWithoutContext ("TxErrHeader",
444  }
445  }
446  }
448 }
449 
450 void
452 {
453  m_node = node;
454 }
455 
456 Ptr<Node>
458 {
460  return m_node;
461 }
462 
464 {
465  // / Set the route cache to use
466  m_routeCache = r;
467 }
468 
471 {
472  // / Get the route cache to use
473  return m_routeCache;
474 }
475 
477 {
478  // / Set the request table to use
479  m_rreqTable = q;
480 }
481 
484 {
485  // / Get the request table to use
486  return m_rreqTable;
487 }
488 
490 {
491  return m_routeCache->IsLinkCache ();
492 }
493 
495 {
496  m_routeCache->UseExtends (rt);
497 }
498 
500 {
501  return m_routeCache->LookupRoute (id, rt);
502 }
503 
505 {
506  Ipv4Address nextHop = SearchNextHop (source, nodelist);
507  m_errorBuffer.DropPacketForErrLink (source, nextHop);
508  return m_routeCache->AddRoute_Link (nodelist, source);
509 }
510 
512 {
513  std::vector<Ipv4Address> nodelist = rt.GetVector ();
514  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodelist);
516  return m_routeCache->AddRoute (rt);
517 }
518 
520 {
521  m_routeCache->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, node);
522 }
523 
525 {
526  return m_routeCache->UpdateRouteEntry (dst);
527 }
528 
531 {
532  NS_LOG_FUNCTION (this << address);
533  int32_t nNodes = NodeList::GetNNodes ();
534  for (int32_t i = 0; i < nNodes; ++i)
535  {
536  Ptr<Node> node = NodeList::GetNode (i);
537  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
538  Ptr<NetDevice> netDevice = ipv4->GetNetDevice (1);
539 
540  if (netDevice->GetAddress () == address)
541  {
542  return ipv4->GetAddress (1, 0).GetLocal ();
543  }
544  }
545  return 0;
546 }
547 
548 void DsrRouting::PrintVector (std::vector<Ipv4Address>& vec)
549 {
550  NS_LOG_FUNCTION (this);
551  /*
552  * Check elements in a route vector
553  */
554  if (!vec.size ())
555  {
556  NS_LOG_DEBUG ("The vector is empty");
557  }
558  else
559  {
560  NS_LOG_DEBUG ("Print all the elements in a vector");
561  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
562  {
563  NS_LOG_DEBUG ("The ip address " << *i);
564  }
565  }
566 }
567 
568 Ipv4Address DsrRouting::SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
569 {
570  NS_LOG_FUNCTION (this << ipv4Address);
571  Ipv4Address nextHop;
572  NS_LOG_DEBUG ("the vector size " << vec.size ());
573  if (vec.size () == 2)
574  {
575  NS_LOG_DEBUG ("The two nodes are neighbors");
576  nextHop = vec[1];
577  return nextHop;
578  }
579  else
580  {
581  if (ipv4Address == vec.back ())
582  {
583  NS_LOG_DEBUG ("We have reached to the final destination " << ipv4Address << " " << vec.back ());
584  return ipv4Address;
585  }
586  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
587  {
588  if (ipv4Address == (*i))
589  {
590  NS_LOG_DEBUG (ipv4Address << " and " << *i);
591  nextHop = *(++i);
592  return nextHop;
593  }
594  }
595  }
596  NS_LOG_DEBUG ("Next hop address not found");
597  Ipv4Address none = "0.0.0.0";
598  return none;
599 }
600 
603 {
604  NS_LOG_FUNCTION (this << nextHop << srcAddress);
605  m_ipv4Route = Create<Ipv4Route> ();
606  m_ipv4Route->SetDestination (nextHop);
607  m_ipv4Route->SetGateway (nextHop);
608  m_ipv4Route->SetSource (srcAddress);
609  return m_ipv4Route;
610 }
611 
612 int
614 {
615  // / This is the protocol number for DSR which is 48
616  return PROT_NUMBER;
617 }
618 
619 uint16_t
621 {
622  int32_t nNodes = NodeList::GetNNodes ();
623  for (int32_t i = 0; i < nNodes; ++i)
624  {
625  Ptr<Node> node = NodeList::GetNode (i);
626  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
627  if (ipv4->GetAddress (1, 0).GetLocal () == address)
628  {
629  return uint16_t (i);
630  }
631  }
632  return 256;
633 }
634 
637 {
638  if (id >= 256)
639  {
640  NS_LOG_DEBUG ("Exceed the node range");
641  return "0.0.0.0";
642  }
643  else
644  {
645  Ptr<Node> node = NodeList::GetNode (uint32_t (id));
646  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
647  return ipv4->GetAddress (1, 0).GetLocal ();
648  }
649 }
650 
651 uint32_t
653 {
654  if (messageType == DSR_CONTROL_PACKET)
655  {
656  return 0;
657  }
658  else
659  {
660  return 1;
661  }
662 }
663 
665 {
666  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
667  MaintainBuffEntry entry;
668  // Find the packet in send buffer
669  if (m_maintainBuffer.Find (nextHop))
670  {
671  NS_LOG_DEBUG ("Trying to dequeue");
672 
673  if (m_maintainBuffer.Dequeue (nextHop, entry))
674  {
675  NS_LOG_DEBUG ("creating new packet");
676  /*
677  * Copy the packet and save a copy to the send buffer.
678  * if only queue the original packet to the buffer,
679  * when dequeue the packet, it turns to be empty.
680  */
681  Ptr<Packet> dequeP = ConstCast<Packet> (entry.GetPacket ());
682  Ptr<Packet> newPacket = dequeP->Copy ();
683  Ptr<Packet> p = dequeP->Copy ();
684 
685  Ipv4Address source = entry.GetSrc ();
686  Ipv4Address destination = entry.GetDst ();
687 
688  // Send the data packet out before schedule the next packet transmission
689  SendPacket (dequeP, source, nextHop, protocol);
690 
691  DsrRoutingHeader dsrRoutingHeader;
692  p->RemoveHeader (dsrRoutingHeader);
693  Ptr<Packet> cleanP = p->Copy ();
694  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
695  newPacket->RemoveAtStart (offset);
696 
697  // Get the number of routers' address field
698  uint8_t buf[2];
699  newPacket->CopyData (buf, sizeof(buf));
700  uint8_t numberAddress = (buf[1] - 2) / 4;
701 
702  DsrOptionSRHeader sourceRoute;
703  sourceRoute.SetNumberAddress (numberAddress);
704  newPacket->RemoveHeader (sourceRoute);
705  uint8_t salvage = sourceRoute.GetSalvage ();
706 
707  // TODO
708  DsrOptionAckReqHeader ackReq;
709  newPacket->RemoveHeader (ackReq);
710  /*
711  * Get the node list address
712  */
713  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
714  Ipv4Address address1 = nodeList[1];
715  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);
716  NS_LOG_DEBUG ("The next hop address" << nextHop);
717  if (nextHop == "0.0.0.0")
718  {
719  PacketNewRoute (cleanP, m_mainAddress, destination, protocol);
720  return;
721  }
722  RouteCacheEntry salvageRoute;
723  bool findRoute = m_routeCache->LookupRoute (destination, salvageRoute);
724  // Check the salvage value in header, if salvage is needed, we should find alternative route
725  if (findRoute && (salvage < m_maxSalvageCount))
726  {
727  // Need to salvage the packet instead of discard it
728  std::vector<Ipv4Address> nodeList = salvageRoute.GetVector ();
729  DsrOptionSRHeader newSR;
730  newSR.SetNodesAddress (nodeList);
731  newSR.SetSegmentsLeft ((nodeList.size () - 2));
732  newSR.SetSalvage (salvage + 1);
733  if (m_routeCache->IsLinkCache ())
734  {
735  m_routeCache->UseExtends (nodeList);
736  }
737 
738  NetworkKey networkKey;
739  networkKey.m_ackId = entry.GetAckId ();
740  networkKey.m_ourAdd = entry.GetOurAdd ();
741  networkKey.m_nextHop = entry.GetNextHop ();
742  networkKey.m_source = entry.GetSrc ();
743  networkKey.m_destination = entry.GetDst ();
744 
745  PassiveKey passiveKey;
746  passiveKey.m_ackId = 0;
747  passiveKey.m_source = entry.GetSrc ();
748  passiveKey.m_destination = entry.GetDst ();
749  passiveKey.m_segsLeft = entry.GetSegsLeft ();
750 
751  m_addressForwardCnt[networkKey] = 0;
752  m_passiveCnt[passiveKey] = 0;
753 
754  if (nextHop != destination)
755  {
756  SchedulePassivePacketRetry (entry, false, protocol);
757  }
758  else
759  {
760  // This is the first network retry
761  ScheduleNetworkPacketRetry (entry, true, protocol);
762  }
763  }
764  else
765  {
766  /*
767  * This code block create a packet and attach a route error option to it
768  */
770  /*
771  * If the salvage is not 0, use the first address in the route as the error dst in error header
772  * otherwise use the source of packet as the error destination
773  */
774  Ipv4Address errorDst;
775  if (salvage)
776  {
777  errorDst = address1;
778  }
779  else
780  {
781  errorDst = source;
782  }
783  SendUnreachError (nextHop, errorDst, destination, salvage, protocol);
784  /*
785  * here we cancel the packet retransmission time for all the packets have next hop address
786  * as nextHop
787  */
788  }
789  if (m_maintainBuffer.GetSize () != 0 && m_maintainBuffer.Find (nextHop))
790  {
792  &DsrRouting::SendRerrWhenBreaksLinkToNextHop,this,nextHop,protocol);
793  }
794  }
795  }
796 }
797 
799 {
800  if (m_sendBuffTimer.IsRunning ())
801  {
803  }
805  CheckSendBuffer ();
806 }
807 
809 {
810  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
811  << " Checking send buffer at " << m_mainAddress << " with size " << m_sendBuffer.GetSize ());
812 
813  for (std::vector<SendBuffEntry>::iterator i = m_sendBuffer.GetBuffer ().begin (); i != m_sendBuffer.GetBuffer ().end (); )
814  {
815  NS_LOG_DEBUG ("Here we try to find the data packet in the send buffer");
816  Ipv4Address destination = i->GetDestination ();
817  RouteCacheEntry toDst;
818  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
819  if (findRoute)
820  {
821  NS_LOG_INFO ("We have found a route for the packet");
822  Ptr<const Packet> packet = i->GetPacket ();
823  Ptr<Packet> cleanP = packet->Copy ();
824  uint8_t protocol = i->GetProtocol ();
825 
826  m_sendBuffer.GetBuffer ().erase (i);
827 
828  DsrRoutingHeader dsrRoutingHeader;
829  Ptr<Packet> copyP = packet->Copy ();
830  Ptr<Packet> dsrPacket = packet->Copy ();
831  dsrPacket->RemoveHeader (dsrRoutingHeader);
832  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
833  copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
834  // The packet to get ipv4 header
835  Ptr<Packet> ipv4P = copyP->Copy ();
836  /*
837  * Peek data to get the option type as well as length and segmentsLeft field
838  */
839  uint32_t size = copyP->GetSize ();
840  uint8_t *data = new uint8_t[size];
841  copyP->CopyData (data, size);
842 
843  uint8_t optionType = 0;
844  optionType = *(data);
845 
846  if (optionType == 3)
847  {
848  Ptr<dsr::DsrOptions> dsrOption;
849  DsrOptionHeader dsrOptionHeader;
850  uint8_t errorType = *(data + 2);
851 
852  if (errorType == 1) // This is the Route Error Option
853  {
855  copyP->RemoveHeader (rerr);
856  NS_ASSERT (copyP->GetSize () == 0);
857 
858  DsrOptionRerrUnreachHeader newUnreach;
859  newUnreach.SetErrorType (1);
860  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
861  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
862  newUnreach.SetErrorDst (rerr.GetErrorDst ());
863  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
864 
865  DsrOptionSRHeader sourceRoute;
866  std::vector<Ipv4Address> errorRoute = toDst.GetVector ();
867  sourceRoute.SetNodesAddress (errorRoute);
868  if (m_routeCache->IsLinkCache ())
869  {
870  m_routeCache->UseExtends (errorRoute);
871  }
872  sourceRoute.SetSegmentsLeft ((errorRoute.size () - 2));
873  uint8_t salvage = 0;
874  sourceRoute.SetSalvage (salvage);
875  Ipv4Address nextHop = SearchNextHop (m_mainAddress, errorRoute); // Get the next hop address
876 
877  if (nextHop == "0.0.0.0")
878  {
879  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
880  return;
881  }
882 
883  SetRoute (nextHop, m_mainAddress);
884  uint8_t length = (sourceRoute.GetLength () + newUnreach.GetLength ());
885  dsrRoutingHeader.SetNextHeader (protocol);
886  dsrRoutingHeader.SetMessageType (1);
887  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
888  dsrRoutingHeader.SetDestId (255);
889  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
890  dsrRoutingHeader.AddDsrOption (newUnreach);
891  dsrRoutingHeader.AddDsrOption (sourceRoute);
892 
893  Ptr<Packet> newPacket = Create<Packet> ();
894  newPacket->AddHeader (dsrRoutingHeader); // Add the routing header with rerr and sourceRoute attached to it
897 
898  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
899  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
900  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
901  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
902 
903  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
904 
905  if (dsrNetworkQueue->Enqueue (newEntry))
906  {
907  Scheduler (priority);
908  }
909  else
910  {
911  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
912  }
913  }
914  }
915  else
916  {
917  dsrRoutingHeader.SetNextHeader (protocol);
918  dsrRoutingHeader.SetMessageType (2);
919  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
920  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
921 
922  DsrOptionSRHeader sourceRoute;
923  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
924  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
925  if (nextHop == "0.0.0.0")
926  {
927  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
928  return;
929  }
930  uint8_t salvage = 0;
931  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
932  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
933  sourceRoute.SetSalvage (salvage);
934 
935  uint8_t length = sourceRoute.GetLength ();
936  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
937  dsrRoutingHeader.AddDsrOption (sourceRoute);
938  cleanP->AddHeader (dsrRoutingHeader);
939  // Send the data packet out before schedule the next packet transmission
940  SendPacket (cleanP, m_mainAddress, nextHop, protocol);
941  Ptr<const Packet> mtP = cleanP->Copy ();
942  // Put the data packet in the maintenance queue for data packet retransmission
943  MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
944  /*source=*/ m_mainAddress, /*destination=*/ destination, /*ackId=*/ 0,
945  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
946  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
947  if (result)
948  {
949  NetworkKey networkKey;
950  networkKey.m_ackId = newEntry.GetAckId ();
951  networkKey.m_ourAdd = newEntry.GetOurAdd ();
952  networkKey.m_nextHop = newEntry.GetNextHop ();
953  networkKey.m_source = newEntry.GetSrc ();
954  networkKey.m_destination = newEntry.GetDst ();
955 
956  PassiveKey passiveKey;
957  passiveKey.m_ackId = 0;
958  passiveKey.m_source = newEntry.GetSrc ();
959  passiveKey.m_destination = newEntry.GetDst ();
960  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
961 
962  m_addressForwardCnt[networkKey] = 0;
963  m_passiveCnt[passiveKey] = 0;
964  if (nextHop != destination)
965  {
966  SchedulePassivePacketRetry (newEntry, false, protocol);
967  }
968  else
969  {
970  // This is the first network retry
971  ScheduleNetworkPacketRetry (newEntry, true, protocol);
972  }
973  }
974  // we need to suspend the normal timer that checks the send buffer
975  // until we are done sending packets
977  {
979  }
981  return;
982  }
983  }
984  else
985  {
986  ++i;
987  }
988  }
989  //after going through the entire send buffer and send all packets found route,
990  //we need to resume the timer if it has been suspended
992  {
993  NS_LOG_DEBUG ("Resume the send buffer timer");
995  }
996 }
997 
998 bool DsrRouting::PromiscReceive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &from,
999  const Address &to, NetDevice::PacketType packetType)
1000 {
1001  // Receive only IP packets and packets destined for other hosts
1002  if (protocol == Ipv4L3Protocol::PROT_NUMBER && packetType == NetDevice::PACKET_OTHERHOST)
1003  {
1004  Ptr<Packet> p = packet->Copy ();
1005  //pull off IP header
1006  Ipv4Header ipv4Header;
1007  p->RemoveHeader (ipv4Header);
1008 
1009  // Process only data packets with DSR header
1010  if (ipv4Header.GetProtocol () == DsrRouting::PROT_NUMBER)
1011  {
1012  //just to minimize debug output
1013  NS_LOG_INFO (this << from << to << packetType << *p);
1014  DsrRoutingHeader dsrRoutingHeader;
1015  //pull of DSR header to check option type
1016  Ptr<Packet> dsrPacket = p->Copy ();
1017  dsrPacket->RemoveHeader (dsrRoutingHeader);
1018  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset (); // Get the offset for option header, 4 bytes in this case
1019  uint8_t nextHeader = dsrRoutingHeader.GetNextHeader ();
1020  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
1021  Ipv4Address source = GetIPfromID (sourceId);
1022 
1023  // This packet is used to peek option type
1024  p->RemoveAtStart (offset);
1025  /*
1026  * Peek data to get the option type as well as length and segmentsLeft field
1027  */
1028  uint32_t size = p->GetSize ();
1029  uint8_t *data = new uint8_t[size];
1030  p->CopyData (data, size);
1031  uint8_t optionType = 0;
1032  optionType = *(data);
1033 
1034  Ptr<dsr::DsrOptions> dsrOption;
1035 
1036  if (optionType == 96) // This is the source route option
1037  {
1038  dsrOption = GetOption (optionType); // Get the relative DSR option and demux to the process function
1039  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () <<
1040  " DSR node " << m_mainAddress <<
1041  " overhearing packet PID: " << p->GetUid () <<
1042  " from " << GetIPfromMAC (Mac48Address::ConvertFrom (from)) <<
1043  " to " << GetIPfromMAC (Mac48Address::ConvertFrom (to)) <<
1044  " with source IP " << ipv4Header.GetSource () <<
1045  " and destination IP " << ipv4Header.GetDestination () <<
1046  " and packet : " << *dsrPacket);
1047  bool isPromisc = true; // Set the boolean value isPromisc as true
1048  dsrOption->Process (p, dsrPacket, m_mainAddress, source, ipv4Header, nextHeader, isPromisc);
1049  return true;
1050  }
1051  }
1052  }
1053  return false;
1054 }
1055 
1056 void
1058  Ipv4Address source,
1059  Ipv4Address destination,
1060  uint8_t protocol)
1061 {
1062  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol);
1063  // Look up routes for the specific destination
1064  RouteCacheEntry toDst;
1065  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1066  // Queue the packet if there is no route pre-existing
1067  if (!findRoute)
1068  {
1069  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1070  << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
1071 
1072  Ptr<Packet> p = packet->Copy ();
1073  SendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol); // Create a new entry for send buffer
1074  bool result = m_sendBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1075  if (result)
1076  {
1077  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1078  << "s Add packet PID: " << packet->GetUid () << " to queue. Packet: " << *packet);
1079 
1080  NS_LOG_LOGIC ("Send RREQ to" << destination);
1081  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1082  {
1083  /*
1084  * Call the send request function, it will update the request table entry and ttl there
1085  */
1086  SendInitialRequest (source, destination, protocol);
1087  }
1088  }
1089  }
1090  else
1091  {
1092  Ptr<Packet> cleanP = packet->Copy ();
1093  DsrRoutingHeader dsrRoutingHeader;
1094  dsrRoutingHeader.SetNextHeader (protocol);
1095  dsrRoutingHeader.SetMessageType (2);
1096  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1097  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1098 
1099  DsrOptionSRHeader sourceRoute;
1100  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1101  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1102  if (nextHop == "0.0.0.0")
1103  {
1104  PacketNewRoute (cleanP, source, destination, protocol);
1105  return;
1106  }
1107  uint8_t salvage = 0;
1108  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
1109  if (m_routeCache->IsLinkCache ())
1110  {
1111  m_routeCache->UseExtends (nodeList);
1112  }
1113  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
1114  sourceRoute.SetSalvage (salvage);
1115 
1116  uint8_t length = sourceRoute.GetLength ();
1117  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1118  dsrRoutingHeader.AddDsrOption (sourceRoute);
1119  cleanP->AddHeader (dsrRoutingHeader);
1120  // Send the data packet out before schedule the next packet transmission
1121  SendPacket (cleanP, source, nextHop, protocol);
1122  Ptr<const Packet> mtP = cleanP->Copy ();
1123  SetRoute (nextHop, m_mainAddress);
1124  // Put the data packet in the maintenance queue for data packet retransmission
1125  MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
1126  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1127  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1128  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1129 
1130  if (result)
1131  {
1132  NetworkKey networkKey;
1133  networkKey.m_ackId = newEntry.GetAckId ();
1134  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1135  networkKey.m_nextHop = newEntry.GetNextHop ();
1136  networkKey.m_source = newEntry.GetSrc ();
1137  networkKey.m_destination = newEntry.GetDst ();
1138 
1139  PassiveKey passiveKey;
1140  passiveKey.m_ackId = 0;
1141  passiveKey.m_source = newEntry.GetSrc ();
1142  passiveKey.m_destination = newEntry.GetDst ();
1143  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1144 
1145  m_addressForwardCnt[networkKey] = 0;
1146  m_passiveCnt[passiveKey] = 0;
1147  if (nextHop != destination)
1148  {
1149  SchedulePassivePacketRetry (newEntry, false, protocol);
1150  }
1151  else
1152  {
1153  // This is the first network retry
1154  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1155  }
1156  }
1157  }
1158 }
1159 
1160 void
1161 DsrRouting::SendUnreachError (Ipv4Address errorHop, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
1162 {
1163  NS_LOG_FUNCTION (this << errorHop << destination << originalDst << (uint32_t)salvage << (uint32_t)protocol);
1164  DsrRoutingHeader dsrRoutingHeader;
1165  dsrRoutingHeader.SetNextHeader (protocol);
1166  dsrRoutingHeader.SetMessageType (1);
1167  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
1168  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1169 
1170  DsrOptionRerrUnreachHeader rerrUnreachHeader;
1171  rerrUnreachHeader.SetErrorType (1);
1172  rerrUnreachHeader.SetErrorSrc (m_mainAddress);
1173  rerrUnreachHeader.SetUnreachNode (errorHop);
1174  rerrUnreachHeader.SetErrorDst (destination);
1175  rerrUnreachHeader.SetOriginalDst (originalDst);
1176  rerrUnreachHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
1177  uint8_t rerrLength = rerrUnreachHeader.GetLength ();
1178 
1179  RouteCacheEntry toDst;
1180  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1181  // Queue the packet if there is no route pre-existing
1182  Ptr<Packet> newPacket = Create<Packet> ();
1183  if (!findRoute)
1184  {
1185  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1186  << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
1187 
1188  dsrRoutingHeader.SetPayloadLength (rerrLength + 2);
1189  dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
1190  newPacket->AddHeader (dsrRoutingHeader);
1191  Ptr<Packet> p = newPacket->Copy ();
1192  // Save the error packet in the error buffer
1193  ErrorBuffEntry newEntry (p, destination, m_mainAddress, errorHop, m_sendBufferTimeout, protocol);
1194  bool result = m_errorBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1195  if (result)
1196  {
1197  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1198  << "s Add packet PID: " << p->GetUid () << " to queue. Packet: " << *p);
1199  NS_LOG_LOGIC ("Send RREQ to" << destination);
1200  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1201  {
1202  NS_LOG_DEBUG ("When there is no existing route request for " << destination << ", initialize one");
1203  /*
1204  * Call the send request function, it will update the request table entry and ttl there
1205  */
1206  SendInitialRequest (m_mainAddress, destination, protocol);
1207  }
1208  }
1209  }
1210  else
1211  {
1212  std::vector<Ipv4Address> nodeList = toDst.GetVector ();
1213  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);
1214  if (nextHop == "0.0.0.0")
1215  {
1216  NS_LOG_DEBUG ("The route is not right");
1217  PacketNewRoute (newPacket, m_mainAddress, destination, protocol);
1218  return;
1219  }
1220  DsrOptionSRHeader sourceRoute;
1221  sourceRoute.SetNodesAddress (nodeList);
1222  if (m_routeCache->IsLinkCache ())
1223  {
1224  m_routeCache->UseExtends (nodeList);
1225  }
1226  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));
1227  uint8_t srLength = sourceRoute.GetLength ();
1228  uint8_t length = (srLength + rerrLength);
1229 
1230  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1231  dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
1232  dsrRoutingHeader.AddDsrOption (sourceRoute);
1233  newPacket->AddHeader (dsrRoutingHeader);
1234 
1235  SetRoute (nextHop, m_mainAddress);
1238  NS_LOG_INFO ("Send the packet to the next hop address " << nextHop << " from " << m_mainAddress << " with the size " << newPacket->GetSize ());
1239 
1240  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1241  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1242  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1243  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1244 
1245  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
1246 
1247  if (dsrNetworkQueue->Enqueue (newEntry))
1248  {
1249  Scheduler (priority);
1250  }
1251  else
1252  {
1253  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1254  }
1255  }
1256 }
1257 
1258 void
1260  DsrOptionSRHeader &sourceRoute,
1261  Ipv4Address nextHop,
1262  uint8_t protocol,
1263  Ptr<Ipv4Route> route)
1264 {
1265  NS_LOG_FUNCTION (this << rerr << sourceRoute << nextHop << (uint32_t)protocol << route);
1266  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1267  DsrRoutingHeader dsrRoutingHeader;
1268  dsrRoutingHeader.SetNextHeader (protocol);
1269  dsrRoutingHeader.SetMessageType (1);
1270  dsrRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
1271  dsrRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
1272 
1273  uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
1274  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1275  dsrRoutingHeader.AddDsrOption (rerr);
1276  dsrRoutingHeader.AddDsrOption (sourceRoute);
1277  Ptr<Packet> packet = Create<Packet> ();
1278  packet->AddHeader (dsrRoutingHeader);
1280  route->SetOutputDevice (dev);
1281 
1282  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1283  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1284  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1285  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1286 
1287  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, nextHop, Simulator::Now (), route);
1288 
1289  if (dsrNetworkQueue->Enqueue (newEntry))
1290  {
1291  Scheduler (priority);
1292  }
1293  else
1294  {
1295  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1296  }
1297 }
1298 
1299 void
1301  Ipv4Address source,
1302  Ipv4Address destination,
1303  uint8_t protocol,
1304  Ptr<Ipv4Route> route)
1305 {
1306  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
1307  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1308 
1309  if (protocol == 1)
1310  {
1311  NS_LOG_INFO ("Drop packet. Not handling ICMP packet for now");
1312  }
1313  else
1314  {
1315  // Look up routes for the specific destination
1316  RouteCacheEntry toDst;
1317  bool findRoute = m_routeCache->LookupRoute (destination, toDst);
1318  // Queue the packet if there is no route pre-existing
1319  if (!findRoute)
1320  {
1321  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1322  << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
1323 
1324  Ptr<Packet> p = packet->Copy ();
1325  SendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol); // Create a new entry for send buffer
1326  bool result = m_sendBuffer.Enqueue (newEntry); // Enqueue the packet in send buffer
1327  if (result)
1328  {
1329  NS_LOG_INFO (Simulator::Now ().GetSeconds ()
1330  << "s Add packet PID: " << packet->GetUid () << " to queue. Packet: " << *packet);
1331  NS_LOG_LOGIC ("Send RREQ to " << destination);
1332  // Only when there is no existing route request timer when new route request is scheduled
1333  if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
1334  {
1335  NS_LOG_DEBUG ("When there is no existing route request for " << destination << ", initialize one");
1336  /*
1337  * Call the send request function, it will update the request table entry and ttl there
1338  */
1339  SendInitialRequest (source, destination, protocol);
1340  }
1341  else
1342  {
1343  NS_LOG_DEBUG ("There is existing route request timer and the request count here " << m_rreqTable->GetRreqCnt (destination));
1344  }
1345  }
1346  }
1347  else
1348  {
1349  Ptr<Packet> cleanP = packet->Copy ();
1350  DsrRoutingHeader dsrRoutingHeader;
1351  dsrRoutingHeader.SetNextHeader (protocol);
1352  dsrRoutingHeader.SetMessageType (2);
1353  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1354  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1355 
1356  DsrOptionSRHeader sourceRoute;
1357  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1358  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1359  if (nextHop == "0.0.0.0")
1360  {
1361  PacketNewRoute (cleanP, source, destination, protocol);
1362  return;
1363  }
1364  uint8_t salvage = 0;
1365  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
1366  if (m_routeCache->IsLinkCache ())
1367  {
1368  m_routeCache->UseExtends (nodeList);
1369  }
1370  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
1371  sourceRoute.SetSalvage (salvage);
1372 
1373  uint8_t length = sourceRoute.GetLength ();
1374 
1375  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1376  dsrRoutingHeader.AddDsrOption (sourceRoute);
1377  cleanP->AddHeader (dsrRoutingHeader);
1378  // Send the data packet out before schedule the next packet transmission
1379  SendPacket (cleanP, source, nextHop, protocol);
1380 
1381  Ptr<const Packet> mtP = cleanP->Copy ();
1382  NS_LOG_DEBUG ("maintain packet size " << cleanP->GetSize ());
1383  // Put the data packet in the maintenance queue for data packet retransmission
1384  MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
1385  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1386  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1387  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1388  if (result)
1389  {
1390  NetworkKey networkKey;
1391  networkKey.m_ackId = newEntry.GetAckId ();
1392  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1393  networkKey.m_nextHop = newEntry.GetNextHop ();
1394  networkKey.m_source = newEntry.GetSrc ();
1395  networkKey.m_destination = newEntry.GetDst ();
1396 
1397  PassiveKey passiveKey;
1398  passiveKey.m_ackId = 0;
1399  passiveKey.m_source = newEntry.GetSrc ();
1400  passiveKey.m_destination = newEntry.GetDst ();
1401  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1402 
1403  m_addressForwardCnt[networkKey] = 0;
1404  m_passiveCnt[passiveKey] = 0;
1405  if (nextHop != destination)
1406  {
1407  SchedulePassivePacketRetry (newEntry, false, protocol);
1408  }
1409  else
1410  {
1411  // This is the first network retry
1412  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1413  }
1414  }
1415  // Try to send packet from *previously* queued entries from send buffer if any
1417  &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
1418  }
1419  }
1420 }
1421 
1422 uint16_t
1424 {
1425  NS_LOG_FUNCTION (this << packet << nextHop);
1426  // This packet is used to peek option type
1427  Ptr<Packet> dsrP = packet->Copy ();
1428  Ptr<Packet> tmpP = packet->Copy ();
1429 
1430  DsrRoutingHeader dsrRoutingHeader;
1431  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
1432  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
1433  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
1434  uint32_t destinationId = dsrRoutingHeader.GetDestId ();
1435  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1436  tmpP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1437 
1438  // Get the number of routers' address field
1439  uint8_t buf[2];
1440  tmpP->CopyData (buf, sizeof(buf));
1441  uint8_t numberAddress = (buf[1] - 2) / 4;
1442  DsrOptionSRHeader sourceRoute;
1443  sourceRoute.SetNumberAddress (numberAddress);
1444  tmpP->RemoveHeader (sourceRoute); // this is a clean packet without any dsr involved headers
1445 
1446  DsrOptionAckReqHeader ackReq;
1447  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
1448  ackReq.SetAckId (m_ackId);
1449 
1450  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
1451  DsrRoutingHeader newDsrRoutingHeader;
1452  newDsrRoutingHeader.SetNextHeader (protocol);
1453  newDsrRoutingHeader.SetMessageType (2);
1454  newDsrRoutingHeader.SetSourceId (sourceId);
1455  newDsrRoutingHeader.SetDestId (destinationId);
1456  newDsrRoutingHeader.SetPayloadLength (length + 4);
1457  newDsrRoutingHeader.AddDsrOption (sourceRoute);
1458  newDsrRoutingHeader.AddDsrOption (ackReq);
1459  dsrP->AddHeader (newDsrRoutingHeader);
1460  // give the dsrP value to packet and then return
1461  packet = dsrP;
1462  return m_ackId;
1463 }
1464 
1465 void
1466 DsrRouting::SendPacket (Ptr<Packet> packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol)
1467 {
1468  NS_LOG_FUNCTION (this << packet << source << nextHop << (uint32_t)protocol);
1469  // Send out the data packet
1470  m_ipv4Route = SetRoute (nextHop, m_mainAddress);
1473 
1474  uint32_t priority = GetPriority (DSR_DATA_PACKET);
1475  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1476  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1477  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1478 
1479  DsrNetworkQueueEntry newEntry (packet, source, 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 void
1492 DsrRouting::Scheduler (uint32_t priority)
1493 {
1494  NS_LOG_FUNCTION (this);
1495  PriorityScheduler (priority, true);
1496 }
1497 
1498 void
1499 DsrRouting::PriorityScheduler (uint32_t priority, bool continueWithFirst)
1500 {
1501  NS_LOG_FUNCTION (this << priority << continueWithFirst);
1502  NS_LOG_DEBUG ("Scheduler looking for packets in network queue");
1503  uint32_t numPriorities;
1504  if (continueWithFirst)
1505  {
1506  numPriorities = 0;
1507  }
1508  else
1509  {
1510  numPriorities = priority;
1511  }
1512  // priorities range from 0 to m_numPriorityQueues, with 0 as the highest priority
1513  for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
1514  {
1515  std::map<uint32_t, Ptr<DsrNetworkQueue> >::iterator q = m_priorityQueue.find (i);
1516  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
1517  uint32_t queueSize = dsrNetworkQueue->GetSize ();
1518  if (queueSize == 0)
1519  {
1520  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1521  {
1522  i = 0;
1523  }
1524  else
1525  {
1526  i++;
1527  }
1528  }
1529  else
1530  {
1531  uint32_t totalQueueSize = 0;
1532  for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator j = m_priorityQueue.begin (); j != m_priorityQueue.end (); j++)
1533  {
1534  NS_LOG_DEBUG ("The size of the network queue for " << j->first << " is " << j->second->GetSize ());
1535  totalQueueSize += j->second->GetSize ();
1536  NS_LOG_DEBUG ("And the total size is " << totalQueueSize);
1537  }
1538  if (totalQueueSize > 5)
1539  {
1540  // Here the queue size is larger than 5, we need to increase the retransmission timer for each packet in the network queue
1542  }
1543  DsrNetworkQueueEntry newEntry;
1544  dsrNetworkQueue->Dequeue (newEntry);
1545  if (SendRealDown (newEntry))
1546  {
1547  NS_LOG_DEBUG ("Packet sent by Dsr. Calling PriorityScheduler after some time");
1548  //packet was successfully sent down. call scheduler after some time
1550  &DsrRouting::PriorityScheduler,this, i, false);
1551  }
1552  else
1553  {
1554  // packet was dropped by Dsr. Call scheduler immediately so that we can
1555  // send another packet immediately.
1556  NS_LOG_DEBUG ("Packet dropped by Dsr. Calling PriorityScheduler immediately");
1558  }
1559  if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
1560  {
1561  i = 0;
1562  }
1563  else
1564  {
1565  i++;
1566  }
1567  }
1568  }
1569 }
1570 
1571 void
1573 {
1574  NS_LOG_FUNCTION (this);
1575  // We may want to get the queue first and then we need to save a vector of the entries here and then find
1576  uint32_t priority = GetPriority (DSR_DATA_PACKET);
1577  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1578  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1579 
1580  std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue ();
1581  for (std::vector<DsrNetworkQueueEntry>::iterator i = newNetworkQueue.begin (); i != newNetworkQueue.end (); i++)
1582  {
1583  Ipv4Address nextHop = i->GetNextHopAddress ();
1584  for (std::map<NetworkKey, Timer>::iterator j = m_addressForwardTimer.begin (); j != m_addressForwardTimer.end (); j++)
1585  {
1586  if (nextHop == j->first.m_nextHop)
1587  {
1588  NS_LOG_DEBUG ("The network delay left is " << j->second.GetDelayLeft ());
1589  j->second.SetDelay (j->second.GetDelayLeft () + m_retransIncr);
1590  NS_LOG_DEBUG ("The new network delay time is " << j->second.GetDelayLeft ());
1591  }
1592  }
1593  }
1594 }
1595 
1596 bool
1598 {
1599  NS_LOG_FUNCTION (this);
1600  Ipv4Address source = newEntry.GetSourceAddress ();
1601  Ipv4Address nextHop = newEntry.GetNextHopAddress ();
1602  Ptr<Packet> packet = newEntry.GetPacket ()->Copy ();
1603  Ptr<Ipv4Route> route = newEntry.GetIpv4Route ();
1604  m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
1605  return true;
1606 }
1607 
1608 void
1609 DsrRouting::SendPacketFromBuffer (DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop, uint8_t protocol)
1610 {
1611  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
1612  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
1613 
1614  // Reconstruct the route and Retransmit the data packet
1615  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1616  Ipv4Address destination = nodeList.back ();
1617  Ipv4Address source = nodeList.front (); // Get the source address
1618 
1619  NS_LOG_INFO ("The nexthop address " << nextHop << " the source " << source << " the destination " << destination);
1620 
1621  /*
1622  * Here we try to find data packet from send buffer, if packet with this destiantion found, send it out
1623  */
1624  if (m_sendBuffer.Find (destination))
1625  {
1626  SendBuffEntry entry;
1627  if (m_sendBuffer.Dequeue (destination, entry))
1628  {
1629  Ptr<Packet> packet = entry.GetPacket ()->Copy ();
1630  NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
1631 
1632  NS_LOG_DEBUG ("This is the data packet");
1633  Ptr<Packet> p = packet->Copy (); // get a copy of the packet
1634  // Set the source route option
1635  DsrRoutingHeader dsrRoutingHeader;
1636  dsrRoutingHeader.SetNextHeader (protocol);
1637  dsrRoutingHeader.SetMessageType (2);
1638  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1639  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
1640 
1641  uint8_t length = sourceRoute.GetLength ();
1642  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
1643  dsrRoutingHeader.AddDsrOption (sourceRoute);
1644 
1645  p->AddHeader (dsrRoutingHeader);
1646  // Send the data packet out before schedule the next packet transmission
1647  NS_LOG_DEBUG ("Send out the data packet");
1648  SendPacket (p, source, nextHop, protocol);
1649 
1650  Ptr<const Packet> mtP = p->Copy ();
1651  // Put the data packet in the maintenance queue for data packet retransmission
1652  MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
1653  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
1654  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
1655  bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
1656 
1657  if (result)
1658  {
1659  NetworkKey networkKey;
1660  networkKey.m_ackId = newEntry.GetAckId ();
1661  networkKey.m_ourAdd = newEntry.GetOurAdd ();
1662  networkKey.m_nextHop = newEntry.GetNextHop ();
1663  networkKey.m_source = newEntry.GetSrc ();
1664  networkKey.m_destination = newEntry.GetDst ();
1665 
1666  PassiveKey passiveKey;
1667  passiveKey.m_ackId = 0;
1668  passiveKey.m_source = newEntry.GetSrc ();
1669  passiveKey.m_destination = newEntry.GetDst ();
1670  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
1671 
1672  m_addressForwardCnt[networkKey] = 0;
1673  m_passiveCnt[passiveKey] = 0;
1674  if (nextHop != destination)
1675  {
1676  SchedulePassivePacketRetry (newEntry, false, protocol);
1677  }
1678  else
1679  {
1680  // This is the first network retry
1681  ScheduleNetworkPacketRetry (newEntry, true, protocol);
1682  }
1683  }
1684 
1685  if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
1686  {
1687  NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
1689  &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
1690  }
1691  }
1692  else
1693  {
1694  NS_LOG_DEBUG ("All queued packets are out-dated for the destination in send buffer");
1695  }
1696  }
1697  /*
1698  * Here we try to find data packet from send buffer, if packet with this destiantion found, send it out
1699  */
1700  else if (m_errorBuffer.Find (destination))
1701  {
1702  ErrorBuffEntry entry;
1703  if (m_errorBuffer.Dequeue (destination, entry))
1704  {
1705  Ptr<Packet> packet = entry.GetPacket ()->Copy ();
1706  NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
1707 
1708  DsrRoutingHeader dsrRoutingHeader;
1709  Ptr<Packet> copyP = packet->Copy ();
1710  Ptr<Packet> dsrPacket = packet->Copy ();
1711  dsrPacket->RemoveHeader (dsrRoutingHeader);
1712  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1713  copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
1714  /*
1715  * Peek data to get the option type as well as length and segmentsLeft field
1716  */
1717  uint32_t size = copyP->GetSize ();
1718  uint8_t *data = new uint8_t[size];
1719  copyP->CopyData (data, size);
1720 
1721  uint8_t optionType = 0;
1722  optionType = *(data);
1723  NS_LOG_DEBUG ("The option type value in send packet " << (uint32_t)optionType);
1724  if (optionType == 3)
1725  {
1726  NS_LOG_DEBUG ("The packet is error packet");
1727  Ptr<dsr::DsrOptions> dsrOption;
1728  DsrOptionHeader dsrOptionHeader;
1729 
1730  uint8_t errorType = *(data + 2);
1731  NS_LOG_DEBUG ("The error type");
1732  if (errorType == 1)
1733  {
1734  NS_LOG_DEBUG ("The packet is route error unreach packet");
1736  copyP->RemoveHeader (rerr);
1737  NS_ASSERT (copyP->GetSize () == 0);
1738  uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
1739 
1740  DsrOptionRerrUnreachHeader newUnreach;
1741  newUnreach.SetErrorType (1);
1742  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
1743  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
1744  newUnreach.SetErrorDst (rerr.GetErrorDst ());
1745  newUnreach.SetOriginalDst (rerr.GetOriginalDst ());
1746  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
1747 
1748  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1749  DsrRoutingHeader newRoutingHeader;
1750  newRoutingHeader.SetNextHeader (protocol);
1751  newRoutingHeader.SetMessageType (1);
1752  newRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
1753  newRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
1754  newRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
1755  newRoutingHeader.AddDsrOption (newUnreach);
1756  newRoutingHeader.AddDsrOption (sourceRoute);
1757  if (m_routeCache->IsLinkCache ())
1758  {
1759  m_routeCache->UseExtends (nodeList);
1760  }
1761  SetRoute (nextHop, m_mainAddress);
1762  Ptr<Packet> newPacket = Create<Packet> ();
1763  newPacket->AddHeader (newRoutingHeader); // Add the extension header with rerr and sourceRoute attached to it
1766 
1767  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
1768  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
1769  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
1770  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
1771 
1772  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
1773 
1774  if (dsrNetworkQueue->Enqueue (newEntry))
1775  {
1776  Scheduler (priority);
1777  }
1778  else
1779  {
1780  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
1781  }
1782  }
1783  }
1784 
1785  if (m_errorBuffer.GetSize () != 0 && m_errorBuffer.Find (destination))
1786  {
1787  NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
1789  &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
1790  }
1791  }
1792  }
1793  else
1794  {
1795  NS_LOG_DEBUG ("Packet not found in either the send or error buffer");
1796  }
1797 }
1798 
1799 bool
1801  uint8_t segsLeft)
1802 {
1803  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
1804 
1805  Ptr<Packet> p = packet->Copy ();
1806  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
1807  MaintainBuffEntry newEntry;
1808  newEntry.SetPacket (p);
1809  newEntry.SetSrc (source);
1810  newEntry.SetDst (destination);
1811  newEntry.SetAckId (0);
1812  newEntry.SetSegsLeft (segsLeft + 1);
1813 
1814  if (m_maintainBuffer.PromiscEqual (newEntry))
1815  {
1816  // The PromiscEqual function will remove the maintain buffer entry if equal value found
1817  // It only compares the source and destination address, ackId, and the segments left value
1818  CancelPassivePacketTimer (newEntry);
1819  return true;
1820  }
1821  return false;
1822 }
1823 
1824 void
1825 DsrRouting::CallCancelPacketTimer (uint16_t ackId, Ipv4Header const& ipv4Header, Ipv4Address realSrc, Ipv4Address realDst)
1826 {
1827  NS_LOG_FUNCTION (this << (uint32_t)ackId << ipv4Header << realSrc << realDst);
1828  Ipv4Address sender = ipv4Header.GetDestination ();
1829  Ipv4Address receiver = ipv4Header.GetSource ();
1830  /*
1831  * Create a packet to fill maintenance buffer, not used to compare
1832  * The reason is ack header doesn't have the original packet copy
1833  */
1834  Ptr<Packet> mainP = Create<Packet> ();
1835  MaintainBuffEntry newEntry (/*Packet=*/ mainP, /*ourAddress=*/ sender, /*nextHop=*/ receiver,
1836  /*source=*/ realSrc, /*destination=*/ realDst, /*ackId=*/ ackId,
1837  /*SegsLeft=*/ 0, /*expire time=*/ Simulator::Now ());
1838  CancelNetworkPacketTimer (newEntry);
1839 }
1840 
1841 void
1843 {
1844  NS_LOG_FUNCTION (this);
1845  NetworkKey networkKey;
1846  networkKey.m_ackId = mb.GetAckId ();
1847  networkKey.m_ourAdd = mb.GetOurAdd ();
1848  networkKey.m_nextHop = mb.GetNextHop ();
1849  networkKey.m_source = mb.GetSrc ();
1850  networkKey.m_destination = mb.GetDst ();
1851  /*
1852  * Here we have found the entry for send retries, so we get the value and increase it by one
1853  */
1854  m_addressForwardCnt[networkKey] = 0;
1855  m_addressForwardCnt.erase (networkKey);
1856 
1857  NS_LOG_INFO ("ackId " << mb.GetAckId () << " ourAdd " << mb.GetOurAdd () << " nextHop " << mb.GetNextHop ()
1858  << " source " << mb.GetSrc () << " destination " << mb.GetDst ()
1859  << " segsLeft " << (uint32_t)mb.GetSegsLeft ()
1860  );
1861  // Find the network acknowledgment timer
1862  std::map<NetworkKey, Timer>::const_iterator i =
1863  m_addressForwardTimer.find (networkKey);
1864  if (i == m_addressForwardTimer.end ())
1865  {
1866  NS_LOG_INFO ("did not find the packet timer");
1867  }
1868  else
1869  {
1870  NS_LOG_INFO ("did find the packet timer");
1871  /*
1872  * Schedule the packet retry
1873  * Push back the nextHop, source, destination address
1874  */
1875  m_addressForwardTimer[networkKey].Cancel ();
1876  m_addressForwardTimer[networkKey].Remove ();
1877  if (m_addressForwardTimer[networkKey].IsRunning ())
1878  {
1879  NS_LOG_INFO ("Timer not canceled");
1880  }
1881  m_addressForwardTimer.erase (networkKey);
1882  }
1883  // Erase the maintenance entry
1884  // yet this does not check the segments left value here
1885  if (m_maintainBuffer.NetworkEqual (mb))
1886  {
1887  NS_LOG_INFO ("Remove same maintenance buffer entry based on network acknowledgment");
1888  }
1889 }
1890 
1891 void
1893 {
1894  NS_LOG_FUNCTION (this);
1895  PassiveKey passiveKey;
1896  passiveKey.m_ackId = 0;
1897  passiveKey.m_source = mb.GetSrc ();
1898  passiveKey.m_destination = mb.GetDst ();
1899  passiveKey.m_segsLeft = mb.GetSegsLeft ();
1900 
1901  m_passiveCnt[passiveKey] = 0;
1902  m_passiveCnt.erase (passiveKey);
1903 
1904  // Find the passive acknowledgment timer
1905  std::map<PassiveKey, Timer>::const_iterator j =
1906  m_passiveAckTimer.find (passiveKey);
1907  if (j == m_passiveAckTimer.end ())
1908  {
1909  NS_LOG_INFO ("did not find the passive timer");
1910  }
1911  else
1912  {
1913  NS_LOG_INFO ("find the passive timer");
1914  /*
1915  * Cancel passive acknowledgment timer
1916  */
1917  m_passiveAckTimer[passiveKey].Cancel ();
1918  m_passiveAckTimer[passiveKey].Remove ();
1919  if (m_passiveAckTimer[passiveKey].IsRunning ())
1920  {
1921  NS_LOG_INFO ("Timer not canceled");
1922  }
1923  m_passiveAckTimer.erase (passiveKey);
1924  }
1925 }
1926 
1927 void
1929 {
1930  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
1931  MaintainBuffEntry entry;
1932  if (m_maintainBuffer.Dequeue (nextHop, entry))
1933  {
1934  Ptr<const Packet> packet = entry.GetPacket ()->Copy ();
1935  Ipv4Address source = entry.GetSrc ();
1936  Ipv4Address destination = entry.GetDst ();
1937  /*
1938  * Cancel the packet timer and then salvage the data packet
1939  */
1940  CancelNetworkPacketTimer (entry);
1941  SalvagePacket (packet, source, destination, protocol);
1942 
1943  if (m_maintainBuffer.GetSize () && m_maintainBuffer.Find (nextHop))
1944  {
1945  NS_LOG_INFO ("Cancel the packet timer for next maintenance entry");
1947  &DsrRouting::CancelPacketTimerNextHop,this,nextHop,protocol);
1948  }
1949  }
1950  else
1951  {
1952  NS_LOG_INFO ("Maintenance buffer entry not found");
1953  }
1954 }
1955 
1956 void
1958 {
1959  NS_LOG_FUNCTION (this << packet << source << dst << (uint32_t)protocol);
1960  // Create two copies of packet
1961  Ptr<Packet> p = packet->Copy ();
1962  Ptr<Packet> newPacket = packet->Copy ();
1963  // Remove the routing header in a whole to get a clean packet
1964  DsrRoutingHeader dsrRoutingHeader;
1965  p->RemoveHeader (dsrRoutingHeader);
1966  // Remove offset of dsr routing header
1967  uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
1968  newPacket->RemoveAtStart (offset);
1969 
1970  // Get the number of routers' address field
1971  uint8_t buf[2];
1972  newPacket->CopyData (buf, sizeof(buf));
1973  uint8_t numberAddress = (buf[1] - 2) / 4;
1974 
1975  DsrOptionSRHeader sourceRoute;
1976  sourceRoute.SetNumberAddress (numberAddress);
1977  newPacket->RemoveHeader (sourceRoute);
1978  uint8_t salvage = sourceRoute.GetSalvage ();
1979  /*
1980  * Look in the route cache for other routes for this destination
1981  */
1982  RouteCacheEntry toDst;
1983  bool findRoute = m_routeCache->LookupRoute (dst, toDst);
1984  if (findRoute && (salvage < m_maxSalvageCount))
1985  {
1986  NS_LOG_DEBUG ("We have found a route for the packet");
1987  DsrRoutingHeader newDsrRoutingHeader;
1988  newDsrRoutingHeader.SetNextHeader (protocol);
1989  newDsrRoutingHeader.SetMessageType (2);
1990  newDsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1991  newDsrRoutingHeader.SetDestId (GetIDfromIP (dst));
1992 
1993  std::vector<Ipv4Address> nodeList = toDst.GetVector (); // Get the route from the route entry we found
1994  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList); // Get the next hop address for the route
1995  if (nextHop == "0.0.0.0")
1996  {
1997  PacketNewRoute (p, source, dst, protocol);
1998  return;
1999  }
2000  // Increase the salvage count by 1
2001  salvage++;
2002  DsrOptionSRHeader sourceRoute;
2003  sourceRoute.SetSalvage (salvage);
2004  sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
2005  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
2006  DsrOptionAckReqHeader ackReq;
2007  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
2008  ackReq.SetAckId (m_ackId);
2009  if (m_routeCache->IsLinkCache ())
2010  {
2011  m_routeCache->UseExtends (nodeList);
2012  }
2013 
2014  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
2015  NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ())
2016  << " length of ack request header " << (uint32_t)(ackReq.GetLength ()));
2017  newDsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
2018  newDsrRoutingHeader.AddDsrOption (sourceRoute);
2019  newDsrRoutingHeader.AddDsrOption (ackReq);
2020  p->AddHeader (newDsrRoutingHeader);
2021 
2022  SetRoute (nextHop, m_mainAddress);
2025  // Send out the data packet
2026 
2027  uint32_t priority = GetPriority (DSR_DATA_PACKET);
2028  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2029  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2030  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2031 
2032  DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
2033 
2034  if (dsrNetworkQueue->Enqueue (newEntry))
2035  {
2036  Scheduler (priority);
2037  }
2038  else
2039  {
2040  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2041  }
2042  /*
2043  * Mark the next hop address in blacklist
2044  */
2045 // NS_LOG_DEBUG ("Save the next hop node in blacklist");
2046 // m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
2047  }
2048  else
2049  {
2050  NS_LOG_DEBUG ("Will not salvage this packet, silently drop");
2051  }
2052 }
2053 
2054 void
2056  bool onlyPassive,
2057  uint8_t protocol)
2058 {
2059  NS_LOG_FUNCTION (this << onlyPassive << (uint32_t)protocol);
2060 
2061  PassiveKey passiveKey;
2062  passiveKey.m_ackId = 0;
2063  passiveKey.m_source = mb.GetSrc ();
2064  passiveKey.m_destination = mb.GetDst ();
2065  passiveKey.m_segsLeft = mb.GetSegsLeft ();
2066 
2067  if (m_passiveAckTimer.find (passiveKey) == m_passiveAckTimer.end ())
2068  {
2070  m_passiveAckTimer[passiveKey] = timer;
2071  }
2072  NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
2073  m_passiveAckTimer[passiveKey].SetFunction (&DsrRouting::PassiveScheduleTimerExpire, this);
2074  m_passiveAckTimer[passiveKey].Remove ();
2075  m_passiveAckTimer[passiveKey].SetArguments (mb, onlyPassive, protocol);
2076  m_passiveAckTimer[passiveKey].Schedule (m_passiveAckTimeout);
2077 }
2078 
2079 void
2081  bool isFirst,
2082  uint8_t protocol)
2083 {
2084  Ptr<Packet> p = Create<Packet> ();
2085  Ptr<Packet> dsrP = Create<Packet> ();
2086  // The new entry will be used for retransmission
2087  NetworkKey networkKey;
2088  Ipv4Address nextHop = mb.GetNextHop ();
2089  NS_LOG_DEBUG ("is the first retry or not " << isFirst);
2090  if (isFirst)
2091  {
2092  // This is the very first network packet retry
2093  p = mb.GetPacket ()->Copy ();
2094  // Here we add the ack request header to the data packet for network acknowledgement
2095  uint16_t ackId = AddAckReqHeader (p, nextHop);
2096  dsrP = p->Copy ();
2097  MaintainBuffEntry newEntry = mb;
2098  // The function AllEqual will find the exact entry and delete it if found
2100  newEntry.SetPacket (dsrP);
2101  newEntry.SetAckId (ackId);
2102  newEntry.SetExpireTime (m_maxMaintainTime);
2103 
2104  networkKey.m_ackId = newEntry.GetAckId ();
2105  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2106  networkKey.m_nextHop = newEntry.GetNextHop ();
2107  networkKey.m_source = newEntry.GetSrc ();
2108  networkKey.m_destination = newEntry.GetDst ();
2109 
2110  m_addressForwardCnt[networkKey] = 0;
2111  m_maintainBuffer.Enqueue (newEntry);
2112 
2113  if (m_addressForwardTimer.find (networkKey) == m_addressForwardTimer.end ())
2114  {
2116  m_addressForwardTimer[networkKey] = timer;
2117  }
2118 
2119  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2120  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2121  m_addressForwardTimer[networkKey].Remove ();
2122  m_addressForwardTimer[networkKey].SetArguments (newEntry, protocol);
2123  NS_LOG_DEBUG ("The packet retries time for " << newEntry.GetAckId () << " is " << m_sendRetries
2124  << " and the delay time is " << Time (2 * m_nodeTraversalTime));
2125  // Back-off mechanism
2126  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_nodeTraversalTime));
2127  }
2128  else
2129  {
2130  networkKey.m_ackId = mb.GetAckId ();
2131  networkKey.m_ourAdd = mb.GetOurAdd ();
2132  networkKey.m_nextHop = mb.GetNextHop ();
2133  networkKey.m_source = mb.GetSrc ();
2134  networkKey.m_destination = mb.GetDst ();
2135  /*
2136  * Here we have found the entry for send retries, so we get the value and increase it by one
2137  */
2138  m_sendRetries = m_addressForwardCnt[networkKey];
2139  NS_LOG_DEBUG ("The packet retry we have done " << m_sendRetries);
2140 
2141  p = mb.GetPacket ()->Copy ();
2142  dsrP = mb.GetPacket ()->Copy ();
2143 
2144  NS_LOG_DEBUG ("The packet with dsr header " << dsrP->GetSize ());
2145  networkKey.m_ackId = mb.GetAckId ();
2146  networkKey.m_ourAdd = mb.GetOurAdd ();
2147  networkKey.m_nextHop = mb.GetNextHop ();
2148  networkKey.m_source = mb.GetSrc ();
2149  networkKey.m_destination = mb.GetDst ();
2150  /*
2151  * If a data packet has been attempted SendRetries times at the maximum TTL without
2152  * receiving any ACK, all data packets destined for the corresponding destination SHOULD be
2153  * dropped from the send buffer
2154  *
2155  * The maxMaintRexmt also needs to decrease one for the passive ack packet
2156  */
2157  /*
2158  * Check if the send retry time for a certain packet has already passed max maintenance retransmission
2159  * time or not
2160  */
2161 
2162  // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
2163  m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
2164  m_addressForwardTimer[networkKey].Remove ();
2165  m_addressForwardTimer[networkKey].SetArguments (mb, protocol);
2166  NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId () << " is " << m_sendRetries
2167  << " and the delay time is " << Time (2 * m_sendRetries * m_nodeTraversalTime));
2168  // Back-off mechanism
2169  m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries * m_nodeTraversalTime));
2170  }
2171 }
2172 
2173 void
2175  bool onlyPassive,
2176  uint8_t protocol)
2177 {
2178  NS_LOG_FUNCTION (this << onlyPassive << (uint32_t)protocol);
2179  Ipv4Address nextHop = mb.GetNextHop ();
2180  Ipv4Address source = mb.GetSrc ();
2181  Ptr<const Packet> packet = mb.GetPacket ();
2182  SetRoute (nextHop, m_mainAddress);
2183  Ptr<Packet> p = packet->Copy ();
2184 
2185  PassiveKey pk;
2186  pk.m_ackId = 0;
2187  pk.m_source = mb.GetSrc ();
2188  pk.m_destination = mb.GetDst ();
2189  pk.m_segsLeft = mb.GetSegsLeft ();
2190 
2191  // Cancel passive ack timer
2192  m_passiveAckTimer[pk].Cancel ();
2193  m_passiveAckTimer[pk].Remove ();
2194  if (m_passiveAckTimer[pk].IsRunning ())
2195  {
2196  NS_LOG_DEBUG ("Timer not canceled");
2197  }
2198  m_passiveAckTimer.erase (pk);
2199  // Send the data packet out before schedule the next packet transmission
2200  SendPacket (p, source, nextHop, protocol);
2201  // Increase the send retry times
2204  {
2206  SchedulePassivePacketRetry (mb, onlyPassive, protocol);
2207  }
2208  else if (!onlyPassive)
2209  {
2210  // This is the first network acknowledgement retry
2211  // Cancel the passive packet timer now and remove maintenance buffer entry for it
2213  ScheduleNetworkPacketRetry (mb, true, protocol);
2214  }
2215  else
2216  {
2217  // This is the end of the data retransmission retries
2219  // The function AllEqual will find the exact entry and delete it if found
2221  }
2222 }
2223 
2224 int64_t
2226 {
2227  NS_LOG_FUNCTION (this << stream);
2229  return 1;
2230 }
2231 
2232 void
2234  uint8_t protocol)
2235 {
2236  Ptr<Packet> p = mb.GetPacket ()->Copy ();
2237  Ipv4Address source = mb.GetSrc ();
2238  Ipv4Address nextHop = mb.GetNextHop ();
2239  Ipv4Address dst = mb.GetDst ();
2240 
2241  NetworkKey networkKey;
2242  networkKey.m_ackId = mb.GetAckId ();
2243  networkKey.m_ourAdd = mb.GetOurAdd ();
2244  networkKey.m_nextHop = nextHop;
2245  networkKey.m_source = source;
2246  networkKey.m_destination = dst;
2247 
2248  // Send the data packet out before schedule the next packet transmission
2249  SendPacket (p, source, nextHop, protocol);
2250  // Increase the send retry times
2251  m_sendRetries = m_addressForwardCnt[networkKey];
2252  NS_LOG_DEBUG ("The send retry time is " << m_sendRetries);
2254  {
2255  Ptr<Packet> dsrP = mb.GetPacket ()->Copy ();
2256  // The packet retries time has exceed the max maintenance retransmission times
2257  NS_LOG_LOGIC ("Packet transmissions to " << nextHop << " has been attempted SendRetries times for " << networkKey.m_ackId);
2258  DsrRoutingHeader dsrRoutingHeader;
2259  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
2260  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
2261  p->RemoveAtStart (offset);
2262 
2263  // Get the number of routers' address field
2264  uint8_t buf[2];
2265  p->CopyData (buf, sizeof(buf));
2266  uint8_t numberAddress = (buf[1] - 2) / 4;
2267  NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
2268  DsrOptionSRHeader sourceRoute;
2269  sourceRoute.SetNumberAddress (numberAddress);
2270  p->RemoveHeader (sourceRoute);
2271  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
2272  uint8_t salvage = sourceRoute.GetSalvage ();
2273  Ipv4Address address1 = nodeList[1];
2274  NS_LOG_DEBUG ("address1 " << address1);
2275  PrintVector (nodeList);
2276 
2277  // Delete all the routes including the links
2279  /*
2280  * If the salvage is not 0, use the first address in the route as the error dst in error header
2281  * otherwise use the source of packet as the error destination
2282  */
2283  Ipv4Address errorDst;
2284  if (salvage)
2285  {
2286  errorDst = address1;
2287  }
2288  else
2289  {
2290  errorDst = source;
2291  }
2292  SendUnreachError (nextHop, errorDst, dst, salvage, protocol);
2293  /*
2294  * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
2295  * Also salvage the packet for the all the packet destined for the nextHop address
2296  */
2297  CancelPacketTimerNextHop (nextHop, protocol);
2298  }
2299  else
2300  {
2301  m_addressForwardCnt[networkKey] = ++m_sendRetries;
2302  ScheduleNetworkPacketRetry (mb, false, protocol);
2303  }
2304 }
2305 
2306 void
2308  DsrOptionSRHeader &sourceRoute,
2309  Ipv4Header const& ipv4Header,
2310  Ipv4Address source,
2311  Ipv4Address nextHop,
2312  Ipv4Address targetAddress,
2313  uint8_t protocol,
2314  Ptr<Ipv4Route> route)
2315 {
2316  NS_LOG_FUNCTION (this << packet << sourceRoute << source << nextHop << targetAddress << (uint32_t)protocol << route);
2317  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2318 
2319  DsrRoutingHeader dsrRoutingHeader;
2320  dsrRoutingHeader.SetNextHeader (protocol);
2321  dsrRoutingHeader.SetMessageType (2);
2322  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2323  dsrRoutingHeader.SetDestId (GetIDfromIP (targetAddress));
2324 
2325  // We get the salvage value in sourceRoute header and set it to route error header if triggered error
2326  Ptr<Packet> p = packet->Copy ();
2327  uint8_t length = sourceRoute.GetLength ();
2328  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2329  dsrRoutingHeader.AddDsrOption (sourceRoute);
2330  p->AddHeader (dsrRoutingHeader);
2331 
2332  // Send the data packet out before schedule the next packet transmission
2333  SendPacket (p, source, nextHop, protocol);
2334 
2335  Ptr<const Packet> mtP = p->Copy ();
2336 
2337  MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
2338  /*source=*/ source, /*destination=*/ targetAddress,
2339  /*ackId=*/ m_ackId, /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
2340  bool result = m_maintainBuffer.Enqueue (newEntry);
2341 
2342  if (result)
2343  {
2344  NetworkKey networkKey;
2345  networkKey.m_ackId = newEntry.GetAckId ();
2346  networkKey.m_ourAdd = newEntry.GetOurAdd ();
2347  networkKey.m_nextHop = newEntry.GetNextHop ();
2348  networkKey.m_source = newEntry.GetSrc ();
2349  networkKey.m_destination = newEntry.GetDst ();
2350 
2351  PassiveKey passiveKey;
2352  passiveKey.m_ackId = 0;
2353  passiveKey.m_source = newEntry.GetSrc ();
2354  passiveKey.m_destination = newEntry.GetDst ();
2355  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
2356 
2357  m_addressForwardCnt[networkKey] = 0;
2358  m_passiveCnt[passiveKey] = 0;
2359  if (nextHop != targetAddress)
2360  {
2361  SchedulePassivePacketRetry (newEntry, false, protocol);
2362  }
2363  else
2364  {
2365  // This is the first network retry
2366  ScheduleNetworkPacketRetry (newEntry, true, protocol);
2367  }
2368  }
2369 }
2370 
2371 void
2373  Ipv4Address destination,
2374  uint8_t protocol)
2375 {
2376  NS_LOG_FUNCTION (this << source << destination << (uint32_t)protocol);
2377  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2378  Ptr<Packet> packet = Create<Packet> ();
2379  // Create an empty Ipv4 route ptr
2380  Ptr<Ipv4Route> route;
2381  /*
2382  * Construct the route request option header
2383  */
2384  DsrRoutingHeader dsrRoutingHeader;
2385  dsrRoutingHeader.SetNextHeader (protocol);
2386  dsrRoutingHeader.SetMessageType (1);
2387  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
2388  dsrRoutingHeader.SetDestId (255);
2389 
2390  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2391  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2392  rreqHeader.SetTarget (destination);
2393  m_requestId = m_rreqTable->CheckUniqueRreqId (destination); // Check the Id cache for duplicate ones
2394  rreqHeader.SetId (m_requestId);
2395 
2396  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2397  uint8_t length = rreqHeader.GetLength ();
2398  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2399  packet->AddHeader (dsrRoutingHeader);
2400 
2401  // Schedule the route requests retry with non-propagation set true
2402  bool nonProp = true;
2403  std::vector<Ipv4Address> address;
2404  address.push_back (source);
2405  address.push_back (destination);
2406  /*
2407  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2408  */
2409  SocketIpTtlTag tag;
2410  tag.SetTtl (0);
2411  Ptr<Packet> nonPropPacket = packet->Copy ();
2412  nonPropPacket->AddPacketTag (tag);
2413  SendRequest (nonPropPacket, source);
2414  // Schedule the next route request
2415  ScheduleRreqRetry (packet, address, nonProp, m_requestId, protocol);
2416 }
2417 
2418 void
2420 {
2421  NS_LOG_FUNCTION (this << (uint32_t)protocol);
2422  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2423  uint8_t salvage = rerr.GetSalvage ();
2424  Ipv4Address dst = rerr.GetOriginalDst ();
2425  NS_LOG_DEBUG ("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc () << " error destination " << rerr.GetErrorDst ()
2426  << " error next hop " << rerr.GetUnreachNode () << " original dst " << rerr.GetOriginalDst ()
2427  );
2428  RouteCacheEntry toDst;
2429  if (m_routeCache->LookupRoute (dst, toDst))
2430  {
2431  /*
2432  * Found a route the dst, construct the source route option header
2433  */
2434  DsrOptionSRHeader sourceRoute;
2435  std::vector<Ipv4Address> ip = toDst.GetVector ();
2436  sourceRoute.SetNodesAddress (ip);
2437  if (m_routeCache->IsLinkCache ())
2438  {
2439  m_routeCache->UseExtends (ip);
2440  }
2441  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
2442  sourceRoute.SetSalvage (salvage);
2443  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
2444  NS_LOG_DEBUG ("The nextHop address " << nextHop);
2445  Ptr<Packet> packet = Create<Packet> ();
2446  if (nextHop == "0.0.0.0")
2447  {
2448  NS_LOG_DEBUG ("Error next hop address");
2449  PacketNewRoute (packet, m_mainAddress, dst, protocol);
2450  return;
2451  }
2452  SetRoute (nextHop, m_mainAddress);
2453  CancelRreqTimer (dst, true);
2454  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
2455  NS_LOG_LOGIC ("Route to " << dst << " found");
2456  return;
2457  }
2458  else
2459  {
2460  NS_LOG_INFO ("No route found, initiate route error request");
2461  Ptr<Packet> packet = Create<Packet> ();
2462  Ipv4Address originalDst = rerr.GetOriginalDst ();
2463  // Create an empty route ptr
2464  Ptr<Ipv4Route> route = 0;
2465  /*
2466  * Construct the route request option header
2467  */
2468  DsrRoutingHeader dsrRoutingHeader;
2469  dsrRoutingHeader.SetNextHeader (protocol);
2470  dsrRoutingHeader.SetMessageType (1);
2471  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
2472  dsrRoutingHeader.SetDestId (255);
2473 
2474  Ptr<Packet> dstP = Create<Packet> ();
2475  DsrOptionRreqHeader rreqHeader; // has an alignment of 4n+0
2476  rreqHeader.AddNodeAddress (m_mainAddress); // Add our own address in the header
2477  rreqHeader.SetTarget (originalDst);
2478  m_requestId = m_rreqTable->CheckUniqueRreqId (originalDst); // Check the Id cache for duplicate ones
2479  rreqHeader.SetId (m_requestId);
2480 
2481  dsrRoutingHeader.AddDsrOption (rreqHeader); // Add the rreqHeader to the dsr extension header
2482  dsrRoutingHeader.AddDsrOption (rerr);
2483  uint8_t length = rreqHeader.GetLength () + rerr.GetLength ();
2484  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
2485  dstP->AddHeader (dsrRoutingHeader);
2486  // Schedule the route requests retry, propagate the route request message as it contains error
2487  bool nonProp = false;
2488  std::vector<Ipv4Address> address;
2489  address.push_back (m_mainAddress);
2490  address.push_back (originalDst);
2491  /*
2492  * Add the socket ip ttl tag to the packet to limit the scope of route requests
2493  */
2494  SocketIpTtlTag tag;
2495  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
2496  Ptr<Packet> propPacket = dstP->Copy ();
2497  propPacket->AddPacketTag (tag);
2498 
2499  if ((m_addressReqTimer.find (originalDst) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (originalDst) == m_nonPropReqTimer.end ()))
2500  {
2501  NS_LOG_INFO ("Only when there is no existing route request time when the initial route request is scheduled");
2502  SendRequest (propPacket, m_mainAddress);
2503  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2504  }
2505  else
2506  {
2507  NS_LOG_INFO ("There is existing route request, find the existing route request entry");
2508  /*
2509  * Cancel the route request timer first before scheduling the route request
2510  * in this case, we do not want to remove the route request entry, so the isRemove value is false
2511  */
2512  CancelRreqTimer (originalDst, false);
2513  ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
2514  }
2515  }
2516 }
2517 
2518 void
2520 {
2521  NS_LOG_FUNCTION (this << dst << isRemove);
2522  // Cancel the non propagation request timer if found
2523  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2524  {
2525  NS_LOG_DEBUG ("Did not find the non-propagation timer");
2526  }
2527  else
2528  {
2529  NS_LOG_DEBUG ("did find the non-propagation timer");
2530  }
2531  m_nonPropReqTimer[dst].Cancel ();
2532  m_nonPropReqTimer[dst].Remove ();
2533 
2534  if (m_nonPropReqTimer[dst].IsRunning ())
2535  {
2536  NS_LOG_DEBUG ("Timer not canceled");
2537  }
2538  m_nonPropReqTimer.erase (dst);
2539 
2540  // Cancel the address request timer if found
2541  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2542  {
2543  NS_LOG_DEBUG ("Did not find the propagation timer");
2544  }
2545  else
2546  {
2547  NS_LOG_DEBUG ("did find the propagation timer");
2548  }
2549  m_addressReqTimer[dst].Cancel ();
2550  m_addressReqTimer[dst].Remove ();
2551  if (m_addressReqTimer[dst].IsRunning ())
2552  {
2553  NS_LOG_DEBUG ("Timer not canceled");
2554  }
2555  m_addressReqTimer.erase (dst);
2556  /*
2557  * If the route request is scheduled to remove the route request entry
2558  * Remove the route request entry with the route retry times done for certain destination
2559  */
2560  if (isRemove)
2561  {
2562  // remove the route request entry from route request table
2564  }
2565 }
2566 
2567 void
2568 DsrRouting::ScheduleRreqRetry (Ptr<Packet> packet, std::vector<Ipv4Address> address, bool nonProp, uint32_t requestId, uint8_t protocol)
2569 {
2570  NS_LOG_FUNCTION (this << packet << nonProp << requestId << (uint32_t)protocol);
2571  Ipv4Address source = address[0];
2572  Ipv4Address dst = address[1];
2573  if (nonProp)
2574  {
2575  // The nonProp route request is only sent out only and is already used
2576  if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
2577  {
2579  m_nonPropReqTimer[dst] = timer;
2580  }
2581  std::vector<Ipv4Address> address;
2582  address.push_back (source);
2583  address.push_back (dst);
2584  m_nonPropReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2585  m_nonPropReqTimer[dst].Remove ();
2586  m_nonPropReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2588  }
2589  else
2590  {
2591  // Cancel the non propagation request timer if found
2592  m_nonPropReqTimer[dst].Cancel ();
2593  m_nonPropReqTimer[dst].Remove ();
2594  if (m_nonPropReqTimer[dst].IsRunning ())
2595  {
2596  NS_LOG_DEBUG ("Timer not canceled");
2597  }
2598  m_nonPropReqTimer.erase (dst);
2599 
2600  if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
2601  {
2603  m_addressReqTimer[dst] = timer;
2604  }
2605  std::vector<Ipv4Address> address;
2606  address.push_back (source);
2607  address.push_back (dst);
2608  m_addressReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
2609  m_addressReqTimer[dst].Remove ();
2610  m_addressReqTimer[dst].SetArguments (packet, address, requestId, protocol);
2611  Time rreqDelay;
2612  // back off mechanism for sending route requests
2613  if (m_rreqTable->GetRreqCnt (dst))
2614  {
2615  // When the route request count is larger than 0
2616  rreqDelay = Time (pow (m_rreqTable->GetRreqCnt (dst), 2) * m_requestPeriod);
2617  }
2618  else
2619  {
2620  // This is the first route request retry
2621  rreqDelay = m_requestPeriod;
2622  }
2623  NS_LOG_DEBUG ("The request count for the destination " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with time value " << rreqDelay);
2624  if (rreqDelay > m_maxRequestPeriod)
2625  {
2626  // use the max request period
2627  NS_LOG_DEBUG ("The max request delay time " << m_maxRequestPeriod.GetSeconds ());
2628  m_addressReqTimer[dst].Schedule (m_maxRequestPeriod);
2629  }
2630  else
2631  {
2632  NS_LOG_DEBUG ("The request delay time " << rreqDelay.GetSeconds ());
2633  m_addressReqTimer[dst].Schedule (rreqDelay);
2634  }
2635 
2636  }
2637 }
2638 
2639 void
2640 DsrRouting::RouteRequestTimerExpire (Ptr<Packet> packet, std::vector<Ipv4Address> address, uint32_t requestId, uint8_t protocol)
2641 {
2642  NS_LOG_FUNCTION (this << packet << requestId << (uint32_t)protocol);
2643  // Get a clean packet without dsr header
2644  Ptr<Packet> dsrP = packet->Copy ();
2645  DsrRoutingHeader dsrRoutingHeader;
2646  dsrP->RemoveHeader (dsrRoutingHeader); // Remove the dsr header in whole
2647 
2648  Ipv4Address source = address[0];
2649  Ipv4Address dst = address[1];
2650  RouteCacheEntry toDst;
2651  if (m_routeCache->LookupRoute (dst, toDst))
2652  {
2653  /*
2654  * Found a route the dst, construct the source route option header
2655  */
2656  DsrOptionSRHeader sourceRoute;
2657  std::vector<Ipv4Address> ip = toDst.GetVector ();
2658  sourceRoute.SetNodesAddress (ip);
2659  if (m_routeCache->IsLinkCache ())
2660  {
2661  m_routeCache->UseExtends (ip);
2662  }
2663  sourceRoute.SetSegmentsLeft ((ip.size () - 2));
2664  uint8_t salvage = 0;
2665  sourceRoute.SetSalvage (salvage);
2666  Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip); // Get the next hop address
2667  NS_LOG_DEBUG ("The nextHop address " << nextHop);
2668  if (nextHop == "0.0.0.0")
2669  {
2670  NS_LOG_DEBUG ("Error next hop address");
2671  PacketNewRoute (dsrP, source, dst, protocol);
2672  return;
2673  }
2674  SetRoute (nextHop, m_mainAddress);
2675  CancelRreqTimer (dst, true);
2676  SendPacketFromBuffer (sourceRoute, nextHop, protocol);
2677  NS_LOG_LOGIC ("Route to " << dst << " found");
2678  return;
2679  }
2680  /*
2681  * If a route discovery has been attempted m_rreqRetries times at the maximum TTL without
2682  * receiving any RREP, all data packets destined for the corresponding destination SHOULD be
2683  * dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
2684  */
2685  NS_LOG_DEBUG ("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt (dst) << " the max " << m_rreqRetries);
2686  if (m_rreqTable->GetRreqCnt (dst) >= m_rreqRetries)
2687  {
2688  NS_LOG_LOGIC ("Route discovery to " << dst << " has been attempted " << m_rreqRetries << " times");
2689  CancelRreqTimer (dst, true);
2690  NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
2692  }
2693  else
2694  {
2695  SocketIpTtlTag tag;
2696  tag.SetTtl ((uint8_t)m_discoveryHopLimit);
2697  Ptr<Packet> propPacket = packet->Copy ();
2698  propPacket->AddPacketTag (tag);
2699  // Increase the request count
2700  m_rreqTable->FindAndUpdate (dst);
2701  SendRequest (propPacket, source);
2702  NS_LOG_DEBUG ("Check the route request entry " << source << " " << dst);
2703  ScheduleRreqRetry (packet, address, false, requestId, protocol);
2704  }
2705  return;
2706 }
2707 
2708 void
2710  Ipv4Address source)
2711 {
2712  NS_LOG_FUNCTION (this << packet << source);
2713  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2714  /*
2715  * The destination address here is directed broadcast address
2716  */
2717  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
2718  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2719  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2720  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2721 
2722  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
2723 
2724  if (dsrNetworkQueue->Enqueue (newEntry))
2725  {
2726  Scheduler (priority);
2727  }
2728  else
2729  {
2730  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2731  }
2732 }
2733 
2734 void
2736 {
2737  NS_LOG_FUNCTION (this << packet);
2738  /*
2739  * This is a forwarding case when sending route requests, a random delay time [0, m_broadcastJitter]
2740  * used before forwarding as link-layer broadcast
2741  */
2743  packet, m_mainAddress);
2744 }
2745 
2746 void
2747 DsrRouting::SendGratuitousReply (Ipv4Address source, Ipv4Address srcAddress, std::vector<Ipv4Address> &nodeList, uint8_t protocol)
2748 {
2749  NS_LOG_FUNCTION (this << source << srcAddress << (uint32_t)protocol);
2750  if (!(m_graReply.FindAndUpdate (source, srcAddress, m_gratReplyHoldoff))) // Find the gratuitous reply entry
2751  {
2752  NS_LOG_LOGIC ("Update gratuitous reply " << source);
2753  GraReplyEntry graReplyEntry (source, srcAddress, m_gratReplyHoldoff + Simulator::Now ());
2754  m_graReply.AddEntry (graReplyEntry);
2755  /*
2756  * Automatic route shortening
2757  */
2758  m_finalRoute.clear (); // Clear the final route vector
2762  std::vector<Ipv4Address>::iterator before = find (nodeList.begin (), nodeList.end (), srcAddress);
2763  for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != before; ++i)
2764  {
2765  m_finalRoute.push_back (*i);
2766  }
2767  m_finalRoute.push_back (srcAddress);
2768  std::vector<Ipv4Address>::iterator after = find (nodeList.begin (), nodeList.end (), m_mainAddress);
2769  for (std::vector<Ipv4Address>::iterator j = after; j != nodeList.end (); ++j)
2770  {
2771  m_finalRoute.push_back (*j);
2772  }
2773  DsrOptionRrepHeader rrep;
2774  rrep.SetNodesAddress (m_finalRoute); // Set the node addresses in the route reply header
2775  // Get the real reply source and destination
2776  Ipv4Address replySrc = m_finalRoute.back ();
2777  Ipv4Address replyDst = m_finalRoute.front ();
2778  /*
2779  * Set the route and use it in send back route reply
2780  */
2781  m_ipv4Route = SetRoute (srcAddress, m_mainAddress);
2782  /*
2783  * This part adds DSR header to the packet and send reply
2784  */
2785  DsrRoutingHeader dsrRoutingHeader;
2786  dsrRoutingHeader.SetNextHeader (protocol);
2787  dsrRoutingHeader.SetMessageType (1);
2788  dsrRoutingHeader.SetSourceId (GetIDfromIP (replySrc));
2789  dsrRoutingHeader.SetDestId (GetIDfromIP (replyDst));
2790 
2791  uint8_t length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
2792  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2793  dsrRoutingHeader.AddDsrOption (rrep);
2794  Ptr<Packet> newPacket = Create<Packet> ();
2795  newPacket->AddHeader (dsrRoutingHeader);
2796  /*
2797  * Send gratuitous reply
2798  */
2799  NS_LOG_INFO ("Send back gratuitous route reply");
2800  SendReply (newPacket, m_mainAddress, srcAddress, m_ipv4Route);
2801  }
2802  else
2803  {
2804  NS_LOG_INFO ("The same gratuitous route reply has already sent");
2805  }
2806 }
2807 
2808 void
2810  Ipv4Address source,
2811  Ipv4Address nextHop,
2812  Ptr<Ipv4Route> route)
2813 {
2814  NS_LOG_FUNCTION (this << packet << source << nextHop);
2815  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2817  route->SetOutputDevice (dev);
2818  NS_LOG_INFO ("The output device " << dev << " packet is: " << *packet);
2819 
2820  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
2821  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2822  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2823  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2824 
2825  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
2826 
2827  if (dsrNetworkQueue->Enqueue (newEntry))
2828  {
2829  Scheduler (priority);
2830  }
2831  else
2832  {
2833  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2834  }
2835 }
2836 
2837 void
2839  Ipv4Address source,
2840  Ipv4Address nextHop,
2841  Ptr<Ipv4Route> route)
2842 {
2843  NS_LOG_FUNCTION (this << packet << source << nextHop);
2845  packet, source, nextHop, route);
2846 }
2847 
2848 void
2850  Ipv4Address source,
2851  Ipv4Address destination,
2852  Ptr<Ipv4Route> route,
2853  double hops)
2854 {
2855  NS_LOG_FUNCTION (this << packet << source << destination);
2856  Simulator::Schedule (Time (2 * m_nodeTraversalTime * (hops - 1 + m_uniformRandomVariable->GetValue (0,1))), &DsrRouting::SendReply, this, packet, source, destination, route);
2857 }
2858 
2859 void
2860 DsrRouting::SendAck (uint16_t ackId,
2861  Ipv4Address destination,
2862  Ipv4Address realSrc,
2863  Ipv4Address realDst,
2864  uint8_t protocol,
2865  Ptr<Ipv4Route> route)
2866 {
2867  NS_LOG_FUNCTION (this << ackId << destination << realSrc << realDst << (uint32_t)protocol << route);
2868  NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
2869 
2870  // This is a route reply option header
2871  DsrRoutingHeader dsrRoutingHeader;
2872  dsrRoutingHeader.SetNextHeader (protocol);
2873  dsrRoutingHeader.SetMessageType (1);
2874  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
2875  dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
2876 
2877  DsrOptionAckHeader ack;
2878  /*
2879  * Set the ack Id and set the ack source address and destination address
2880  */
2881  ack.SetAckId (ackId);
2882  ack.SetRealSrc (realSrc);
2883  ack.SetRealDst (realDst);
2884 
2885  uint8_t length = ack.GetLength ();
2886  dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
2887  dsrRoutingHeader.AddDsrOption (ack);
2888 
2889  Ptr<Packet> packet = Create<Packet> ();
2890  packet->AddHeader (dsrRoutingHeader);
2892  route->SetOutputDevice (dev);
2893  NS_LOG_DEBUG ("Send out the ACK");
2894 
2895  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
2896  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
2897  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
2898  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
2899 
2900  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
2901 
2902  if (dsrNetworkQueue->Enqueue (newEntry))
2903  {
2904  Scheduler (priority);
2905  }
2906  else
2907  {
2908  NS_LOG_INFO ("Packet dropped as dsr network queue is full");
2909  }
2910 }
2911 
2914  Ipv4Header const &ip,
2915  Ptr<Ipv4Interface> incomingInterface)
2916 {
2917  NS_LOG_FUNCTION (this << p << ip << incomingInterface);
2918 
2919  NS_LOG_INFO ("Our own IP address " << m_mainAddress << " The incoming interface address " << incomingInterface);
2920  m_node = GetNode (); // Get the node
2921  Ptr<Packet> packet = p->Copy (); // Save a copy of the received packet
2922  /*
2923  * When forwarding or local deliver packets, this one should be used always!!
2924  */
2925  DsrRoutingHeader dsrRoutingHeader;
2926  packet->RemoveHeader (dsrRoutingHeader); // Remove the DSR header in whole
2927  Ptr<Packet> copy = packet->Copy ();
2928  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
2929  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
2930  Ipv4Address source = GetIPfromID (sourceId);
2931  NS_LOG_DEBUG ("The source address " << source << " with source id " << sourceId);
2932  /*
2933  * Get the IP source and destination address
2934  */
2935  Ipv4Address src = ip.GetSource ();
2936 
2937  bool isPromisc = false;
2938  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset (); // Get the offset for option header, 8 bytes in this case
2939 
2940  // This packet is used to peek option type
2941  p->RemoveAtStart (offset);
2942 
2943  Ptr<dsr::DsrOptions> dsrOption;
2944  DsrOptionHeader dsrOptionHeader;
2945  /*
2946  * Peek data to get the option type as well as length and segmentsLeft field
2947  */
2948  uint32_t size = p->GetSize ();
2949  uint8_t *data = new uint8_t[size];
2950  p->CopyData (data, size);
2951 
2952  uint8_t optionType = 0;
2953  uint8_t optionLength = 0;
2954  uint8_t segmentsLeft = 0;
2955 
2956  optionType = *(data);
2957  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet size " << p->GetSize ());
2958  dsrOption = GetOption (optionType); // Get the relative dsr option and demux to the process function
2959 
2960  if (optionType == 1) // This is the request option
2961  {
2962  BlackList *blackList = m_rreqTable->FindUnidirectional (src);
2963  if (blackList)
2964  {
2965  NS_LOG_DEBUG ("Discard this packet due to unidirectional link");
2966  m_dropTrace (p);
2967  }
2968 
2969  dsrOption = GetOption (optionType);
2970  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc);
2971 
2972  if (optionLength == 0)
2973  {
2974  NS_LOG_DEBUG ("Discard this packet");
2975  m_dropTrace (p);
2976  }
2977  }
2978  else if (optionType == 2)
2979  {
2980  dsrOption = GetOption (optionType);
2981  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc);
2982 
2983  if (optionLength == 0)
2984  {
2985  NS_LOG_DEBUG ("Discard this packet");
2986  m_dropTrace (p);
2987  }
2988  }
2989 
2990  else if (optionType == 32) // This is the ACK option
2991  {
2992  NS_LOG_DEBUG ("This is the ack option");
2993  dsrOption = GetOption (optionType);
2994  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc);
2995 
2996  if (optionLength == 0)
2997  {
2998  NS_LOG_DEBUG ("Discard this packet");
2999  m_dropTrace (p);
3000  }
3001  }
3002 
3003  else if (optionType == 3) // This is a route error header
3004  {
3005  // populate this route error
3006  NS_LOG_DEBUG ("The option type value " << (uint32_t)optionType);
3007 
3008  dsrOption = GetOption (optionType);
3009  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc);
3010 
3011  if (optionLength == 0)
3012  {
3013  NS_LOG_DEBUG ("Discard this packet");
3014  m_dropTrace (p);
3015  }
3016  NS_LOG_DEBUG ("The option Length " << (uint32_t)optionLength);
3017  }
3018 
3019  else if (optionType == 96) // This is the source route option
3020  {
3021  NS_LOG_DEBUG ("This is the source route option " << (uint32_t)optionType);
3022  dsrOption = GetOption (optionType);
3023  optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc);
3024 
3025  segmentsLeft = *(data + 3);
3026  NS_LOG_DEBUG ("The segments left in source route header " << (uint32_t)segmentsLeft);
3027  if (optionLength == 0)
3028  {
3029  NS_LOG_DEBUG ("Discard this packet");
3030  m_dropTrace (p);
3031  }
3032  else
3033  {
3034  if (segmentsLeft == 0)
3035  {
3036  // / Get the next header
3037  uint8_t nextHeader = dsrRoutingHeader.GetNextHeader ();
3039  Ptr<IpL4Protocol> nextProto = l3proto->GetProtocol (nextHeader);
3040  if (nextProto != 0)
3041  {
3042  // we need to make a copy in the unlikely event we hit the
3043  // RX_ENDPOINT_UNREACH code path
3044  // Here we can use the packet that has been get off whole DSR header
3045  NS_LOG_DEBUG ("The packet size here " << copy->GetSize ());
3046  NS_LOG_DEBUG ("The packet received " << *copy);
3047  enum IpL4Protocol::RxStatus status =
3048  nextProto->Receive (copy, ip, incomingInterface);
3049  NS_LOG_DEBUG ("The receive status " << status);
3050  switch (status)
3051  {
3052  case IpL4Protocol::RX_OK:
3053  // fall through
3055  // fall through
3057  break;
3059  if (ip.GetDestination ().IsBroadcast () == true
3060  || ip.GetDestination ().IsMulticast () == true)
3061  {
3062  break; // Do not reply to broadcast or multicast
3063  }
3064  // Another case to suppress ICMP is a subnet-directed broadcast
3065  }
3066  return status;
3067  }
3068  }
3069  else
3070  {
3071  NS_LOG_INFO ("This is not the final destination, the packet has already been forward to next hop");
3072  }
3073  }
3074  }
3075  else
3076  {
3077  NS_LOG_LOGIC ("Unknown Option. Drop!");
3078  /*
3079  * Initialize the salvage value to 0
3080  */
3081  uint8_t salvage = 0;
3082 
3083  DsrOptionRerrUnsupportHeader rerrUnsupportHeader;
3084  rerrUnsupportHeader.SetErrorType (3); // The error type 3 means Option not supported
3085  rerrUnsupportHeader.SetErrorSrc (m_mainAddress); // The error source address is our own address
3086  rerrUnsupportHeader.SetUnsupported (optionType); // The unsupported option type number
3087  rerrUnsupportHeader.SetErrorDst (src); // Error destination address is the destination of the data packet
3088  rerrUnsupportHeader.SetSalvage (salvage); // Set the value about whether to salvage a packet or not
3089 
3090  /*
3091  * The unknow option error is not supported currently in this implementation, and it's also not likely to
3092  * happen in simulations
3093  */
3094 // SendError (rerrUnsupportHeader, 0, protocol); // Send the error packet
3095  }
3096  return IpL4Protocol::RX_OK;
3097 }
3098 
3101  Ipv6Address &src,
3102  Ipv6Address &dst,
3103  Ptr<Ipv6Interface> incomingInterface)
3104 {
3105  NS_LOG_FUNCTION (this << p << src << dst << incomingInterface);
3107 }
3108 
3109 void
3111 {
3112  m_downTarget = callback;
3113 }
3114 
3115 void
3117 {
3118  NS_FATAL_ERROR ("Unimplemented");
3119 }
3120 
3121 
3124 {
3125  return m_downTarget;
3126 }
3127 
3130 {
3131  NS_FATAL_ERROR ("Unimplemented");
3132  return MakeNullCallback<void,Ptr<Packet>, Ipv6Address, Ipv6Address, uint8_t, Ptr<Ipv6Route> > ();
3133 }
3134 
3136 {
3137  m_options.push_back (option);
3138 }
3139 
3141 {
3142  for (DsrOptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
3143  {
3144  if ((*i)->GetOptionNumber () == optionNumber)
3145  {
3146  return *i;
3147  }
3148  }
3149  return 0;
3150 }
3151 } /* namespace dsr */
3152 } /* namespace ns3 */