Update DSR model
authorYufei Cheng <yfcheng@ittc.ku.edu>
Sun, 06 May 2012 20:52:24 -0700
changeset 8752 2da1fab73114
parent 8751 efad81f3cb47
child 8753 8d84b96e26bf
Update DSR model
examples/routing/manet-routing-compare.cc
manet-routing.output.csv.dsr
manet-routing.output.csv.olsr
src/dsr/examples/dsr.cc
src/dsr/examples/wscript
src/dsr/helper/dsr-main-helper.cc
src/dsr/model/dsr-errorbuff.cc
src/dsr/model/dsr-errorbuff.h
src/dsr/model/dsr-fs-header.h
src/dsr/model/dsr-maintain-buff.cc
src/dsr/model/dsr-maintain-buff.h
src/dsr/model/dsr-network-queue.cc
src/dsr/model/dsr-network-queue.h
src/dsr/model/dsr-option-header.cc
src/dsr/model/dsr-option-header.h
src/dsr/model/dsr-options.cc
src/dsr/model/dsr-rcache.cc
src/dsr/model/dsr-rcache.h
src/dsr/model/dsr-routing.cc
src/dsr/model/dsr-routing.h
src/dsr/model/dsr-rreq-table.cc
src/dsr/model/dsr-rreq-table.h
src/dsr/model/dsr-rsendbuff.cc
src/dsr/model/dsr-rsendbuff.h
src/dsr/wscript
--- a/examples/routing/manet-routing-compare.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/examples/routing/manet-routing-compare.cc	Sun May 06 20:52:24 2012 -0700
@@ -269,6 +269,21 @@
   wifiMac.SetType ("ns3::AdhocWifiMac");
   NetDeviceContainer adhocDevices = wifi.Install (wifiPhy, wifiMac, adhocNodes);
 
+  MobilityHelper mobilityAdhoc;
+
+  ObjectFactory pos;
+  pos.SetTypeId ("ns3::RandomRectanglePositionAllocator");
+  pos.Set ("X", RandomVariableValue (UniformVariable (0.0, 300.0)));
+  pos.Set ("Y", RandomVariableValue (UniformVariable (0.0, 1500.0)));
+
+  Ptr<PositionAllocator> taPositionAlloc = pos.Create ()->GetObject<PositionAllocator> ();
+  mobilityAdhoc.SetMobilityModel ("ns3::RandomWaypointMobilityModel",
+                                  "Speed", RandomVariableValue (UniformVariable (0.0, nodeSpeed)),
+                                  "Pause", RandomVariableValue (ConstantVariable (nodePause)),
+                                  "PositionAllocator", PointerValue (taPositionAlloc));
+  mobilityAdhoc.SetPositionAllocator (taPositionAlloc);
+  mobilityAdhoc.Install (adhocNodes);
+
   AodvHelper aodv;
   OlsrHelper olsr;
   DsdvHelper dsdv;
@@ -316,21 +331,6 @@
   Ipv4InterfaceContainer adhocInterfaces;
   adhocInterfaces = addressAdhoc.Assign (adhocDevices);
 
-  MobilityHelper mobilityAdhoc;
-
-  ObjectFactory pos;
-  pos.SetTypeId ("ns3::RandomRectanglePositionAllocator");
-  pos.Set ("X", RandomVariableValue (UniformVariable (0.0, 300.0)));
-  pos.Set ("Y", RandomVariableValue (UniformVariable (0.0, 1500.0)));
-
-  Ptr<PositionAllocator> taPositionAlloc = pos.Create ()->GetObject<PositionAllocator> ();
-  mobilityAdhoc.SetMobilityModel ("ns3::RandomWaypointMobilityModel",
-                                  "Speed", RandomVariableValue (UniformVariable (0.0, nodeSpeed)),
-                                  "Pause", RandomVariableValue (ConstantVariable (nodePause)),
-                                  "PositionAllocator", PointerValue (taPositionAlloc));
-  mobilityAdhoc.SetPositionAllocator (taPositionAlloc);
-  mobilityAdhoc.Install (adhocNodes);
-
   OnOffHelper onoff1 ("ns3::UdpSocketFactory",Address ());
   onoff1.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable  (1)));
   onoff1.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
@@ -344,7 +344,7 @@
 
       UniformVariable var;
       ApplicationContainer temp = onoff1.Install (adhocNodes.Get (i + nSinks));
-      temp.Start (Seconds (var.GetValue (50.0,51.0)));
+      temp.Start (Seconds (var.GetValue (100.0,101.0)));
       temp.Stop (Seconds (TotalTime));
     }
 
--- a/manet-routing.output.csv.dsr	Fri Jan 27 15:15:48 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-SimulationSecond,ReceiveRate,PacketsReceived,NumberOfSinks,RoutingProtocol,TransmissionPower
-0,0,0,10,DSR,7.5
-1,0,0,10,DSR,7.5
-2,0,0,10,DSR,7.5
-3,0,0,10,DSR,7.5
-4,0,0,10,DSR,7.5
-5,0,0,10,DSR,7.5
-6,0,0,10,DSR,7.5
-7,0,0,10,DSR,7.5
-8,0,0,10,DSR,7.5
-9,0,0,10,DSR,7.5
-10,0,0,10,DSR,7.5
-11,0,0,10,DSR,7.5
-12,0,0,10,DSR,7.5
-13,0,0,10,DSR,7.5
-14,0,0,10,DSR,7.5
-15,0,0,10,DSR,7.5
-16,0,0,10,DSR,7.5
-17,0,0,10,DSR,7.5
-18,0,0,10,DSR,7.5
-19,0,0,10,DSR,7.5
-20,0,0,10,DSR,7.5
-21,0,0,10,DSR,7.5
-22,0,0,10,DSR,7.5
-23,0,0,10,DSR,7.5
-24,0,0,10,DSR,7.5
-25,0,0,10,DSR,7.5
-26,0,0,10,DSR,7.5
-27,0,0,10,DSR,7.5
-28,0,0,10,DSR,7.5
-29,0,0,10,DSR,7.5
-30,0,0,10,DSR,7.5
-31,0,0,10,DSR,7.5
-32,0,0,10,DSR,7.5
-33,0,0,10,DSR,7.5
-34,0,0,10,DSR,7.5
-35,0,0,10,DSR,7.5
-36,0,0,10,DSR,7.5
-37,0,0,10,DSR,7.5
-38,0,0,10,DSR,7.5
-39,0,0,10,DSR,7.5
-40,0,0,10,DSR,7.5
-41,0,0,10,DSR,7.5
-42,0,0,10,DSR,7.5
-43,0,0,10,DSR,7.5
-44,0,0,10,DSR,7.5
-45,0,0,10,DSR,7.5
-46,0,0,10,DSR,7.5
-47,0,0,10,DSR,7.5
-48,0,0,10,DSR,7.5
-49,0,0,10,DSR,7.5
-50,0,0,10,DSR,7.5
-51,0,0,10,DSR,7.5
-52,0,0,10,DSR,7.5
-53,1.536,3,10,DSR,7.5
-54,71.168,139,10,DSR,7.5
-55,29.184,57,10,DSR,7.5
-56,0,0,10,DSR,7.5
-57,0,0,10,DSR,7.5
-58,0,0,10,DSR,7.5
-59,3.584,7,10,DSR,7.5
-60,12.288,24,10,DSR,7.5
-61,7.168,14,10,DSR,7.5
-62,5.12,10,10,DSR,7.5
-63,0,0,10,DSR,7.5
-64,0,0,10,DSR,7.5
-65,0,0,10,DSR,7.5
-66,0,0,10,DSR,7.5
-67,1.536,3,10,DSR,7.5
-68,0,0,10,DSR,7.5
-69,0,0,10,DSR,7.5
-70,0,0,10,DSR,7.5
-71,0,0,10,DSR,7.5
-72,0,0,10,DSR,7.5
-73,0,0,10,DSR,7.5
-74,0,0,10,DSR,7.5
-75,0,0,10,DSR,7.5
-76,0,0,10,DSR,7.5
-77,3.584,7,10,DSR,7.5
-78,14.336,28,10,DSR,7.5
-79,12.288,24,10,DSR,7.5
-80,0.512,1,10,DSR,7.5
-81,0,0,10,DSR,7.5
-82,1.024,2,10,DSR,7.5
-83,4.096,8,10,DSR,7.5
-84,4.096,8,10,DSR,7.5
-85,2.048,4,10,DSR,7.5
-86,1.536,3,10,DSR,7.5
-87,7.68,15,10,DSR,7.5
-88,4.608,9,10,DSR,7.5
-89,5.632,11,10,DSR,7.5
-90,0.512,1,10,DSR,7.5
-91,5.632,11,10,DSR,7.5
-92,8.192,16,10,DSR,7.5
-93,14.848,29,10,DSR,7.5
-94,10.752,21,10,DSR,7.5
-95,14.336,28,10,DSR,7.5
-96,2.048,4,10,DSR,7.5
-97,6.144,12,10,DSR,7.5
-98,11.776,23,10,DSR,7.5
-99,8.704,17,10,DSR,7.5
-100,5.632,11,10,DSR,7.5
-101,6.144,12,10,DSR,7.5
-102,9.216,18,10,DSR,7.5
-103,5.12,10,10,DSR,7.5
-104,10.24,20,10,DSR,7.5
-105,5.12,10,10,DSR,7.5
-106,7.68,15,10,DSR,7.5
-107,8.192,16,10,DSR,7.5
-108,3.072,6,10,DSR,7.5
-109,1.536,3,10,DSR,7.5
-110,7.168,14,10,DSR,7.5
-111,7.68,15,10,DSR,7.5
-112,7.168,14,10,DSR,7.5
-113,5.632,11,10,DSR,7.5
-114,4.608,9,10,DSR,7.5
-115,8.704,17,10,DSR,7.5
-116,21.504,42,10,DSR,7.5
-117,4.608,9,10,DSR,7.5
-118,18.944,37,10,DSR,7.5
-119,23.552,46,10,DSR,7.5
-120,46.592,91,10,DSR,7.5
-121,38.4,75,10,DSR,7.5
-122,11.264,22,10,DSR,7.5
-123,44.544,87,10,DSR,7.5
-124,33.28,65,10,DSR,7.5
-125,13.312,26,10,DSR,7.5
-126,18.432,36,10,DSR,7.5
-127,31.744,62,10,DSR,7.5
-128,47.616,93,10,DSR,7.5
-129,48.128,94,10,DSR,7.5
-130,28.672,56,10,DSR,7.5
-131,71.68,140,10,DSR,7.5
-132,50.688,99,10,DSR,7.5
-133,9.728,19,10,DSR,7.5
-134,34.304,67,10,DSR,7.5
-135,12.288,24,10,DSR,7.5
-136,14.848,29,10,DSR,7.5
-137,3.584,7,10,DSR,7.5
-138,10.752,21,10,DSR,7.5
-139,17.92,35,10,DSR,7.5
-140,7.68,15,10,DSR,7.5
-141,29.184,57,10,DSR,7.5
-142,5.12,10,10,DSR,7.5
-143,55.808,109,10,DSR,7.5
-144,28.672,56,10,DSR,7.5
-145,21.504,42,10,DSR,7.5
-146,20.48,40,10,DSR,7.5
-147,46.592,91,10,DSR,7.5
-148,3.072,6,10,DSR,7.5
-149,18.944,37,10,DSR,7.5
-150,48.128,94,10,DSR,7.5
-151,33.792,66,10,DSR,7.5
-152,0,0,10,DSR,7.5
-153,20.48,40,10,DSR,7.5
-154,30.208,59,10,DSR,7.5
-155,17.92,35,10,DSR,7.5
-156,3.072,6,10,DSR,7.5
-157,12.288,24,10,DSR,7.5
-158,23.04,45,10,DSR,7.5
-159,27.648,54,10,DSR,7.5
-160,16.384,32,10,DSR,7.5
-161,9.728,19,10,DSR,7.5
-162,17.92,35,10,DSR,7.5
-163,10.24,20,10,DSR,7.5
-164,20.992,41,10,DSR,7.5
-165,14.336,28,10,DSR,7.5
-166,5.632,11,10,DSR,7.5
-167,11.776,23,10,DSR,7.5
-168,25.6,50,10,DSR,7.5
-169,13.312,26,10,DSR,7.5
-170,3.072,6,10,DSR,7.5
-171,13.824,27,10,DSR,7.5
-172,11.776,23,10,DSR,7.5
-173,8.192,16,10,DSR,7.5
-174,3.072,6,10,DSR,7.5
-175,0.512,1,10,DSR,7.5
-176,3.584,7,10,DSR,7.5
-177,13.824,27,10,DSR,7.5
-178,16.896,33,10,DSR,7.5
-179,5.632,11,10,DSR,7.5
-180,16.896,33,10,DSR,7.5
-181,14.336,28,10,DSR,7.5
-182,6.656,13,10,DSR,7.5
-183,18.432,36,10,DSR,7.5
-184,24.576,48,10,DSR,7.5
-185,13.312,26,10,DSR,7.5
-186,14.848,29,10,DSR,7.5
-187,9.728,19,10,DSR,7.5
-188,6.144,12,10,DSR,7.5
-189,6.656,13,10,DSR,7.5
-190,86.528,169,10,DSR,7.5
-191,13.824,27,10,DSR,7.5
-192,37.888,74,10,DSR,7.5
-193,12.8,25,10,DSR,7.5
-194,2.048,4,10,DSR,7.5
-195,9.728,19,10,DSR,7.5
-196,17.92,35,10,DSR,7.5
-197,2.56,5,10,DSR,7.5
-198,10.24,20,10,DSR,7.5
-199,2.56,5,10,DSR,7.5
--- a/manet-routing.output.csv.olsr	Fri Jan 27 15:15:48 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-SimulationSecond,ReceiveRate,PacketsReceived,NumberOfSinks,RoutingProtocol,TransmissionPower
-0,0,0,10,OLSR,7.5
-1,0,0,10,OLSR,7.5
-2,0,0,10,OLSR,7.5
-3,0,0,10,OLSR,7.5
-4,0,0,10,OLSR,7.5
-5,0,0,10,OLSR,7.5
-6,0,0,10,OLSR,7.5
-7,0,0,10,OLSR,7.5
-8,0,0,10,OLSR,7.5
-9,0,0,10,OLSR,7.5
-10,0,0,10,OLSR,7.5
-11,0,0,10,OLSR,7.5
-12,0,0,10,OLSR,7.5
-13,0,0,10,OLSR,7.5
-14,0,0,10,OLSR,7.5
-15,0,0,10,OLSR,7.5
-16,0,0,10,OLSR,7.5
-17,0,0,10,OLSR,7.5
-18,0,0,10,OLSR,7.5
-19,0,0,10,OLSR,7.5
-20,0,0,10,OLSR,7.5
-21,0,0,10,OLSR,7.5
-22,0,0,10,OLSR,7.5
-23,0,0,10,OLSR,7.5
-24,0,0,10,OLSR,7.5
-25,0,0,10,OLSR,7.5
-26,0,0,10,OLSR,7.5
-27,0,0,10,OLSR,7.5
-28,0,0,10,OLSR,7.5
-29,0,0,10,OLSR,7.5
-30,0,0,10,OLSR,7.5
-31,0,0,10,OLSR,7.5
-32,0,0,10,OLSR,7.5
-33,0,0,10,OLSR,7.5
-34,0,0,10,OLSR,7.5
-35,0,0,10,OLSR,7.5
-36,0,0,10,OLSR,7.5
-37,0,0,10,OLSR,7.5
-38,0,0,10,OLSR,7.5
-39,0,0,10,OLSR,7.5
-40,0,0,10,OLSR,7.5
-41,0,0,10,OLSR,7.5
-42,0,0,10,OLSR,7.5
-43,0,0,10,OLSR,7.5
-44,0,0,10,OLSR,7.5
-45,0,0,10,OLSR,7.5
-46,0,0,10,OLSR,7.5
-47,0,0,10,OLSR,7.5
-48,0,0,10,OLSR,7.5
-49,0,0,10,OLSR,7.5
-50,0,0,10,OLSR,7.5
-51,5.632,11,10,OLSR,7.5
-52,16.384,32,10,OLSR,7.5
-53,18.432,36,10,OLSR,7.5
-54,20.48,40,10,OLSR,7.5
-55,18.944,37,10,OLSR,7.5
-56,16.384,32,10,OLSR,7.5
-57,18.944,37,10,OLSR,7.5
-58,18.432,36,10,OLSR,7.5
-59,17.92,35,10,OLSR,7.5
-60,18.432,36,10,OLSR,7.5
-61,18.432,36,10,OLSR,7.5
-62,17.408,34,10,OLSR,7.5
-63,17.92,35,10,OLSR,7.5
-64,17.92,35,10,OLSR,7.5
-65,18.432,36,10,OLSR,7.5
-66,18.432,36,10,OLSR,7.5
-67,17.92,35,10,OLSR,7.5
-68,17.92,35,10,OLSR,7.5
-69,14.848,29,10,OLSR,7.5
-70,18.432,36,10,OLSR,7.5
-71,15.872,31,10,OLSR,7.5
-72,14.848,29,10,OLSR,7.5
-73,14.336,28,10,OLSR,7.5
-74,12.8,25,10,OLSR,7.5
-75,18.432,36,10,OLSR,7.5
-76,18.432,36,10,OLSR,7.5
-77,17.92,35,10,OLSR,7.5
-78,18.432,36,10,OLSR,7.5
-79,18.432,36,10,OLSR,7.5
-80,17.408,34,10,OLSR,7.5
-81,16.896,33,10,OLSR,7.5
-82,20.48,40,10,OLSR,7.5
-83,17.92,35,10,OLSR,7.5
-84,22.016,43,10,OLSR,7.5
-85,16.384,32,10,OLSR,7.5
-86,16.896,33,10,OLSR,7.5
-87,17.92,35,10,OLSR,7.5
-88,19.456,38,10,OLSR,7.5
-89,17.92,35,10,OLSR,7.5
-90,18.432,36,10,OLSR,7.5
-91,17.408,34,10,OLSR,7.5
-92,15.872,31,10,OLSR,7.5
-93,16.384,32,10,OLSR,7.5
-94,16.384,32,10,OLSR,7.5
-95,16.896,33,10,OLSR,7.5
-96,17.408,34,10,OLSR,7.5
-97,18.944,37,10,OLSR,7.5
-98,16.384,32,10,OLSR,7.5
-99,19.456,38,10,OLSR,7.5
-100,20.48,40,10,OLSR,7.5
-101,20.48,40,10,OLSR,7.5
-102,20.48,40,10,OLSR,7.5
-103,19.968,39,10,OLSR,7.5
-104,19.456,38,10,OLSR,7.5
-105,17.92,35,10,OLSR,7.5
-106,17.92,35,10,OLSR,7.5
-107,18.432,36,10,OLSR,7.5
-108,18.432,36,10,OLSR,7.5
-109,18.432,36,10,OLSR,7.5
-110,19.968,39,10,OLSR,7.5
-111,18.944,37,10,OLSR,7.5
-112,18.432,36,10,OLSR,7.5
-113,18.432,36,10,OLSR,7.5
-114,18.432,36,10,OLSR,7.5
-115,20.48,40,10,OLSR,7.5
-116,20.48,40,10,OLSR,7.5
-117,20.48,40,10,OLSR,7.5
-118,20.48,40,10,OLSR,7.5
-119,20.48,40,10,OLSR,7.5
-120,18.944,37,10,OLSR,7.5
-121,17.92,35,10,OLSR,7.5
-122,18.432,36,10,OLSR,7.5
-123,19.968,39,10,OLSR,7.5
-124,20.48,40,10,OLSR,7.5
-125,19.968,39,10,OLSR,7.5
-126,16.384,32,10,OLSR,7.5
-127,16.896,33,10,OLSR,7.5
-128,16.384,32,10,OLSR,7.5
-129,17.92,35,10,OLSR,7.5
-130,18.432,36,10,OLSR,7.5
-131,17.92,35,10,OLSR,7.5
-132,17.92,35,10,OLSR,7.5
-133,20.48,40,10,OLSR,7.5
-134,20.48,40,10,OLSR,7.5
-135,18.432,36,10,OLSR,7.5
-136,17.92,35,10,OLSR,7.5
-137,16.896,33,10,OLSR,7.5
-138,16.384,32,10,OLSR,7.5
-139,17.92,35,10,OLSR,7.5
-140,18.432,36,10,OLSR,7.5
-141,17.408,34,10,OLSR,7.5
-142,16.384,32,10,OLSR,7.5
-143,16.384,32,10,OLSR,7.5
-144,16.384,32,10,OLSR,7.5
-145,18.432,36,10,OLSR,7.5
-146,19.456,38,10,OLSR,7.5
-147,18.944,37,10,OLSR,7.5
-148,18.432,36,10,OLSR,7.5
-149,19.968,39,10,OLSR,7.5
-150,19.968,39,10,OLSR,7.5
-151,18.944,37,10,OLSR,7.5
-152,20.992,41,10,OLSR,7.5
-153,18.944,37,10,OLSR,7.5
-154,18.432,36,10,OLSR,7.5
-155,17.408,34,10,OLSR,7.5
-156,20.48,40,10,OLSR,7.5
-157,18.944,37,10,OLSR,7.5
-158,17.92,35,10,OLSR,7.5
-159,18.944,37,10,OLSR,7.5
-160,18.432,36,10,OLSR,7.5
-161,19.456,38,10,OLSR,7.5
-162,19.968,39,10,OLSR,7.5
-163,19.456,38,10,OLSR,7.5
-164,19.968,39,10,OLSR,7.5
-165,20.48,40,10,OLSR,7.5
-166,20.48,40,10,OLSR,7.5
-167,19.968,39,10,OLSR,7.5
-168,20.48,40,10,OLSR,7.5
-169,18.944,37,10,OLSR,7.5
-170,19.456,38,10,OLSR,7.5
-171,18.944,37,10,OLSR,7.5
-172,21.504,42,10,OLSR,7.5
-173,20.48,40,10,OLSR,7.5
-174,19.968,39,10,OLSR,7.5
-175,18.432,36,10,OLSR,7.5
-176,18.432,36,10,OLSR,7.5
-177,19.456,38,10,OLSR,7.5
-178,20.48,40,10,OLSR,7.5
-179,17.92,35,10,OLSR,7.5
-180,18.944,37,10,OLSR,7.5
-181,19.968,39,10,OLSR,7.5
-182,20.48,40,10,OLSR,7.5
-183,18.944,37,10,OLSR,7.5
-184,18.432,36,10,OLSR,7.5
-185,19.968,39,10,OLSR,7.5
-186,20.48,40,10,OLSR,7.5
-187,20.48,40,10,OLSR,7.5
-188,20.48,40,10,OLSR,7.5
-189,18.432,36,10,OLSR,7.5
-190,18.432,36,10,OLSR,7.5
-191,17.408,34,10,OLSR,7.5
-192,19.456,38,10,OLSR,7.5
-193,17.92,35,10,OLSR,7.5
-194,18.432,36,10,OLSR,7.5
-195,19.968,39,10,OLSR,7.5
-196,20.48,40,10,OLSR,7.5
-197,19.968,39,10,OLSR,7.5
-198,20.992,41,10,OLSR,7.5
-199,20.48,40,10,OLSR,7.5
--- a/src/dsr/examples/dsr.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/examples/dsr.cc	Sun May 06 20:52:24 2012 -0700
@@ -29,11 +29,6 @@
  * US Department of Defense (DoD), and ITTC at The University of Kansas.
  */
 
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <string>
-
 #include "ns3/core-module.h"
 #include "ns3/network-module.h"
 #include "ns3/applications-module.h"
@@ -41,14 +36,13 @@
 #include "ns3/config-store-module.h"
 #include "ns3/wifi-module.h"
 #include "ns3/internet-module.h"
-#include "ns3/ipv4-list-routing-helper.h"
 #include "ns3/dsr-module.h"
 
-NS_LOG_COMPONENT_DEFINE ("DsrExample");
+using namespace ns3;
+NS_LOG_COMPONENT_DEFINE ("DsrTest");
 
-using namespace ns3;
-
-int main (int argc, char *argv[])
+int
+main (int argc, char *argv[])
 {
   //
   // Users may find it convenient to turn on explicit debugging
@@ -72,150 +66,128 @@
   LogComponentEnable ("RouteCache", LOG_LEVEL_ALL);
   LogComponentEnable ("DsrMaintainBuffer", LOG_LEVEL_ALL);
   LogComponentEnable ("RreqTable", LOG_LEVEL_ALL);
+  LogComponentEnable ("DsrErrorBuffer", LOG_LEVEL_ALL);
+  LogComponentEnable ("DsrNetworkQueue", LOG_LEVEL_ALL);
 #endif
 
-  SeedManager::SetSeed (99);
-  SeedManager::SetRun (1);
+  NS_LOG_INFO ("creating the nodes");
 
-  double totalTime = 1000.0;
-  double dataStart = 50.0;
+  // General parameters
   uint32_t nWifis = 50;
   uint32_t nSinks = 10;
-  double txp = 8.9048;
+  double TotalTime = 600.0;
+  double dataTime = 500.0;
+  double ppers = 1;
+  uint32_t packetSize = 64;
+  double dataStart = 100.0; // start sending data at 100s
+
+  //mobility parameters
   double pauseTime = 0.0;
   double nodeSpeed = 20.0;
-  uint32_t packetSize = 64;
-  std::string phyModeControl ("DsssRate11Mbps");
-  std::string phyModeData ("DsssRate11Mbps");
+  double txpDistance = 250.0;
+
   std::string rate = "0.512kbps";
-  double ppers = 1.0;
-  /*
-   * Define the DSR parameters
-   */
-  uint32_t m_maxCacheLen = 64;
-  Time m_maxCacheTime = Seconds (30);
-  Time m_nodeTraversalTime = MicroSeconds (2);
-  Time m_passiveAckTimeout = MicroSeconds (4);
-  uint32_t m_maxSendBuffLen = 64;
-  Time m_sendBufferTimeout = Seconds (30);
-  uint32_t m_maxMaintainLen = 50;
-  Time m_maxMaintainTime = Seconds (30);
-  uint32_t m_maintenanceRetries = 2;
-  std::string cacheType ("PathCache");            // PathCache
-  bool enableSubRoute = false;
+  std::string dataMode ("DsssRate11Mbps");
+  std::string phyMode ("DsssRate11Mbps");
 
   //Allow users to override the default parameters and set it to new ones from CommandLine.
   CommandLine cmd;
-  cmd.AddValue ("MaxCacheLen", "Max route cache length.", m_maxCacheLen);
-  cmd.AddValue ("RouteCacheTimeout", "Max route cache timeout.", m_maxCacheTime);
-  cmd.AddValue ("NodeTraversalTime", "The time it takes to travel to neighboring nodes.", m_nodeTraversalTime);
-  cmd.AddValue ("PassiveAckTimeout", "The time for ack to traversal the two neighboring nodes.", m_passiveAckTimeout);
-  cmd.AddValue ("MaxSendBuffLen", "Maximum number of packets that can be stored.", m_maxSendBuffLen);
-  cmd.AddValue ("MaxSendBuffTime", "Maximum time packets can be queued.", m_sendBufferTimeout);
-  cmd.AddValue ("MaxMaintLen", "Maximum number of packets that can be stored.", m_maxMaintainLen);
-  cmd.AddValue ("MaxMaintTime", "Maximum time packets can be queued.", m_maxMaintainTime);
-  cmd.AddValue ("MaintenanceRetries", "Maximum retransmission retries for maintenance data packet.", m_maintenanceRetries);
-  cmd.AddValue ("CacheType", "route cache type, Default:PathCache", cacheType);
-  cmd.AddValue ("EnableSubRoute", "whether to enable the sub route mechanism, Default:false", enableSubRoute);
+  cmd.AddValue ("nWifis", "Number of wifi nodes", nWifis);
+  cmd.AddValue ("nSinks", "Number of SINK traffic nodes", nSinks);
+  cmd.AddValue ("rate", "CBR traffic rate(in kbps), Default:8", rate);
+  cmd.AddValue ("nodeSpeed", "Node speed in RandomWayPoint model, Default:20", nodeSpeed);
+  cmd.AddValue ("packetSize", "The packet size", packetSize);
+  cmd.AddValue ("txpDistance", "Specify node's transmit range, Default:300", txpDistance);
+  cmd.AddValue ("pauseTime", "pauseTime for mobility model, Default: 0", pauseTime);
   cmd.Parse (argc, argv);
 
-  NS_LOG_INFO ("Create nodes.");
-  NodeContainer nodes;
-  nodes.Create (nWifis);
-  NetDeviceContainer devices;
+  SeedManager::SetSeed (10);
+  SeedManager::SetRun (1);
 
-  // Fix non-unicast data rate to be the same as that of unicast
-  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue (phyModeData));
+  NodeContainer adhocNodes;
+  adhocNodes.Create (nWifis);
+  NetDeviceContainer allDevices;
+
+  NS_LOG_INFO ("setting the default phy and channel parameters");
+  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue (phyMode));
   Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
-  // disable fragmentation
+  // disable fragmentation for frames below 2200 bytes
   Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
 
-  NS_LOG_INFO ("Create channels.");
+  NS_LOG_INFO ("setting the default phy and channel parameters ");
   WifiHelper wifi;
   wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+
   YansWifiChannelHelper wifiChannel;
   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
-  wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
+  wifiChannel.AddPropagationLoss("ns3::RangePropagationLossModel", "MaxRange", DoubleValue (txpDistance));
   wifiPhy.SetChannel (wifiChannel.Create ());
 
   // Add a non-QoS upper mac, and disable rate control
   NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
-  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue (phyModeData),
-                                "ControlMode", StringValue (phyModeControl));
-  wifiPhy.Set ("TxPowerStart", DoubleValue (txp));
-  wifiPhy.Set ("TxPowerEnd", DoubleValue (txp));
-  // Set it to adhoc mode
-  wifiMac.SetType ("ns3::AdhocWifiMac");
-  devices = wifi.Install (wifiPhy, wifiMac, nodes);
-
-  InternetStackHelper internet;
-  DsrMainHelper dsrMain;
-  DsrHelper dsr;
-  dsr.Set ("MaxCacheLen", UintegerValue (m_maxCacheLen));
-  dsr.Set ("RouteCacheTimeout", TimeValue (m_maxCacheTime));
-  dsr.Set ("NodeTraversalTime", TimeValue (m_nodeTraversalTime));
-  dsr.Set ("PassiveAckTimeout", TimeValue (m_passiveAckTimeout));
-  dsr.Set ("MaxSendBuffLen", UintegerValue (m_maxSendBuffLen));
-  dsr.Set ("MaxSendBuffTime", TimeValue (m_sendBufferTimeout));
-  dsr.Set ("MaxMaintLen", UintegerValue (m_maxMaintainLen));
-  dsr.Set ("MaxMaintTime", TimeValue (m_maxMaintainTime));
-  dsr.Set ("MaintenanceRetries", UintegerValue (m_maintenanceRetries));
-  dsr.Set ("EnableSubRoute", BooleanValue (false));
-  dsr.Set ("CacheType", StringValue (cacheType));
-  dsr.Set ("SendBuffInterval", TimeValue (Seconds (50)));
-  internet.Install (nodes);
-  dsrMain.Install (dsr, nodes);
-
-  NS_LOG_INFO ("assigning ip address");
-  Ipv4AddressHelper addressAdhoc;
-  addressAdhoc.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer adhocInterfaces;
-  adhocInterfaces = addressAdhoc.Assign (devices);
-
-  MobilityHelper mobility;
+  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue (dataMode), "ControlMode",
+      StringValue (phyMode));
 
-  ObjectFactory pos;
-  pos.SetTypeId ("ns3::RandomRectanglePositionAllocator");
-  pos.Set ("X", RandomVariableValue (UniformVariable (0.0, 300.0)));
-  pos.Set ("Y", RandomVariableValue (UniformVariable (0.0, 1500.0)));
-  Ptr<PositionAllocator> positionAlloc = pos.Create ()->GetObject<PositionAllocator> ();
-  mobility.SetPositionAllocator (positionAlloc);
-
-  mobility.SetMobilityModel ("ns3::RandomWaypointMobilityModel",
-                             "Speed", RandomVariableValue (ConstantVariable (nodeSpeed)),
-                             "Pause", RandomVariableValue (ConstantVariable (pauseTime)),
-                             "PositionAllocator", PointerValue (positionAlloc));
-  mobility.Install (nodes);
-
-  // many to many application
-  uint16_t port = 9;
-  double randomStartTime = (1 / ppers) / nSinks;     //distributed btw 1s evenly as we are sending 1pkt/s
+  wifiMac.SetType ("ns3::AdhocWifiMac");
+  allDevices = wifi.Install (wifiPhy, wifiMac, adhocNodes);
 
-  for (uint32_t i = 0; i < nSinks; i++)
-    {
-      PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
-      ApplicationContainer apps_sink = sink.Install (nodes.Get (i));
-      apps_sink.Start (Seconds (0.0));
-      apps_sink.Stop (Seconds (totalTime));
-
-      OnOffHelper onoff1 ("ns3::UdpSocketFactory", Address (InetSocketAddress (adhocInterfaces.GetAddress (i), port)));
-      onoff1.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
-      onoff1.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
-      onoff1.SetAttribute ("PacketSize", UintegerValue (packetSize));
-      onoff1.SetAttribute ("DataRate", DataRateValue (DataRate (rate)));
-
-      ApplicationContainer apps1 = onoff1.Install (nodes.Get (i + nSinks));
-      apps1.Start (Seconds (dataStart + i * randomStartTime));
-      apps1.Stop (Seconds (totalTime));
-    }
+  NS_LOG_INFO ("Configure Tracing.");
 
   AsciiTraceHelper ascii;
   Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream ("dsrtest.tr");
   wifiPhy.EnableAsciiAll (stream);
 
+  MobilityHelper adhocMobility;
+  ObjectFactory pos;
+  pos.SetTypeId ("ns3::RandomRectanglePositionAllocator");
+  pos.Set ("X", RandomVariableValue (UniformVariable (0.0, 300.0)));
+  pos.Set ("Y", RandomVariableValue (UniformVariable (0.0, 1500.0)));
+  Ptr<PositionAllocator> taPositionAlloc = pos.Create ()->GetObject<PositionAllocator> ();
+
+  adhocMobility.SetMobilityModel ("ns3::RandomWaypointMobilityModel",
+      "Speed", RandomVariableValue (UniformVariable (0.0, nodeSpeed)),
+      "Pause", RandomVariableValue (ConstantVariable (pauseTime)),
+      "PositionAllocator", PointerValue (taPositionAlloc)
+      );
+  adhocMobility.Install (adhocNodes);
+
+  InternetStackHelper internet;
+  DsrMainHelper dsrMain;
+  DsrHelper dsr;
+  internet.Install (adhocNodes);
+  dsrMain.Install (dsr, adhocNodes);
+
+  NS_LOG_INFO ("assigning ip address");
+  Ipv4AddressHelper address;
+  address.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer allInterfaces;
+  allInterfaces = address.Assign (allDevices);
+
+  uint16_t port = 9;
+  double randomStartTime = (1/ppers) / nSinks; //distributed btw 1s evenly as we are sending 4pkt/s
+
+  for (uint32_t i = 0; i < nSinks; ++i)
+  {
+    PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
+    ApplicationContainer apps_sink = sink.Install (adhocNodes.Get (i));
+    apps_sink.Start (Seconds (0.0));
+    apps_sink.Stop (Seconds (TotalTime));
+
+    OnOffHelper onoff1 ("ns3::UdpSocketFactory", Address (InetSocketAddress (allInterfaces.GetAddress (i), port)));
+    onoff1.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+    onoff1.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+    onoff1.SetAttribute ("PacketSize", UintegerValue (packetSize));
+    onoff1.SetAttribute ("DataRate", DataRateValue (DataRate (rate)));
+
+    ApplicationContainer apps1 = onoff1.Install (adhocNodes.Get (i + nWifis - nSinks));
+    apps1.Start (Seconds (dataStart + i*randomStartTime));
+    apps1.Stop (Seconds (dataTime + i*randomStartTime));
+  }
+
   NS_LOG_INFO ("Run Simulation.");
-  Simulator::Stop (Seconds (totalTime));
+  Simulator::Stop (Seconds (TotalTime));
   Simulator::Run ();
   Simulator::Destroy ();
 }
+
--- a/src/dsr/examples/wscript	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/examples/wscript	Sun May 06 20:52:24 2012 -0700
@@ -1,6 +1,6 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 def build(bld):
-    obj = bld.create_ns3_program('dsr', ['core', 'network', 'internet', 'wifi', 'dsr'])
+    obj = bld.create_ns3_program('dsr', ['core', 'simulator', 'node', 'internet-stack'])
     obj.source = 'dsr.cc'
 
--- a/src/dsr/helper/dsr-main-helper.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/helper/dsr-main-helper.cc	Sun May 06 20:52:24 2012 -0700
@@ -90,13 +90,13 @@
 {
   NS_LOG_FUNCTION (node);
   Ptr<ns3::dsr::DsrRouting> dsr = m_dsrHelper->Create (node);
-  Ptr<ns3::dsr::RouteCache> routeCache = CreateObject<ns3::dsr::RouteCache> ();
-  Ptr<ns3::dsr::RreqTable> rreqTable = CreateObject<ns3::dsr::RreqTable> ();
-  dsr->SetRouteCache (routeCache);
-  dsr->SetRequestTable (rreqTable);
+//  Ptr<ns3::dsr::RouteCache> routeCache = CreateObject<ns3::dsr::RouteCache> ();
+//  Ptr<ns3::dsr::RreqTable> rreqTable = CreateObject<ns3::dsr::RreqTable> ();
+//  dsr->SetRouteCache (routeCache);
+//  dsr->SetRequestTable (rreqTable);
   dsr->SetNode (node);
-  node->AggregateObject (routeCache);
-  node->AggregateObject (rreqTable);
+//  node->AggregateObject (routeCache);
+//  node->AggregateObject (rreqTable);
 }
 
 void
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dsr/model/dsr-errorbuff.cc	Sun May 06 20:52:24 2012 -0700
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Yufei Cheng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Yufei Cheng   <yfcheng@ittc.ku.edu>
+ *
+ * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
+ * ResiliNets Research Group  http://wiki.ittc.ku.edu/resilinets
+ * Information and Telecommunication Technology Center (ITTC)
+ * and Department of Electrical Engineering and Computer Science
+ * The University of Kansas Lawrence, KS USA.
+ *
+ * Work supported in part by NSF FIND (Future Internet Design) Program
+ * under grant CNS-0626918 (Postmodern Internet Architecture),
+ * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
+ * US Department of Defense (DoD), and ITTC at The University of Kansas.
+ */
+
+#include "dsr-errorbuff.h"
+#include <algorithm>
+#include <functional>
+#include "ns3/ipv4-route.h"
+#include "ns3/socket.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("DsrErrorBuffer");
+
+namespace ns3 {
+namespace dsr {
+
+uint32_t
+ErrorBuffer::GetSize ()
+{
+  Purge ();
+  return m_errorBuffer.size ();
+}
+
+bool
+ErrorBuffer::Enqueue (ErrorBuffEntry & entry)
+{
+  Purge ();
+  for (std::vector<ErrorBuffEntry>::const_iterator i = m_errorBuffer.begin (); i
+       != m_errorBuffer.end (); ++i)
+    {
+      NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid () << " source " << i->GetSource () << " " << entry.GetSource ()
+                   << " next hop " << i->GetNextHop () << " " << entry.GetNextHop () << " dst " << i->GetDestination () << " " << entry.GetDestination ());
+
+      if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ()) && (i->GetSource () == entry.GetSource ()) && (i->GetNextHop () == entry.GetSource ())
+          && (i->GetDestination () == entry.GetDestination ()))
+        {
+          return false;
+        }
+    }
+
+  entry.SetExpireTime (m_errorBufferTimeout);     // Initialize the send buffer timeout
+  /*
+   * Drop the most aged packet when buffer reaches to max
+   */
+  if (m_errorBuffer.size () >= m_maxLen)
+    {
+      Drop (m_errorBuffer.front (), "Drop the most aged packet");         // Drop the most aged packet
+      m_errorBuffer.erase (m_errorBuffer.begin ());
+    }
+  // enqueue the entry
+  m_errorBuffer.push_back (entry);
+  return true;
+}
+
+void
+ErrorBuffer::DropPacketForErrLink (Ipv4Address source, Ipv4Address nextHop)
+{
+  NS_LOG_FUNCTION (this << source << nextHop);
+  Purge ();
+  std::vector<Ipv4Address> list;
+  list.push_back (source);
+  list.push_back (nextHop);
+  const std::vector<Ipv4Address> link = list;
+  /*
+   * Drop the packet with the error link source----------nextHop
+   */
+  for (std::vector<ErrorBuffEntry>::iterator i = m_errorBuffer.begin (); i
+       != m_errorBuffer.end (); ++i)
+    {
+      if (LinkEqual (*i, link))
+        {
+          DropLink (*i, "DropPacketForErrLink");
+        }
+    }
+  m_errorBuffer.erase (std::remove_if (m_errorBuffer.begin (), m_errorBuffer.end (),
+                                      std::bind2nd (std::ptr_fun (ErrorBuffer::LinkEqual), link)), m_errorBuffer.end ());
+}
+
+bool
+ErrorBuffer::Dequeue (Ipv4Address dst, ErrorBuffEntry & entry)
+{
+  Purge ();
+  /*
+   * Dequeue the entry with destination address dst
+   */
+  for (std::vector<ErrorBuffEntry>::iterator i = m_errorBuffer.begin (); i != m_errorBuffer.end (); ++i)
+    {
+      if (i->GetDestination () == dst)
+        {
+          entry = *i;
+          m_errorBuffer.erase (i);
+          NS_LOG_DEBUG ("Packet size while dequeuing " << entry.GetPacket ()->GetSize ());
+          return true;
+        }
+    }
+  return false;
+}
+
+bool
+ErrorBuffer::Find (Ipv4Address dst)
+{
+  /*
+   * Make sure if the send buffer contains entry with certain dst
+   */
+  for (std::vector<ErrorBuffEntry>::const_iterator i = m_errorBuffer.begin (); i
+       != m_errorBuffer.end (); ++i)
+    {
+      if (i->GetDestination () == dst)
+        {
+          NS_LOG_DEBUG ("Found the packet");
+          return true;
+        }
+    }
+  return false;
+}
+
+struct IsExpired
+{
+  bool
+  operator() (ErrorBuffEntry const & e) const
+  {
+    // NS_LOG_DEBUG("Expire time for packet in req queue: "<<e.GetExpireTime ());
+    return (e.GetExpireTime () < Seconds (0));
+  }
+};
+
+void
+ErrorBuffer::Purge ()
+{
+  /*
+   * Purge the buffer to eliminate expired entries
+   */
+  NS_LOG_DEBUG ("The error buffer size " << m_errorBuffer.size ());
+  IsExpired pred;
+  for (std::vector<ErrorBuffEntry>::iterator i = m_errorBuffer.begin (); i
+       != m_errorBuffer.end (); ++i)
+    {
+      if (pred (*i))
+        {
+          NS_LOG_DEBUG ("Dropping Queue Packets");
+          Drop (*i, "Drop out-dated packet ");
+        }
+    }
+  m_errorBuffer.erase (std::remove_if (m_errorBuffer.begin (), m_errorBuffer.end (), pred),
+                      m_errorBuffer.end ());
+}
+
+void
+ErrorBuffer::Drop (ErrorBuffEntry en, std::string reason)
+{
+  NS_LOG_LOGIC (reason << en.GetPacket ()->GetUid () << " " << en.GetDestination ());
+//  en.GetErrorCallback () (en.GetPacket (), en.GetDestination (),
+//     Socket::ERROR_NOROUTETOHOST);
+  return;
+}
+
+void
+ErrorBuffer::DropLink (ErrorBuffEntry en, std::string reason)
+{
+  NS_LOG_LOGIC (reason << en.GetPacket ()->GetUid () << " " << en.GetSource () << " " << en.GetNextHop ());
+//  en.GetErrorCallback () (en.GetPacket (), en.GetDestination (),
+//     Socket::ERROR_NOROUTETOHOST);
+  return;
+}
+}  // namespace dsr
+}  // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dsr/model/dsr-errorbuff.h	Sun May 06 20:52:24 2012 -0700
@@ -0,0 +1,203 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Yufei Cheng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Yufei Cheng   <yfcheng@ittc.ku.edu>
+ *
+ * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
+ * ResiliNets Research Group  http://wiki.ittc.ku.edu/resilinets
+ * Information and Telecommunication Technology Center (ITTC)
+ * and Department of Electrical Engineering and Computer Science
+ * The University of Kansas Lawrence, KS USA.
+ *
+ * Work supported in part by NSF FIND (Future Internet Design) Program
+ * under grant CNS-0626918 (Postmodern Internet Architecture),
+ * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
+ * US Department of Defense (DoD), and ITTC at The University of Kansas.
+ */
+
+#ifndef DSR_ERRORBUFF_H
+#define DSR_ERRORBUFF_H
+
+#include <vector>
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+namespace dsr {
+/**
+ * \ingroup dsr
+ * \brief DSR Error Buffer Entry
+ */
+class ErrorBuffEntry
+{
+public:
+  // / c-tor
+  ErrorBuffEntry (Ptr<const Packet> pa = 0, Ipv4Address d = Ipv4Address (), Ipv4Address s = Ipv4Address (),
+                  Ipv4Address n = Ipv4Address (), Time exp = Simulator::Now (), uint8_t p = 0)
+    : m_packet (pa),
+      m_dst (d),
+      m_source (s),
+      m_nextHop (n),
+      m_expire (exp + Simulator::Now ()),
+      m_protocol (p)
+  {
+  }
+  /**
+   * Compare send buffer entries
+   * \return true if equal
+   */
+  bool operator== (ErrorBuffEntry const & o) const
+  {
+    return ((m_packet == o.m_packet) && (m_source == o.m_source) && (m_nextHop == o.m_nextHop) && (m_dst == o.m_dst) && (m_expire == o.m_expire));
+  }
+  // /\name Fields
+  // \{
+  Ptr<const Packet> GetPacket () const
+  {
+    return m_packet;
+  }
+  void SetPacket (Ptr<const Packet> p)
+  {
+    m_packet = p;
+  }
+  Ipv4Address GetDestination () const
+  {
+    return m_dst;
+  }
+  void SetDestination (Ipv4Address d)
+  {
+    m_dst = d;
+  }
+  Ipv4Address GetSource () const
+  {
+    return m_source;
+  }
+  void SetSource (Ipv4Address s)
+  {
+    m_source = s;
+  }
+  Ipv4Address GetNextHop () const
+  {
+    return m_nextHop;
+  }
+  void SetNextHop (Ipv4Address n)
+  {
+    m_nextHop = n;
+  }
+  void SetExpireTime (Time exp)
+  {
+    m_expire = exp + Simulator::Now ();
+  }
+  Time GetExpireTime () const
+  {
+    return m_expire - Simulator::Now ();
+  }
+  void SetProtocol (uint8_t p)
+  {
+    m_protocol = p;
+  }
+  uint8_t GetProtocol () const
+  {
+    return m_protocol;
+  }
+  // \}
+private:
+  // / Data packet
+  Ptr<const Packet> m_packet;
+  // / Destination address
+  Ipv4Address m_dst;
+  // / Source address
+  Ipv4Address m_source;
+  // / Nexthop address
+  Ipv4Address m_nextHop;
+  // / Expire time for queue entry
+  Time m_expire;
+  // / The protocol number
+  uint8_t m_protocol;
+};
+
+/**
+ * \ingroup dsr
+ * \brief DSR error buffer
+ */
+/************************************************************************************************************************/
+class ErrorBuffer
+{
+public:
+  // / Default c-tor
+  ErrorBuffer ()
+  {
+  }
+  // / Push entry in queue, if there is no entry with the same packet and destination address in queue.
+  bool Enqueue (ErrorBuffEntry & entry);
+  // / Return first found (the earliest) entry for given destination
+  bool Dequeue (Ipv4Address dst, ErrorBuffEntry & entry);
+  // / Remove all packets with the error link
+  void DropPacketForErrLink (Ipv4Address source, Ipv4Address nextHop);
+  // / Finds whether a packet with destination dst exists in the queue
+  bool Find (Ipv4Address dst);
+  // / Number of entries
+  uint32_t GetSize ();
+  // /\name Fields
+  // \{
+  uint32_t GetMaxQueueLen () const
+  {
+    return m_maxLen;
+  }
+  void SetMaxQueueLen (uint32_t len)
+  {
+    m_maxLen = len;
+  }
+  Time GetErrorBufferTimeout () const
+  {
+    return m_errorBufferTimeout;
+  }
+  void SetErrorBufferTimeout (Time t)
+  {
+    m_errorBufferTimeout = t;
+  }
+  // \}
+
+  std::vector<ErrorBuffEntry> & GetBuffer ()
+  {
+    return m_errorBuffer;
+  }
+
+private:
+  // / The send buffer to cache unsent packet
+  std::vector<ErrorBuffEntry> m_errorBuffer;
+  // / Remove all expired entries
+  void Purge ();
+  // / Notify that packet is dropped from queue by timeout
+  void Drop (ErrorBuffEntry en, std::string reason);
+  // / Notify that packet is dropped from queue by timeout
+  void DropLink (ErrorBuffEntry en, std::string reason);
+  // / The maximum number of packets that we allow a routing protocol to buffer.
+  uint32_t m_maxLen;
+  // / The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
+  Time m_errorBufferTimeout;
+  // / Check if the send buffer entry is the same or not
+  static bool LinkEqual (ErrorBuffEntry en, const std::vector<Ipv4Address> link)
+  {
+    return ((en.GetSource () == link[0]) && (en.GetNextHop () == link[1]));
+  }
+};
+/*******************************************************************************************************************************/
+} // namespace dsr
+} // namespace ns3
+
+#endif /* DSR_ERRORBUFF_H */
--- a/src/dsr/model/dsr-fs-header.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-fs-header.h	Sun May 06 20:52:24 2012 -0700
@@ -76,13 +76,6 @@
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   \endverbatim
 */
-
-enum DsrMessageType
-{
-  DSR_CONTROL_PACKET = 1,
-  DSR_DATA_PACKET = 2
-};
-
 class DsrFsHeader : public Header
 {
 public:
--- a/src/dsr/model/dsr-maintain-buff.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-maintain-buff.cc	Sun May 06 20:52:24 2012 -0700
@@ -56,8 +56,8 @@
        != m_maintainBuffer.end (); ++i)
     {
       NS_LOG_INFO ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our add " << i->GetOurAdd () << " " << entry.GetOurAdd ()
-                              << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                              << " ackId " << i->GetAckId () << " " << entry.GetAckId () << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft ()
+                   << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+                   << " ackId " << i->GetAckId () << " " << entry.GetAckId () << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft ()
                    );
 
       if ((i->GetNextHop () == entry.GetNextHop ()) && (i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetSrc () == entry.GetSrc ())
@@ -75,6 +75,7 @@
       m_maintainBuffer.erase (m_maintainBuffer.begin ());        // Drop the most aged packet
     }
   m_maintainBuffer.push_back (entry);
+  NS_LOG_DEBUG ("The maintain size " << m_maintainBuffer.size());
   return true;
 }
 
@@ -105,6 +106,34 @@
   return false;
 }
 
+//bool
+//MaintainBuffer::FindMaintainEntry (Ptr<Packet> packet, Ipv4Address ourAdd, Ipv4Address src, Ipv4Address nextHop, Ipv4Address dst, NetworkKey networkKey)
+//{
+//  // TODO if necessary this one can strip the packet header and have more information
+//  for (std::vector<MaintainBuffEntry>::const_iterator i = m_maintainBuffer.begin (); i
+//       != m_maintainBuffer.end (); ++i)
+//    {
+//      NS_LOG_INFO ("packet " << i->GetPacket () << " " << packet << " nexthop " << i->GetNextHop () << " " << nextHop
+//                   << " our add " << i->GetOurAdd () << " " << ourAdd << " src " << i->GetSrc ()
+//                   << " " << src << " dst " << i->GetDst () << " " << dst
+//                   );
+//
+//      if ((i->GetPacket () == packet) && (i->GetNextHop () == nextHop) && (i->GetOurAdd () == ourAdd) && (i->GetSrc () == src)
+//          && (i->GetDst () == dst))
+//        {
+//          NS_LOG_DEBUG ("Same maintenance entry found");
+//          networkKey.m_ackId = newEntry.GetAckId ();
+//          networkKey.m_ourAdd = newEntry.GetOurAdd ();
+//          networkKey.m_nextHop = newEntry.GetNextHop ();
+//          networkKey.m_source = newEntry.GetSrc ();
+//          networkKey.m_destination = newEntry.GetDst ();
+//          // TODO may need a different network key to have
+//          return true;
+//        }
+//    }
+//  return false;
+//}
+
 bool
 MaintainBuffer::Find (Ipv4Address nextHop)
 {
@@ -128,8 +157,30 @@
     {
 
       NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
-                               << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                               << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
+                 << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+                 << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
+
+      if ((i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetNextHop () == entry.GetNextHop ())
+          && (i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
+          && (i->GetAckId () == entry.GetAckId ()) && (i->GetSegsLeft () == entry.GetSegsLeft ()))
+        {
+          m_maintainBuffer.erase (i);   // Erase the same maintain buffer entry for the received packet
+          return true;
+        }
+    }
+  return false;
+}
+
+bool
+MaintainBuffer::NetworkEqual (MaintainBuffEntry & entry)
+{
+  for (std::vector<MaintainBuffEntry>::iterator i = m_maintainBuffer.begin (); i
+       != m_maintainBuffer.end (); ++i)
+    {
+
+      NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
+                 << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+                 << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
 
       if ((i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetNextHop () == entry.GetNextHop ())
           && (i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
@@ -145,18 +196,17 @@
 bool
 MaintainBuffer::PromiscEqual (MaintainBuffEntry & entry)
 {
+  NS_LOG_DEBUG ("The maintenance buffer size " << m_maintainBuffer.size());
   for (std::vector<MaintainBuffEntry>::iterator i = m_maintainBuffer.begin (); i
        != m_maintainBuffer.end (); ++i)
     {
+      NS_LOG_DEBUG ("src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+                 << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft () << " ackId " << (uint32_t)i->GetAckId () << " "
+                 << (uint32_t)entry.GetAckId ()
+          );
 
-      NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
-                               << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                               << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft ()
-                    );
-
-      if ((i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetNextHop () == entry.GetNextHop ())
-          && (i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
-          && (i->GetSegsLeft () == entry.GetSegsLeft ())
+      if ((i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
+          && (i->GetSegsLeft () == entry.GetSegsLeft ()) && (i->GetAckId () == entry.GetAckId ())
           )
         {
           m_maintainBuffer.erase (i);   // Erase the same maintain buffer entry for the promisc received packet
--- a/src/dsr/model/dsr-maintain-buff.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-maintain-buff.h	Sun May 06 20:52:24 2012 -0700
@@ -38,37 +38,54 @@
 #include "ns3/ipv4-header.h"
 #include "dsr-option-header.h"
 
-
 namespace ns3 {
 namespace dsr {
 /*
  * The maintenance buffer is responsible for maintaining packet next hop delivery
  * The data packet is saved in maintenance buffer whenever the data packet is sent out of send buffer
  */
-
 /*
  * The packet timer key for controlling data packet retransmission
  */
-struct PacketKey
+struct NetworkKey
 {
   uint16_t m_ackId;
   Ipv4Address m_ourAdd;
   Ipv4Address m_nextHop;
   Ipv4Address m_source;
   Ipv4Address m_destination;
+
+  /**
+   * Compare maintain Buffer entries
+   * \return true if equal
+   */
+  bool operator < (NetworkKey const & o) const
+  {
+    return ((m_ackId < o.m_ackId) && (m_ourAdd < o.m_ourAdd) && (m_nextHop < o.m_nextHop) && (m_source < o.m_source)
+            && (m_destination < o.m_destination)
+            );
+  }
+};
+
+struct PassiveKey
+{
+  uint16_t m_ackId;
+  Ipv4Address m_source;
+  Ipv4Address m_destination;
   uint8_t m_segsLeft;
 
   /**
    * Compare maintain Buffer entries
    * \return true if equal
    */
-  bool operator < (PacketKey const & o) const
+  bool operator < (PassiveKey const & o) const
   {
-    return ((m_ackId < o.m_ackId) && (m_ourAdd < o.m_ourAdd) && (m_nextHop < o.m_nextHop) && (m_source < o.m_source)
+    return ((m_ackId < o.m_ackId) && (m_source < o.m_source)
             && (m_destination < o.m_destination) && (m_segsLeft < o.m_segsLeft)
             );
   }
 };
+
 /**
  * \ingroup dsr
  * \brief DSR Maintain Buffer Entry
@@ -87,7 +104,6 @@
       m_dst (dst),
       m_ackId (ackId),
       m_segsLeft (segs),
-      m_isPassive (true),
       m_expire (exp + Simulator::Now ())
   {
   }
@@ -150,14 +166,6 @@
   {
     m_segsLeft = segs;
   }
-  bool GetPassive () const
-  {
-    return m_isPassive;
-  }
-  void SetPassive (bool pa)
-  {
-    m_isPassive = pa;
-  }
   void SetExpireTime (Time exp)
   {
     m_expire = exp + Simulator::Now ();
@@ -184,10 +192,6 @@
   uint16_t m_id;
   // / The segments left field
   uint8_t m_segsLeft;
-  // / The fragment offset of ipv4 header
-  uint16_t m_fragment;
-  // / if the ack metric is passive ack or not
-  bool m_isPassive;
   // / Expire time for queue entry
   Time m_expire;
 };
@@ -209,6 +213,7 @@
   bool Dequeue (Ipv4Address dst, MaintainBuffEntry & entry);
   // / Remove all packets with destination IP address dst
   void DropPacketWithNextHop (Ipv4Address nextHop);
+  bool FindMaintainEntry (Ptr<Packet> packet, Ipv4Address ourAdd, Ipv4Address src, Ipv4Address nextHop, Ipv4Address dst, NetworkKey networkKey);
   // / Finds whether a packet with destination dst exists in the queue
   bool Find (Ipv4Address nextHop);
   // / Number of entries
@@ -231,8 +236,9 @@
   {
     m_maintainBufferTimeout = t;
   }
+  bool AllEqual (MaintainBuffEntry & entry);
   // / Verify if the maintain buffer entry is the same in every field for network ack
-  bool AllEqual (MaintainBuffEntry & entry);
+  bool NetworkEqual (MaintainBuffEntry & entry);
   // / Verify if the maintain buffer entry is the same in every field for promiscuous ack
   bool PromiscEqual (MaintainBuffEntry & entry);
   // \}
@@ -240,6 +246,7 @@
 private:
   // / The vector of maintain buffer entries
   std::vector<MaintainBuffEntry> m_maintainBuffer;
+  std::vector<NetworkKey> m_allNetworkKey;
   // / Remove all expired entries
   void Purge ();
   // / The maximum number of packets that we allow a routing protocol to buffer.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dsr/model/dsr-network-queue.cc	Sun May 06 20:52:24 2012 -0700
@@ -0,0 +1,175 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Yufei Cheng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Yufei Cheng   <yfcheng@ittc.ku.edu>
+ *
+ * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
+ * ResiliNets Research Group  http://wiki.ittc.ku.edu/resilinets
+ * Information and Telecommunication Technology Center (ITTC)
+ * and Department of Electrical Engineering and Computer Science
+ * The University of Kansas Lawrence, KS USA.
+ *
+ * Work supported in part by NSF FIND (Future Internet Design) Program
+ * under grant CNS-0626918 (Postmodern Internet Architecture),
+ * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
+ * US Department of Defense (DoD), and ITTC at The University of Kansas.
+ */
+
+#include "dsr-network-queue.h"
+#include "ns3/test.h"
+#include <algorithm>
+#include <functional>
+#include <map>
+#include "ns3/log.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/socket.h"
+
+NS_LOG_COMPONENT_DEFINE ("DsrNetworkQueue");
+
+namespace ns3 {
+namespace dsr {
+
+NS_OBJECT_ENSURE_REGISTERED (DsrNetworkQueue);
+
+TypeId
+DsrNetworkQueue::GetTypeID (void)
+{
+  static TypeId tid = TypeId ("ns3::dsr::DsrNetworkQueue")
+      .SetParent<Object> ()
+      .AddConstructor<DsrNetworkQueue>  ()
+      ;
+  return tid;
+}
+
+DsrNetworkQueue::DsrNetworkQueue (uint32_t maxLen, Time maxDelay) :
+    m_size(0), m_maxSize (maxLen), m_maxDelay (maxDelay)
+{
+  NS_LOG_FUNCTION(this );
+}
+
+DsrNetworkQueue::DsrNetworkQueue () : m_size(0)
+{
+  NS_LOG_FUNCTION(this );
+}
+
+DsrNetworkQueue::~DsrNetworkQueue ()
+{
+  NS_LOG_FUNCTION(this );
+  Flush();
+}
+
+void
+DsrNetworkQueue::SetMaxNetworkSize (uint32_t maxSize)
+{
+  m_maxSize = maxSize;
+}
+
+void
+DsrNetworkQueue::SetMaxNetworkDelay (Time delay)
+{
+  m_maxDelay = delay;
+}
+
+uint32_t
+DsrNetworkQueue::GetMaxNetworkSize (void) const
+{
+  return m_maxSize;
+}
+
+Time
+DsrNetworkQueue::GetMaxNetworkDelay (void) const
+{
+  return m_maxDelay;
+}
+
+bool
+DsrNetworkQueue::Enqueue (DsrNetworkQueueEntry & entry)
+{
+  NS_LOG_FUNCTION (this << m_size << m_maxSize);
+  if (m_size >= m_maxSize)
+  {
+    return false;
+  }
+  Time now = Simulator::Now ();
+  entry.SetInsertedTimeStamp (now);
+  m_dsrNetworkQueue.push_back (entry);
+  m_size++;
+  NS_LOG_DEBUG ("The network queue size for now " << m_size);
+  return true;
+}
+
+bool
+DsrNetworkQueue::Dequeue (DsrNetworkQueueEntry & entry)
+{
+  NS_LOG_FUNCTION (this);
+  Cleanup ();
+  std::vector<DsrNetworkQueueEntry>::iterator i = m_dsrNetworkQueue.begin ();
+  if (i == m_dsrNetworkQueue.end ())
+  {
+    // no elements in array
+    NS_LOG_DEBUG ("Does not find the queued packet in the network queue");
+    return false;
+  }
+  entry = *i;
+  m_dsrNetworkQueue.erase (i);
+  m_size--;
+  return true;
+}
+
+void
+DsrNetworkQueue::Cleanup (void)
+{
+  NS_LOG_FUNCTION(this);
+  if (m_dsrNetworkQueue.empty ())
+    {
+      return;
+    }
+
+  Time now = Simulator::Now ();
+  uint32_t n = 0;
+  for (std::vector<DsrNetworkQueueEntry>::iterator i = m_dsrNetworkQueue.begin (); i != m_dsrNetworkQueue.end ();)
+    {
+      if (i->GetInsertedTimeStamp() + m_maxDelay > now)
+        {
+          i++;
+        }
+      else
+        {
+          i = m_dsrNetworkQueue.erase (i);
+          n++;
+        }
+    }
+  m_size -= n;
+}
+
+uint32_t
+DsrNetworkQueue::GetSize ()
+{
+  NS_LOG_FUNCTION(this);
+  return m_size;
+}
+
+void
+DsrNetworkQueue::Flush (void)
+{
+  NS_LOG_FUNCTION(this);
+  m_dsrNetworkQueue.erase (m_dsrNetworkQueue.begin (), m_dsrNetworkQueue.end ());
+  m_size = 0;
+}
+
+}  // namespace dsr
+}  // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dsr/model/dsr-network-queue.h	Sun May 06 20:52:24 2012 -0700
@@ -0,0 +1,136 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Yufei Cheng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Yufei Cheng   <yfcheng@ittc.ku.edu>
+ *
+ * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
+ * ResiliNets Research Group  http://wiki.ittc.ku.edu/resilinets
+ * Information and Telecommunication Technology Center (ITTC)
+ * and Department of Electrical Engineering and Computer Science
+ * The University of Kansas Lawrence, KS USA.
+ *
+ * Work supported in part by NSF FIND (Future Internet Design) Program
+ * under grant CNS-0626918 (Postmodern Internet Architecture),
+ * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
+ * US Department of Defense (DoD), and ITTC at The University of Kansas.
+ */
+
+#ifndef DSR_NETWORK_QUEUE_H
+#define DSR_NETWORK_QUEUE_H
+
+#include <vector>
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/simulator.h"
+#include "ns3/ipv4-header.h"
+#include "dsr-option-header.h"
+
+namespace ns3 {
+namespace dsr {
+
+enum DsrMessageType
+{
+  DSR_CONTROL_PACKET = 1,
+  DSR_DATA_PACKET = 2
+};
+/**
+ * \ingroup dsr
+ * \brief DSR Network Queue Entry
+ */
+class DsrNetworkQueueEntry
+{
+public:
+  /// c-tor
+  DsrNetworkQueueEntry (Ptr<const Packet> pa = 0, Ipv4Address s = Ipv4Address (), Ipv4Address n = Ipv4Address (),
+                        Time exp = Simulator::Now (), Ptr<Ipv4Route> r = 0)
+    : m_packet (pa),
+      m_srcAddr (s),
+      m_nextHopAddr (n),
+      tstamp (exp),
+      m_ipv4Route (r)
+  {
+  }
+  /**
+   * Compare send buffer entries
+   * \return true if equal
+   */
+  bool operator== (DsrNetworkQueueEntry const & o) const
+  {
+    return ((m_packet == o.m_packet) && (m_srcAddr == o.m_srcAddr) && (m_nextHopAddr == o.m_nextHopAddr) &&
+            (tstamp == o.tstamp) && (m_ipv4Route == o.m_ipv4Route));
+  }
+
+  ///\name Fields
+  //\{
+  Ptr<const Packet> GetPacket () const { return m_packet; }
+  void SetPacket (Ptr<const Packet> p) { m_packet = p; }
+  Ptr<Ipv4Route> GetIpv4Route() const { return m_ipv4Route; }
+  void SetIpv4Route (Ptr<Ipv4Route> route) { m_ipv4Route = route; }
+  Ipv4Address GetSourceAddress() const { return m_srcAddr; }
+  void SetSourceAddress (Ipv4Address addr) { m_srcAddr = addr; }
+  Ipv4Address GetNextHopAddress() const { return m_nextHopAddr; }
+  void SetNextHopAddress (Ipv4Address addr) { m_nextHopAddr = addr; }
+  Time GetInsertedTimeStamp (void) const {return tstamp;}
+  void SetInsertedTimeStamp (Time time) {tstamp = time;}
+  //\}
+private:
+  /// Data packet
+  Ptr<const Packet> m_packet;
+  Ipv4Address m_srcAddr;
+  Ipv4Address m_nextHopAddr;
+  Time tstamp;
+  /// Ipv4Route
+  Ptr<Ipv4Route> m_ipv4Route;
+};
+
+class DsrNetworkQueue : public Object
+{
+public:
+  static TypeId GetTypeID (void);
+  /// Default c-tor
+  DsrNetworkQueue ();
+  DsrNetworkQueue (uint32_t maxLen, Time maxDelay);
+  ~DsrNetworkQueue ();
+  /// Push entry in queue, if there is no entry with the same packet and destination address in queue.
+  bool Enqueue (DsrNetworkQueueEntry & entry);
+  /// Return first found (the earliest) entry for given destination
+  bool Dequeue (DsrNetworkQueueEntry & entry);
+  /// Number of entries
+  uint32_t GetSize ();
+
+  void SetMaxNetworkSize (uint32_t maxSize);
+  void SetMaxNetworkDelay (Time delay);
+  uint32_t GetMaxNetworkSize (void) const;
+  Time GetMaxNetworkDelay (void) const;
+  void Flush (void);
+
+  std::vector<DsrNetworkQueueEntry> & GetQueue ()
+  {
+    return m_dsrNetworkQueue;
+  }
+
+private:
+  void Cleanup (void);
+  std::vector<DsrNetworkQueueEntry> m_dsrNetworkQueue;
+  uint32_t m_size;
+  uint32_t m_maxSize;
+  Time m_maxDelay;
+};
+
+} // namespace dsr
+} // namespace ns3
+
+#endif /* DSR_NETWORK_QUEUE_H */
--- a/src/dsr/model/dsr-option-header.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-option-header.cc	Sun May 06 20:52:24 2012 -0700
@@ -38,7 +38,6 @@
 #include "ns3/packet.h"
 #include "ns3/enum.h"
 
-
 namespace ns3 {
 namespace dsr {
 NS_LOG_COMPONENT_DEFINE ("DsrOptionHeader");
@@ -681,7 +680,7 @@
     m_errorLength (4)
 {
   SetType (3);
-  SetLength (14);
+  SetLength (18);
 }
 
 DsrOptionRerrHeader::~DsrOptionRerrHeader ()
@@ -738,7 +737,7 @@
 
 uint32_t DsrOptionRerrHeader::GetSerializedSize () const
 {
-  return 16;
+  return 20;
 }
 
 void DsrOptionRerrHeader::Serialize (Buffer::Iterator start) const
@@ -799,10 +798,10 @@
 
 DsrOptionRerrUnreachHeader::DsrOptionRerrUnreachHeader ()
   :    m_reserved (0),
-    m_salvage (0)
+       m_salvage (0)
 {
   SetType (3);
-  SetLength (14);
+  SetLength (18);
   SetErrorType (1);
 }
 
@@ -850,6 +849,16 @@
   return m_unreachNode;
 }
 
+void DsrOptionRerrUnreachHeader::SetOriginalDst (Ipv4Address originalDst)
+{
+  m_originalDst = originalDst;
+}
+
+Ipv4Address DsrOptionRerrUnreachHeader::GetOriginalDst () const
+{
+  return m_originalDst;
+}
+
 void DsrOptionRerrUnreachHeader::Print (std::ostream &os) const
 {
   os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength ()
@@ -860,7 +869,7 @@
 
 uint32_t DsrOptionRerrUnreachHeader::GetSerializedSize () const
 {
-  return 16;
+  return 20;
 }
 
 void DsrOptionRerrUnreachHeader::Serialize (Buffer::Iterator start) const
@@ -874,7 +883,7 @@
   WriteTo (i, m_errorSrcAddress);
   WriteTo (i, m_errorDstAddress);
   WriteTo (i, m_unreachNode);
-
+  WriteTo (i, m_originalDst);
 }
 
 uint32_t DsrOptionRerrUnreachHeader::Deserialize (Buffer::Iterator start)
@@ -888,6 +897,7 @@
   ReadFrom (i, m_errorSrcAddress);
   ReadFrom (i, m_errorDstAddress);
   ReadFrom (i, m_unreachNode);
+  ReadFrom (i, m_originalDst);
 
   return GetSerializedSize ();
 }
--- a/src/dsr/model/dsr-option-header.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-option-header.h	Sun May 06 20:52:24 2012 -0700
@@ -957,6 +957,16 @@
    */
   Ipv4Address GetUnreachNode () const;
   /**
+   * \brief Set the unreachable node ip address
+   * \param The unreachable ip address
+   */
+  void SetOriginalDst (Ipv4Address originalDst);
+  /**
+   * \brief Get the unreachable node ip address
+   * \return The unreachable ip address
+   */
+  Ipv4Address GetOriginalDst () const;
+  /**
    * \brief Print some informations about the packet.
    * \param os output stream
    * \return info about this packet
@@ -1014,6 +1024,10 @@
    */
   Ipv4Address    m_unreachNode;
   /**
+   * \brief The original destination address
+   */
+  Ipv4Address    m_originalDst;
+  /**
    * \brief The specific error type
    */
   uint16_t       m_typeSpecific;
--- a/src/dsr/model/dsr-options.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-options.cc	Sun May 06 20:52:24 2012 -0700
@@ -106,6 +106,7 @@
 
 bool DsrOptions::ContainAddressAfter (Ipv4Address ipv4Address, Ipv4Address destAddress, std::vector<Ipv4Address> &nodeList)
 {
+  NS_LOG_FUNCTION (this << ipv4Address << destAddress);
   std::vector<Ipv4Address>::iterator it = find (nodeList.begin (), nodeList.end (), destAddress);
 
   for (std::vector<Ipv4Address>::iterator i = it; i != nodeList.end (); ++i)
@@ -121,6 +122,7 @@
 std::vector<Ipv4Address>
 DsrOptions::CutRoute (Ipv4Address ipv4Address, std::vector<Ipv4Address> &nodeList)
 {
+  NS_LOG_FUNCTION (this << ipv4Address);
   std::vector<Ipv4Address>::iterator it = find (nodeList.begin (), nodeList.end (), ipv4Address);
   std::vector<Ipv4Address> cutRoute;
   for (std::vector<Ipv4Address>::iterator i = it; i != nodeList.end (); ++i)
@@ -142,6 +144,7 @@
 
 bool DsrOptions::ReverseRoutes (std::vector<Ipv4Address> & vec)
 {
+  NS_LOG_FUNCTION (this);
   std::vector<Ipv4Address> vec2 (vec);
   vec.clear ();    // To ensure vec is empty before start
   for (std::vector<Ipv4Address>::reverse_iterator ri = vec2.rbegin (); ri
@@ -159,7 +162,9 @@
 
 Ipv4Address DsrOptions::SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this << ipv4Address);
   Ipv4Address nextHop;
+  NS_LOG_DEBUG ("the vector size " << vec.size ());
   if (vec.size () == 2)
     {
       NS_LOG_DEBUG ("The two nodes are neighbors");
@@ -173,7 +178,7 @@
           NS_LOG_DEBUG ("We have reached to the final destination " << ipv4Address << " " << vec.back ());
           return ipv4Address;
         }
-      for (std::vector<Ipv4Address>::iterator i = vec.begin (); i != vec.end (); ++i)
+      for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
         {
           if (ipv4Address == (*i))
             {
@@ -189,6 +194,7 @@
 
 Ipv4Address DsrOptions::ReverseSearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this << ipv4Address);
   Ipv4Address nextHop;
   if (vec.size () == 2)
     {
@@ -214,6 +220,7 @@
 
 void DsrOptions::PrintVector (std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this);
   /*
    * Check elements in a route vector
    */
@@ -233,6 +240,11 @@
 
 bool DsrOptions::IfDuplicates (std::vector<Ipv4Address>& vec, std::vector<Ipv4Address>& vec2)
 {
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("The first vector ");
+  PrintVector (vec);
+  NS_LOG_DEBUG ("The second vector ");
+  PrintVector (vec2);
   for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
     {
       for (std::vector<Ipv4Address>::const_iterator j = vec2.begin (); j != vec2.end (); ++j)
@@ -252,6 +264,7 @@
 
 bool DsrOptions::CheckDuplicates (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this << ipv4Address);
   for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
     {
       if ((*i) == ipv4Address)
@@ -268,6 +281,7 @@
 
 void DsrOptions::RemoveDuplicates (std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this);
   //Remove duplicate ip address from the route if any, should not happen with normal behavior nodes
   std::vector<Ipv4Address> vec2 (vec); // declare vec2 as a copy of the vec
   PrintVector (vec2); // Print all the ip address in the route
@@ -312,6 +326,7 @@
 uint32_t
 DsrOptions::GetIDfromIP (Ipv4Address address)
 {
+  NS_LOG_FUNCTION (this << address);
   int32_t nNodes = NodeList::GetNNodes ();
   for (int32_t i = 0; i < nNodes; ++i)
     {
@@ -327,6 +342,7 @@
 
 Ptr<Node> DsrOptions::GetNodeWithAddress (Ipv4Address ipv4Address)
 {
+  NS_LOG_FUNCTION (this << ipv4Address);
   int32_t nNodes = NodeList::GetNNodes ();
   for (int32_t i = 0; i < nNodes; ++i)
     {
@@ -372,7 +388,6 @@
 uint8_t DsrOptionPad1::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
-
   Ptr<Packet> p = packet->Copy ();
   DsrOptionPad1Header pad1Header;
   p->RemoveHeader (pad1Header);
@@ -414,7 +429,6 @@
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
 
   Ptr<Packet> p = packet->Copy ();
-
   DsrOptionPadnHeader padnHeader;
   p->RemoveHeader (padnHeader);
 
@@ -459,14 +473,24 @@
 uint8_t DsrOptionRreq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
+  // Fields from IP header
+  Ipv4Address srcAddress = ipv4Header.GetSource ();
+  Ipv4Address destAddress = ipv4Header.GetDestination ();
+  /*
+   * \ when the ip source address is equal to the address of our own, this is request packet originated
+   * \ by the node itself, discard it
+   */
+  if (srcAddress == ipv4Address)
+    {
+      NS_LOG_DEBUG ("Discard the packet");
+      m_dropTrace (packet); // call the drop trace to show in the tracing
+      return 0;
+    }
   /*
    * Get the node associated with the ipv4 address and get several objects from the node and leave for further use
    */
   Ptr<Node> node = GetNodeWithAddress (ipv4Address);
   Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-  Ptr<dsr::RouteCache> m_routeCache = node->GetObject<dsr::RouteCache> ();
-  Ptr<dsr::RreqTable>  m_rreqTable = node->GetObject<dsr::RreqTable> ();
-  ActiveRouteTimeout = m_routeCache->GetCacheTimeout ();
 
   // Set the isError boolean value as false
   bool isError = false;
@@ -478,7 +502,7 @@
   uint8_t buf[2];
   p->CopyData (buf, sizeof(buf));
   uint8_t numberAddress = (buf[1] - 6) / 4;
-
+  NS_LOG_DEBUG ("The number of Ip addresses " << (uint32_t)numberAddress);
   if (numberAddress >= 255)
     {
       NS_LOG_DEBUG ("Discard the packet, malformed header since two many ip addresses in route");
@@ -486,57 +510,38 @@
       return 0;
     }
 
-  NS_LOG_DEBUG ("The number of Ip addresses " << (uint32_t)numberAddress);
   /*
    * Create the dsr rreq header
    */
   DsrOptionRreqHeader rreq;
-
-  // Fields from IP header
-  Ipv4Address srcAddress = ipv4Header.GetSource ();
-  Ipv4Address destAddress = ipv4Header.GetDestination ();
   /*
    * Set the number of addresses with the value from peek data and remove the rreq header
    */
   rreq.SetNumberAddress (numberAddress);
-
-  /*
-   * \ when the ip source address is equal to the address of our own, this is request packet originated
-   * \ by the node itself, discard it
-   */
-  if (srcAddress == ipv4Address)
+  // Remove the route request header
+  p->RemoveHeader (rreq);
+  // Verify the option length
+  uint8_t length = rreq.GetLength ();
+  if (length % 2 != 0)
     {
-      NS_LOG_DEBUG ("Discard the packet");
-      m_dropTrace (packet); // call the drop trace to show in the tracing
+      NS_LOG_LOGIC ("Malformed header. Drop!");
+      m_dropTrace (packet); // call drop trace
       return 0;
     }
-
-  p->RemoveHeader (rreq);
-  Ptr<Packet> errP = p->Copy ();
-
   // The target address is where we want to send the data packets
   Ipv4Address targetAddress = rreq.GetTarget ();
-  uint16_t id = rreq.GetId ();
   // Get the node list and source address from the route request header
-  std::vector<Ipv4Address> nodeList = rreq.GetNodesAddresses ();
+  std::vector<Ipv4Address> mainVector = rreq.GetNodesAddresses ();
+  std::vector<Ipv4Address> nodeList (mainVector);
   PrintVector (nodeList);
-
-  // Get the TTL value
-  uint8_t ttl = ipv4Header.GetTtl ();
-  NS_LOG_DEBUG ("The TTL " << (uint32_t) ttl);
   /*
-   *  Node checks to determine whether it has received a RREQ with the same Originator IP Address and RREQ ID.
-   *  If such a RREQ has been received, the node silently discards the newly received RREQ.
+   * Construct the dsr routing header for future use
    */
-  if (ttl)
-    {
-      // if the TTL value is not 0, save the route request entry
-      if (m_rreqTable->FindSrc (source, targetAddress, id))
-        {
-          NS_LOG_DEBUG ("Received the same route request recently, not processing it further");
-          return 0;
-        }
-    }
+  DsrRoutingHeader dsrRoutingHeader;
+  dsrRoutingHeader.SetNextHeader (protocol);
+  dsrRoutingHeader.SetMessageType (1);
+  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
+  dsrRoutingHeader.SetDestId (255);
 
   if (CheckDuplicates (ipv4Address, nodeList))
     {
@@ -549,15 +554,6 @@
     }
   else
     {
-      // Verify the option length
-      uint8_t length = rreq.GetLength ();
-      if (length % 2 != 0)
-        {
-          NS_LOG_LOGIC ("Malformed header. Drop!");
-          m_dropTrace (packet); // call drop trace
-          return 0;
-        }
-
       // A node ignores all RREQs received from any node in its blacklist
       RouteCacheEntry toPrev;
       /*
@@ -571,6 +567,7 @@
       /*
        * The target address equal to our own ip address
        */
+      NS_LOG_DEBUG ("The target address over here " << targetAddress << " and the ip address " << ipv4Address << " and the source address " << mainVector[0]);
       if (targetAddress == ipv4Address)
         {
           Ipv4Address nextHop; // Declare the next hop address to use
@@ -584,9 +581,10 @@
             }
           else
             {
-              nodeList.push_back (ipv4Address);    // push back our own address
+              std::vector<Ipv4Address> changeRoute (nodeList);
+              changeRoute.push_back (ipv4Address);    // push back our own address
               m_finalRoute.clear ();              // get a clear route vector
-              for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != nodeList.end (); ++i)
+              for (std::vector<Ipv4Address>::iterator i = changeRoute.begin (); i != changeRoute.end (); ++i)
                 {
                   m_finalRoute.push_back (*i);  // Get the full route from source to destination
                 }
@@ -599,7 +597,7 @@
           NS_LOG_DEBUG ("The nextHop address " << nextHop);
           Ipv4Address replyDst = m_finalRoute.front ();
           /*
-           * This part add dsr header to the packet and send reply
+           * This part add dsr header to the packet and send route reply packet
            */
           DsrRoutingHeader dsrRoutingHeader;
           dsrRoutingHeader.SetNextHeader (protocol);
@@ -626,15 +624,15 @@
               bool addRoute = false;
               if (numberAddress > 0)
                 {
-                  RouteCacheEntry toSource (/*IP_VECTOR=*/ m_finalRoute, /*dst=*/
-                                                           dst, /*expire time=*/ ActiveRouteTimeout);
-                  if (m_routeCache->IsLinkCache ())
+                  RouteCacheEntry toSource (/*IP_VECTOR=*/m_finalRoute, /*dst=*/
+                                  dst, /*expire time=*/ActiveRouteTimeout);
+                  if (dsr->IsLinkCache ())
                     {
-                      addRoute = m_routeCache->AddRoute_Link (m_finalRoute, ipv4Address);
+                      addRoute = dsr->AddRoute_Link (m_finalRoute, ipv4Address);
                     }
                   else
                     {
-                      addRoute = m_routeCache->AddRoute (toSource);
+                      addRoute = dsr->AddRoute (toSource);
                     }
                 }
               else
@@ -645,24 +643,19 @@
 
               if (addRoute)
                 {
-                  NS_LOG_DEBUG ("The route is failed to add in cache");
-                  return 0;
-                }
-              else
-                {
                   /*
                    * Found a route to the dst, construct the source route option header
                    */
                   DsrOptionSRHeader sourceRoute;
                   NS_LOG_DEBUG ("The route length " << m_finalRoute.size ());
                   sourceRoute.SetNodesAddress (m_finalRoute);
-                  if (m_routeCache->IsLinkCache ())
+                  if (dsr->IsLinkCache ())
                     {
-                      m_routeCache->UseExtends (m_finalRoute);
+                      dsr->UseExtends (m_finalRoute);
                     }
                   sourceRoute.SetSegmentsLeft ((m_finalRoute.size () - 2));
-                  uint8_t salvage = 0;
-                  sourceRoute.SetSalvage (salvage);
+                  // The salvage value here is 0
+                  sourceRoute.SetSalvage (0);
                   Ipv4Address nextHop = SearchNextHop (ipv4Address, m_finalRoute); // Get the next hop address
                   NS_LOG_DEBUG ("The nextHop address " << nextHop);
 
@@ -673,11 +666,16 @@
                     }
                   SetRoute (nextHop, ipv4Address);
                   /*
-                   * Schedule the packet retry
+                   * Send the data packet from the send buffer
                    */
-                  dsr->SendPacket (sourceRoute, nextHop, protocol);
-                  // Cancel the route request timer for destination
-                  dsr->CancelRreqTimer (dst);
+                  dsr->SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+                  // Cancel the route request timer for destination after sending the data packet
+                  dsr->CancelRreqTimer (dst, true);
+                }
+              else
+                {
+                  NS_LOG_DEBUG ("The route is failed to add in cache");
+                  return 0;
                 }
             }
           else
@@ -694,24 +692,21 @@
        *      need to delay based on a random value from d = H * (h - 1 + r), which can avoid possible route
        *      reply storm.
        */
-      else if (m_routeCache->LookupRoute (targetAddress, toPrev))
+      else if (dsr->LookupRoute (targetAddress, toPrev))
         {
-
           RouteCacheEntry::IP_VECTOR ip = toPrev.GetVector (); // The route from our own route cache to dst
-
           PrintVector (ip);
-          std::vector<Ipv4Address> nodeList = rreq.GetNodesAddresses (); // Route from rreq header
           std::vector<Ipv4Address> saveRoute (nodeList);
           PrintVector (saveRoute);
           // Verify if the two vector contains duplicates, if so, do not use
           // the route found and forward the route request
-          if (!(IfDuplicates (ip, nodeList)))
+          if (!(IfDuplicates (ip, saveRoute)))
             {
-              m_finalRoute.clear (); // Clear the final route vector
+              m_finalRoute.clear ();            // Clear the final route vector
               /**
                * push back the intermediate node address from the source to this node
                */
-              for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != nodeList.end (); ++i)
+              for (std::vector<Ipv4Address>::iterator i = saveRoute.begin (); i != saveRoute.end (); ++i)
                 {
                   m_finalRoute.push_back (*i);
                 }
@@ -730,43 +725,42 @@
 
               if (ReverseRoutes (reverseRoute))
                 {
-                  Ipv4Address dst = reverseRoute.back ();
                   saveRoute.push_back (ipv4Address);
                   ReverseRoutes (saveRoute);
+                  Ipv4Address dst = saveRoute.back ();
+                  NS_LOG_DEBUG ("This is the route save in route cache");
                   PrintVector (saveRoute);
+
                   RouteCacheEntry toSource (/*IP_VECTOR=*/ saveRoute, /*dst=*/ dst, /*expire time=*/ ActiveRouteTimeout);
                   NS_ASSERT (saveRoute.front () == ipv4Address);
                   // Add the route entry in the route cache
-                  if (m_routeCache->IsLinkCache ())
+                  if (dsr->IsLinkCache ())
                     {
-                      addRoute = m_routeCache->AddRoute_Link (saveRoute, ipv4Address);
+                      addRoute = dsr->AddRoute_Link (saveRoute, ipv4Address);
                     }
                   else
                     {
-                      addRoute = m_routeCache->AddRoute (toSource);
+                      addRoute = dsr->AddRoute (toSource);
                     }
+
                   if (addRoute)
                     {
-                      NS_LOG_DEBUG ("The route is failed to add in cache");
-                      return 0;
-                    }
-                  else
-                    {
                       NS_LOG_DEBUG ("We have added the route and search send buffer for packet with destination " << dst);
                       /*
                        * Found a route the dst, construct the source route option header
                        */
                       DsrOptionSRHeader sourceRoute;
-                      NS_LOG_DEBUG ("The route length " << reverseRoute.size ());
-                      sourceRoute.SetNodesAddress (reverseRoute);
-                      if (m_routeCache->IsLinkCache ())
+                      PrintVector (saveRoute);
+
+                      sourceRoute.SetNodesAddress (saveRoute);
+                      if (dsr->IsLinkCache ())
                         {
-                          m_routeCache->UseExtends (reverseRoute);
+                          dsr->UseExtends (saveRoute);
                         }
                       sourceRoute.SetSegmentsLeft ((saveRoute.size () - 2));
                       uint8_t salvage = 0;
                       sourceRoute.SetSalvage (salvage);
-                      Ipv4Address nextHop = SearchNextHop (ipv4Address, reverseRoute); // Get the next hop address
+                      Ipv4Address nextHop = SearchNextHop (ipv4Address, saveRoute); // Get the next hop address
                       NS_LOG_DEBUG ("The nextHop address " << nextHop);
 
                       if (nextHop == "0.0.0.0")
@@ -778,36 +772,44 @@
                       /*
                        * Schedule the packet retry
                        */
-                      dsr->SendPacket (sourceRoute, nextHop, protocol);
+                      dsr->SendPacketFromBuffer (sourceRoute, nextHop, protocol);
                       // Cancel the route request timer for destination
-                      dsr->CancelRreqTimer (dst);
+                      dsr->CancelRreqTimer (dst, true);
+                    }
+                  else
+                    {
+                      NS_LOG_DEBUG ("The route is failed to add in cache");
+                      return 0;
                     }
                 }
               else
                 {
                   NS_LOG_DEBUG ("Unable to reverse the route");
+                  return 0;
                 }
 
               /*
                * Need to first pin down the next hop address before removing duplicates
                */
               Ipv4Address nextHop = ReverseSearchNextHop (ipv4Address, m_finalRoute);
+              NS_LOG_DEBUG ("The nextHop address " << nextHop);
               /*
                * First remove the duplicate ip address to automatically shorten the route, and then reversely
                * search the next hop address
                */
-              PrintVector (m_finalRoute);
               // Set the route
               SetRoute (nextHop, ipv4Address);
 
               uint16_t hops = m_finalRoute.size ();
               DsrOptionRrepHeader rrep;
               rrep.SetNodesAddress (m_finalRoute);     // Set the node addresses in the route reply header
-              NS_LOG_DEBUG ("The nextHop address " << nextHop);
               // Get the real source of the reply
               Ipv4Address realSource = m_finalRoute.back ();
+              Ipv4Address realDst = m_finalRoute.front ();
+              PrintVector (m_finalRoute);
+              NS_LOG_DEBUG ("This is the full route from " << realSource << " to " << realDst);
               /*
-               * This part add dsr header to the packet and send reply
+               * This part add dsr header to the packet and send route reply packet
                */
               DsrRoutingHeader dsrRoutingHeader;
               dsrRoutingHeader.SetNextHeader (protocol);
@@ -823,79 +825,86 @@
               dsr->ScheduleCachedReply (newPacket, ipv4Address, nextHop, m_ipv4Route, hops);
               isPromisc = false;
             }
+          else
+            {
+              NS_LOG_DEBUG ("There is duplicate ip addresses in the two route parts");
+            }
+          return rreq.GetSerializedSize ();
         }
       /*
        * (iii) no route in any type has been found
        */
       else
         {
-          std::vector<Ipv4Address> nodeList = rreq.GetNodesAddresses (); // route from rreq header
-          PrintVector (nodeList);
-          /*
-           * Otherwise, forward the route request packet
-           */
-          PrintVector (nodeList);
-          nodeList.push_back (ipv4Address);
-          PrintVector (nodeList);
-          NS_ASSERT (nodeList.front () == source);
-          rreq.SetNodesAddress (nodeList);
+          mainVector.push_back (ipv4Address);
+          NS_ASSERT (mainVector.front () == source);
+          NS_LOG_DEBUG ("Print out the main vector");
+          PrintVector (mainVector);
+          rreq.SetNodesAddress (mainVector);
+
+          Ptr<Packet> errP = p->Copy ();
+          if (errP->GetSize ())
+            {
+              NS_LOG_DEBUG ("Error header included");
+              DsrOptionRerrUnreachHeader rerr;
+              p->RemoveHeader (rerr);
+              Ipv4Address errorSrc = rerr.GetErrorSrc ();
+              Ipv4Address unreachNode = rerr.GetUnreachNode ();
+              Ipv4Address errorDst = rerr.GetErrorDst ();
+
+              if ((errorSrc == srcAddress) && (unreachNode == ipv4Address))
+                {
+                  NS_LOG_DEBUG ("The error link back to work again");
+                  uint16_t length = rreq.GetLength ();
+                  NS_LOG_DEBUG ("The RREQ header length " <<  length);
+                  dsrRoutingHeader.AddDsrOption (rreq);
+                  dsrRoutingHeader.SetPayloadLength (length + 2);
+                }
+              else
+                {
+                  isError = true;
+                  dsr->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, ipv4Address);
+
+                  DsrOptionRerrUnreachHeader newUnreach;
+                  newUnreach.SetErrorType (1);
+                  newUnreach.SetErrorSrc (errorSrc);
+                  newUnreach.SetUnreachNode (unreachNode);
+                  newUnreach.SetErrorDst (errorDst);
+                  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
+                  uint16_t length = rreq.GetLength () + newUnreach.GetLength ();
+                  NS_LOG_DEBUG ("The RREQ and newUnreach header length " <<  length);
+                  dsrRoutingHeader.SetPayloadLength (length + 4);
+                  dsrRoutingHeader.AddDsrOption (rreq);
+                  dsrRoutingHeader.AddDsrOption (newUnreach);
+                }
+            }
+          else
+            {
+              uint16_t length = rreq.GetLength ();
+              NS_LOG_DEBUG ("The RREQ header length " <<  length);
+              dsrRoutingHeader.AddDsrOption (rreq);
+              dsrRoutingHeader.SetPayloadLength (length + 2);
+            }
+          // Get the TTL value
+          uint8_t ttl = ipv4Header.GetTtl ();
           /*
           * Decrease the TTL value in the packet tag by one, this tag will go to ip layer 3 send function
           * and drop packet when TTL value equals to 0
           */
+          NS_LOG_DEBUG ("The ttl value here " << (uint32_t)ttl);
           if (ttl)
             {
               Ptr<Packet> interP = Create<Packet> ();
               SocketIpTtlTag tag;
               tag.SetTtl (ttl - 1);
               interP->AddPacketTag (tag);
-              /*
-               * Construct the route request header to forward the route requests
-               */
-              DsrRoutingHeader dsrRoutingHeader;
-              dsrRoutingHeader.SetNextHeader (protocol);
-              dsrRoutingHeader.SetMessageType (1);
-              dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
-              dsrRoutingHeader.SetDestId (255);
-              dsrRoutingHeader.AddDsrOption (rreq);
-
-              // if the errP packet is not 0, then there is an error header after it
-              if (errP->GetSize ())
-                {
-                  NS_LOG_DEBUG ("Error header included");
-                  DsrOptionRerrUnreachHeader rerr;
-                  p->RemoveHeader (rerr);
-                  Ipv4Address errorSrc = rerr.GetErrorSrc ();
-                  Ipv4Address unreachNode = rerr.GetUnreachNode ();
-                  isError = true;
-                  m_routeCache->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, ipv4Address);
-
-                  DsrOptionRerrUnreachHeader newUnreach;
-                  newUnreach.SetErrorType (1);
-                  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
-                  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
-                  newUnreach.SetErrorDst (rerr.GetErrorDst ());
-                  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
-                  dsrRoutingHeader.AddDsrOption (newUnreach);
-                  uint16_t length = rreq.GetLength () + newUnreach.GetLength ();
-                  NS_LOG_DEBUG ("The RREQ and newUnreach header length " <<  length);
-                  dsrRoutingHeader.SetPayloadLength (length + 4);
-                  interP->AddHeader (dsrRoutingHeader);
-                }
-              else
-                {
-                  uint16_t length = rreq.GetLength ();
-                  NS_LOG_DEBUG ("The RREQ header length " <<  length);
-                  dsrRoutingHeader.SetPayloadLength (length + 2);
-                  interP->AddHeader (dsrRoutingHeader);
-                }
-
+              interP->AddHeader (dsrRoutingHeader);
               dsr->ScheduleInterRequest (interP);
               isPromisc = false;
             }
+          return rreq.GetSerializedSize ();
         }
     }
-
   return rreq.GetSerializedSize ();
 }
 
@@ -949,14 +958,11 @@
 
   Ptr<Node> node = GetNodeWithAddress (ipv4Address);
   Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-  Ptr<dsr::RouteCache> m_routeCache = node->GetObject<dsr::RouteCache> ();
-  Ptr<dsr::RreqTable>  m_rreqTable = node->GetObject<dsr::RreqTable> ();
-  ActiveRouteTimeout = m_routeCache->GetCacheTimeout ();
 
   NS_LOG_DEBUG ("The next header value " << (uint32_t)protocol);
 
   std::vector<Ipv4Address> nodeList = rrep.GetNodesAddress ();
-  /*
+  /**
    * Get the destination address, which is the last element in the nodeList
    */
   Ipv4Address targetAddress = nodeList.front ();
@@ -970,11 +976,11 @@
           NS_LOG_DEBUG ("The route we have contains 0 entries");
           return 0;
         }
-      /*
+      /**
        * Get the destination address for the data packet, which is the last element in the nodeList
        */
       Ipv4Address dst = nodeList.back ();
-      /*
+      /**
        * Add the newly found route to the route cache
        * The route looks like:
        * \\ "srcAddress" + "intermediate node address" + "targetAddress"
@@ -982,31 +988,26 @@
       RouteCacheEntry toDestination (/*IP_VECTOR=*/ nodeList, /*dst=*/ dst, /*expire time=*/ ActiveRouteTimeout);
       NS_ASSERT (nodeList.front () == ipv4Address);
       bool addRoute = false;
-      if (m_routeCache->IsLinkCache ())
+      if(dsr->IsLinkCache())
         {
-          m_routeCache->AddRoute_Link (nodeList, ipv4Address);
+          addRoute = dsr->AddRoute_Link (nodeList, ipv4Address);
         }
       else
         {
-          m_routeCache->AddRoute (toDestination);
+          addRoute = dsr->AddRoute (toDestination);
         }
+
       if (addRoute)
         {
-          NS_LOG_DEBUG ("Failed to add the route");
-          return 0;
-        }
-      else
-        {
           NS_LOG_DEBUG ("We have added the route and search send buffer for packet with destination " << dst);
-          /*
+          /**
            * Found a route the dst, construct the source route option header
            */
           DsrOptionSRHeader sourceRoute;
           NS_LOG_DEBUG ("The route length " << nodeList.size ());
           sourceRoute.SetNodesAddress (nodeList);
           sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));
-          uint8_t salvage = 0;
-          sourceRoute.SetSalvage (salvage);
+          sourceRoute.SetSalvage (0);
           Ipv4Address nextHop = SearchNextHop (ipv4Address, nodeList); // Get the next hop address
           NS_LOG_DEBUG ("The nextHop address " << nextHop);
           if (nextHop == "0.0.0.0")
@@ -1016,12 +1017,17 @@
             }
           PrintVector (nodeList);
           SetRoute (nextHop, ipv4Address);
-          /*
+          // Cancel the route request timer for destination
+          dsr->CancelRreqTimer (dst, true);
+          /**
            * Schedule the packet retry
            */
-          dsr->SendPacket (sourceRoute, nextHop, protocol);
-          // Cancel the route request timer for destination
-          dsr->CancelRreqTimer (dst);
+          dsr->SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+        }
+      else
+        {
+          NS_LOG_DEBUG ("Failed to add the route");
+          return 0;
         }
     }
   else
@@ -1049,17 +1055,17 @@
           RouteCacheEntry toDestination (/*IP_VECTOR=*/ cutRoute, /*dst=*/ dst, /*expire time=*/ ActiveRouteTimeout);
           NS_ASSERT (cutRoute.front () == ipv4Address);
           bool addRoute = false;
-          if (m_routeCache->IsLinkCache ())
+          if(dsr->IsLinkCache())
             {
-              m_routeCache->AddRoute_Link (nodeList, ipv4Address);
+              addRoute = dsr->AddRoute_Link (nodeList, ipv4Address);
             }
           else
             {
-              m_routeCache->AddRoute (toDestination);
+              addRoute = dsr->AddRoute (toDestination);
             }
           if (addRoute)
             {
-              dsr->CancelRreqTimer (dst);
+              dsr->CancelRreqTimer (dst, true);
             }
           else
             {
@@ -1148,14 +1154,8 @@
 
   // The route size saved in the source route
   std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
-
   uint8_t segsLeft = sourceRoute.GetSegmentsLeft ();
   uint8_t salvage = sourceRoute.GetSalvage ();
-
-  // Here we remove the ack packet to the previous hop
-  DsrOptionAckReqHeader ackReq;
-  p->RemoveHeader (ackReq);
-  uint16_t ackId = ackReq.GetAckId ();
   /*
    * Get the node from IP address and get the DSR extension object
    */
@@ -1180,12 +1180,11 @@
        */
       Ptr<Node> node = GetNodeWithAddress (ipv4Address);
       Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-
-      bool findSame = dsr->FindSamePackets (packet, ipv4Header, source, destination, segsLeft);
+      bool findSame = dsr->FindSamePackets (packet, source, destination, segsLeft);
 
       if (findSame)
         {
-          NS_LOG_DEBUG ("Received one passive acknowledgment for data packet");
+          NS_LOG_DEBUG ("Received one passive acknowledgment for a successfully delivered packet");
         }
       if (ContainAddressAfter (ipv4Address, destAddress, nodeList))
         {
@@ -1205,18 +1204,38 @@
       uint8_t length = sourceRoute.GetLength ();
       uint8_t nextAddressIndex;
       Ipv4Address nextAddress;
-      /*
-       * Send back acknowledgment packet to the earlier hop
-       */
-      m_ipv4Route = SetRoute (srcAddress, ipv4Address);
-      NS_LOG_DEBUG ("Send back ACK to the earlier hop " << srcAddress << " from us " << ipv4Address);
-      dsr->SendAck (ackId, srcAddress, source, destination, protocol, m_ipv4Route);
+
+      // Get the option type value
+      uint32_t size = p->GetSize ();
+      uint8_t *data = new uint8_t[size];
+      p->CopyData (data, size);
+      uint8_t optionType = 0;
+      optionType = *(data);
+      NS_LOG_DEBUG ("The packet size over here " << p->GetSize());
+
+      NS_LOG_DEBUG ("The option type over here " << (uint32_t)optionType);
+      if (optionType == 160)
+        {
+          NS_LOG_DEBUG ("Here we remove the ack request header and add ack header to the packet");
+          // Here we remove the ack packet to the previous hop
+          DsrOptionAckReqHeader ackReq;
+          p->RemoveHeader (ackReq);
+          uint16_t ackId = ackReq.GetAckId ();
+          NS_LOG_DEBUG ("The type value " << (uint32_t)ackReq.GetType ());
+          /*
+           * Send back acknowledgment packet to the earlier hop
+           */
+          m_ipv4Route = SetRoute (srcAddress, ipv4Address);
+          NS_LOG_DEBUG ("Send back ACK to the earlier hop " << srcAddress << " from us " << ipv4Address);
+          dsr->SendAck (ackId, srcAddress, source, destination, protocol, m_ipv4Route);
+        }
       /*
        * After send back ACK, check if the segments left value has turned to 0 or not, if yes, update the route entry
        * and return header length
        */
       if (segsLeft == 0)
         {
+          NS_LOG_DEBUG ("This is the final destination");
           isPromisc = false;
           return sourceRoute.GetSerializedSize ();
         }
@@ -1274,6 +1293,7 @@
         }
       // Set the route and forward the data packet
       SetRoute (nextAddress, ipv4Address);
+      NS_LOG_DEBUG ("dsr packet size " << dsrP->GetSize());
       dsr->ForwardPacket (dsrP, newSourceRoute, ipv4Header, realSource, nextAddress, targetAddress, protocol, m_ipv4Route);
     }
   return sourceRoute.GetSerializedSize ();
@@ -1314,7 +1334,6 @@
 uint8_t DsrOptionRerr::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
-
   Ptr<Packet> p = packet->Copy ();
   uint32_t size = p->GetSize ();
   uint8_t *data = new uint8_t[size];
@@ -1325,13 +1344,11 @@
    */
   Ptr<Node> node = GetNodeWithAddress (ipv4Address);
   Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-
-  Ipv4Address srcAddress = ipv4Header.GetSource ();
-  Ipv4Address destAddress = ipv4Header.GetDestination ();
   /*
    * The error serialized size
    */
   uint32_t rerrSize;
+  NS_LOG_DEBUG ("The error type value here " << (uint32_t)errorType);
   if (errorType == 1) // unreachable ip address
     {
       /*
@@ -1355,8 +1372,7 @@
        * Delete all the routes including the unreachable node address from the route cache
        */
       Ptr<Node> node = GetNodeWithAddress (ipv4Address);
-      Ptr<dsr::RouteCache> m_routeCache = node->GetObject<dsr::RouteCache> ();
-      m_routeCache->DeleteAllRoutesIncludeLink (errorSource, unreachAddress, ipv4Address);
+      dsr->DeleteAllRoutesIncludeLink (errorSource, unreachAddress, ipv4Address);
 
       Ptr<Packet> newP = p->Copy ();
       uint32_t serialized = DoSendError (newP, rerrUnreach, rerrSize, ipv4Address, protocol);
@@ -1376,7 +1392,7 @@
       p->RemoveHeader (rerrUnsupport);
       rerrSize = rerrUnsupport.GetSerializedSize ();
 
-      // This is for the other two error options TODO
+      // This is for the other two error options, not supporting for now TODO
 //      uint32_t serialized = DoSendError (p, rerrUnsupport, rerrSize, ipv4Address, protocol);
       uint32_t serialized = 0;
       return serialized;
@@ -1405,9 +1421,7 @@
    * Get the segments left field and the next address
    */
   uint8_t segmentsLeft = sourceRoute.GetSegmentsLeft ();
-  NS_LOG_DEBUG ("The segments left " << (uint32_t)segmentsLeft);
   uint8_t length = sourceRoute.GetLength ();
-  NS_LOG_DEBUG ("The number of addresses we have " << (uint32_t)numberAddress);
   uint8_t nextAddressIndex;
   Ipv4Address nextAddress;
   /*
@@ -1438,18 +1452,11 @@
    */
   if (segmentsLeft == 0 && targetAddress == ipv4Address)
     {
-      NS_LOG_DEBUG ("This is the destination of the error");
+      NS_LOG_INFO ("This is the destination of the error, send error request");
       dsr->SendErrorRequest (rerr, protocol);
       return serializedSize;
     }
 
-  DsrOptionRerrUnreachHeader newUnreach;
-  newUnreach.SetErrorType (1);
-  newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
-  newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
-  newUnreach.SetErrorDst (rerr.GetErrorDst ());
-  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
-
   // Get the next Router Address
   DsrOptionSRHeader newSourceRoute;
   newSourceRoute.SetSegmentsLeft (segmentsLeft - 1);
@@ -1468,7 +1475,7 @@
 
   // Set the route entry
   SetRoute (nextAddress, ipv4Address);
-  dsr->ForwardErrPacket (newUnreach, newSourceRoute, nextAddress, protocol, m_ipv4Route);
+  dsr->ForwardErrPacket (rerr, newSourceRoute, nextAddress, protocol, m_ipv4Route);
   return serializedSize;
 }
 
@@ -1521,7 +1528,6 @@
    */
   Ptr<Node> node = GetNodeWithAddress (ipv4Address);
   Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-  Ptr<dsr::RouteCache> m_routeCache = node->GetObject<dsr::RouteCache> ();
 
   NS_LOG_DEBUG ("The next header value " << (uint32_t)protocol);
 
@@ -1583,8 +1589,7 @@
    */
   Ptr<Node> node = GetNodeWithAddress (ipv4Address);
   Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-  Ptr<dsr::RouteCache> srcRouteCache = node->GetObject<dsr::RouteCache> ();
-  srcRouteCache->UpdateRouteEntry (realDst);
+  dsr->UpdateRouteEntry (realDst);
   /*
    * Cancel the packet retransmit timer when receiving the ack packet
    */
--- a/src/dsr/model/dsr-rcache.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-rcache.cc	Sun May 06 20:52:24 2012 -0700
@@ -52,12 +52,33 @@
 namespace ns3 {
 namespace dsr {
 
-void Link::Print () const
+bool CompareRoutesBoth (const RouteCacheEntry &a, const RouteCacheEntry &b)
+{
+  // compare based on both with hop count considered priority
+  return (a.GetVector ().size () < b.GetVector ().size ()) ||
+      ((a.GetVector ().size () == b.GetVector ().size ()) && (a.GetExpireTime() > b.GetExpireTime()))
+      ;
+}
+
+bool CompareRoutesHops (const RouteCacheEntry &a, const RouteCacheEntry &b)
+{
+  // compare based on hops
+  return a.GetVector ().size () < b.GetVector ().size ();
+}
+
+bool CompareRoutesExpire (const RouteCacheEntry &a, const RouteCacheEntry &b)
+{
+  // compare based on expire time
+  return a.GetExpireTime() > b.GetExpireTime();
+}
+
+void Link::Print() const
 {
   NS_LOG_DEBUG (m_low << "----" << m_high);
 }
 
-NodeStab::NodeStab ()
+NodeStab::NodeStab (Time nodeStab)
+  : m_nodeStability (nodeStab + Simulator::Now ())
 {
 }
 
@@ -65,19 +86,8 @@
 {
 }
 
-void
-NodeStab::IncStability ()
-{
-  m_nodeStability = Time (GetNodeStability () * m_stabilityIncrFactor);
-}
-
-void
-NodeStab::DecStability ()
-{
-  m_nodeStability = Time (GetNodeStability () / m_stabilityDecrFactor);
-}
-
-LinkStab::LinkStab ()
+LinkStab::LinkStab (Time linkStab)
+  : m_linkStability (linkStab + Simulator::Now ())
 {
 }
 
@@ -121,23 +131,6 @@
      << "\t";
 }
 
-bool CompareRoutesExpire (const RouteCacheEntry &a, const RouteCacheEntry &b)
-{
-  return a.GetExpireTime () > b.GetExpireTime ();
-}
-
-bool CompareRoutesHop (const RouteCacheEntry &a, const RouteCacheEntry &b)
-{
-  return a.GetVector ().size () < b.GetVector ().size ();
-}
-
-bool CompareRoutes (const RouteCacheEntry &a, const RouteCacheEntry &b)
-{
-  return (a.GetVector ().size () < b.GetVector ().size ())
-         || ((a.GetVector ().size () == b.GetVector ().size ()) && (a.GetExpireTime () > b.GetExpireTime ()))
-  ;
-}
-
 NS_OBJECT_ENSURE_REGISTERED (RouteCache);
 
 TypeId RouteCache::GetTypeId ()
@@ -211,7 +204,7 @@
 RouteCache::LookupRoute (Ipv4Address id, RouteCacheEntry & rt)
 {
   NS_LOG_FUNCTION (this << id);
-  if (IsLinkCache ())
+  if (IsLinkCache())
     {
       return LookupRoute_Link (id, rt);
     }
@@ -261,7 +254,7 @@
                       RouteCacheEntry changeEntry; // Create the route entry
                       changeEntry.SetVector (changeVector);
                       changeEntry.SetDestination (id);
-                      // use the expire time from original route entry
+                      // Use the expire time from original route entry
                       changeEntry.SetExpireTime (k->GetExpireTime ());
                       // We need to add new route entry here
                       std::list<RouteCacheEntry> newVector;
@@ -285,7 +278,7 @@
        */
       std::list<RouteCacheEntry> rtVector = m->second;
       rt = rtVector.front ();  // use the first entry in the route vector
-      NS_LOG_DEBUG ("Route to " << id << " with route size " << rtVector.size ());
+      NS_LOG_DEBUG ("Route to " << id << " with route size " << rtVector.size());
       return true;
     }
 }
@@ -295,23 +288,20 @@
 {
   NS_LOG_FUNCTION (this << type);
   if (type == std::string ("LinkCache"))
-    {
-      m_isLinkCache = true;
-    }
+    m_isLinkCache = true;
   else if (type == std::string ("PathCache"))
-    {
-      m_isLinkCache = false;
-    }
+    m_isLinkCache = false;
   else
     {
       m_isLinkCache = false;             // use path cache as default
-      NS_LOG_DEBUG ("Error Cache Type");
+      NS_LOG_INFO ("Error Cache Type");
     }
 }
 
 bool
 RouteCache::IsLinkCache ()
 {
+  NS_LOG_FUNCTION (this);
   return m_isLinkCache;
 }
 
@@ -319,14 +309,13 @@
 RouteCache::RebuildBestRouteTable (Ipv4Address source)
 {
   NS_LOG_FUNCTION (this << source);
-  /*
-   * the followings are initialize-single-source
+  /**
+   * \brief The followings are initialize-single-source
    */
   // @d shortest-path estimate
   std::map<Ipv4Address, uint32_t> d;
   // @pre preceeding node
   std::map<Ipv4Address, Ipv4Address> pre;
-  NS_LOG_FUNCTION (this << source);
   for (std::map<Ipv4Address, std::map<Ipv4Address, uint32_t> >::iterator i = m_netGraph.begin (); i != m_netGraph.end (); ++i)
     {
       if (i->second.find (source) != i->second.end ())
@@ -342,72 +331,72 @@
     }
   d[source] = 0;
   /**
-   * the followings are core of dijskra algorithm
-   *
+   * \brief The followings are core of dijskra algorithm
    */
   // the node set which shortest distance has been calculated, if true calculated
   std::map<Ipv4Address, bool> s;
   double temp = MAXWEIGHT;
   Ipv4Address tempip = Ipv4Address ("255.255.255.255");
   for (uint32_t i = 0; i < m_netGraph.size (); i++)
+  {
+    temp = MAXWEIGHT;
+    for (std::map<Ipv4Address,uint32_t>::const_iterator j = d.begin (); j != d.end (); ++j)
+      {
+        Ipv4Address ip = j->first;
+        if (s.find (ip) == s.end ())
+          {
+            /**
+             * \brief The followings are for comparison
+             */
+            if (j->second <= temp)
+              {
+                temp = j->second;
+                tempip = ip;
+              }
+          }
+      }
+    if (!tempip.IsBroadcast ())
     {
-      temp = MAXWEIGHT;
-      for (std::map<Ipv4Address,uint32_t>::iterator j = d.begin (); j != d.end (); ++j)
+      s[tempip] = true;
+      for (std::map<Ipv4Address, uint32_t>::const_iterator k = m_netGraph[tempip].begin (); k != m_netGraph[tempip].end (); ++k)
+      {
+        if (s.find (k->first) == s.end () && d[k->first] > d[tempip] + k->second)
+          {
+            d[k->first] = d[tempip] + k->second;
+            pre[k->first] = tempip;
+          }
+        /**
+         *  Selects the shortest-length route that has the longest expected lifetime
+         *  (highest minimum timeout of any link in the route)
+         *  For the computation overhead and complexity
+         *  Here I just implement kind of greedy strategy to select link with the longest expected lifetime when there is two options
+         */
+        else if (d[k->first] == d[tempip] + k->second)
         {
-          Ipv4Address ip = j->first;
-          if (s.find (ip) == s.end ())
+          std::map<Link, LinkStab>::iterator oldlink = m_linkCache.find (Link (k->first, pre[k->first]));
+          std::map<Link, LinkStab>::iterator newlink = m_linkCache.find (Link (k->first, tempip));
+          if (oldlink != m_linkCache.end () && newlink != m_linkCache.end ())
             {
-              /*
-               * the followings are for comparison
-               */
-              if (j->second <= temp)
+              if (oldlink->second.GetLinkStability () < newlink->second.GetLinkStability ())
                 {
-                  temp = j->second;
-                  tempip = ip;
-                }
-            }
-        }
-      if (!tempip.IsBroadcast ())
-        {
-          s[tempip] = true;
-          for (std::map<Ipv4Address, uint32_t>::iterator k = m_netGraph[tempip].begin (); k != m_netGraph[tempip].end (); ++k)
-            {
-              if (s.find (k->first) == s.end () && d[k->first] > d[tempip] + k->second)
-                {
+                  NS_LOG_INFO ("Select the link with longest expected lifetime");
                   d[k->first] = d[tempip] + k->second;
                   pre[k->first] = tempip;
                 }
-              /**
-               *  Selects the shortest-length route that has the longest expected lifetime
-               *  (highest minimum timeout of any link in the route)
-               *  For the computation overhead and complexity
-               *  Here I just implement kind of greedy strategy to select link with the longest expected lifetime when there is two options
-               */
-              else if (d[k->first] == d[tempip] + k->second)
-                {
-                  std::map<Link, LinkStab>::iterator oldlink = m_linkCache.find (Link (k->first, pre[k->first]));
-                  std::map<Link, LinkStab>::iterator newlink = m_linkCache.find (Link (k->first, tempip));
-                  if (oldlink != m_linkCache.end () && newlink != m_linkCache.end ())
-                    {
-                      if (oldlink->second.GetLinkStability () < newlink->second.GetLinkStability ())
-                        {
-                          NS_LOG_DEBUG ("Select the link with longest expected lifetime");
-                          d[k->first] = d[tempip] + k->second;
-                          pre[k->first] = tempip;
-                        }
-                    }
-                  else
-                    {
-                      NS_LOG_DEBUG ("Link Stability Info Corrupt");
-                    }
-                }
+            }
+          else
+            {
+              NS_LOG_INFO ("Link Stability Info Corrupt");
             }
         }
+      }
     }
+  }
   // clean the best route table
   m_bestRoutesTable_link.clear ();
-  for (std::map<Ipv4Address, Ipv4Address>::iterator i = pre.begin (); i != pre.end (); ++i)
-    { // loop for all vertexes
+  for(std::map<Ipv4Address, Ipv4Address>::iterator i = pre.begin (); i != pre.end (); ++i)
+    {
+      // loop for all vertexes
       RouteCacheEntry::IP_VECTOR route;
       Ipv4Address iptemp = i->first;
 
@@ -419,11 +408,11 @@
               iptemp = pre[iptemp];
             }
           route.push_back (source);
-          /*
-           * reverse the route
+          /**
+           * \brief Reverse the route
            */
           RouteCacheEntry::IP_VECTOR reverseroute;
-          for (RouteCacheEntry::IP_VECTOR::reverse_iterator j = route.rbegin (); j != route.rend (); ++j)
+          for(RouteCacheEntry::IP_VECTOR::reverse_iterator j = route.rbegin (); j!= route.rend (); ++j)
             {
               reverseroute.push_back (*j);
             }
@@ -438,24 +427,26 @@
 RouteCache::LookupRoute_Link (Ipv4Address id, RouteCacheEntry & rt)
 {
   NS_LOG_FUNCTION (this << id);
-  NS_LOG_DEBUG ("Use Link Cache");
-  std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR>::iterator i = m_bestRoutesTable_link.find (id);
+  std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR>::const_iterator i = m_bestRoutesTable_link.find (id);
   if (i == m_bestRoutesTable_link.end ())
     {
-      NS_LOG_DEBUG ("No Route To " << id);
+      NS_LOG_INFO("No Route To " << id);
       return false;
     }
   else
     {
       if (i->second.size () < 2)
         {
-          NS_LOG_DEBUG ("Route To " << id << " Error");
+          NS_LOG_DEBUG ("Route To " << id << " error");
           return false;
         }
-      RouteCacheEntry toSource (/*IP_VECTOR=*/ i->second, /*dst=*/ id, /*expire time=*/ Time (0));
-      rt = toSource;
-      NS_LOG_DEBUG ("The route length " << i->second.size ());
-      NS_LOG_LOGIC ("Route to " << id << " found");
+
+      RouteCacheEntry newEntry; // Create the route entry
+      newEntry.SetVector (i->second);
+      newEntry.SetDestination (id);
+      newEntry.SetExpireTime (RouteCacheTimeout);
+      NS_LOG_INFO ("Route to " << id << " found with the route length " << i->second.size ());
+      rt = newEntry;
       std::vector<Ipv4Address> path = rt.GetVector ();
       PrintVector (path);
       return true;
@@ -466,26 +457,34 @@
 RouteCache::PurgeLinkNode ()
 {
   NS_LOG_FUNCTION (this);
-  for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); )
+  NS_LOG_DEBUG ("The size of the link cache before " << m_linkCache.size());
+  for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end ();)
     {
+      NS_LOG_DEBUG ("The link stability " << i->second.GetLinkStability());
+      std::map<Link, LinkStab>::iterator itmp = i;
       if (i->second.GetLinkStability () <= Seconds (0))
         {
-          m_linkCache.erase (i++);
+          ++i;
+          m_linkCache.erase (itmp);
         }
       else
         {
-          i++;
+          ++i;
         }
     }
-  for (std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.begin (); i != m_nodeCache.end (); )
+  NS_LOG_DEBUG ("The size of the node cache before " << m_nodeCache.size());
+  for (std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.begin (); i != m_nodeCache.end ();)
     {
+      NS_LOG_DEBUG ("The node stability " << i->second.GetNodeStability ());
+      std::map<Ipv4Address, NodeStab>::iterator itmp = i;
       if (i->second.GetNodeStability () <= Seconds (0))
         {
-          m_nodeCache.erase (i++);
+          ++i;
+          m_nodeCache.erase (itmp);
         }
       else
         {
-          i++;
+          ++i;
         }
     }
 }
@@ -495,8 +494,9 @@
 {
   NS_LOG_FUNCTION (this);
   m_netGraph.clear ();
-  for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); ++i)
+  for(std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); ++i)
     {
+      // Here the weight is set as 1
       uint32_t weight = 1;
       m_netGraph[i->first.m_low][i->first.m_high] = weight;
       m_netGraph[i->first.m_high][i->first.m_low] = weight;
@@ -504,6 +504,47 @@
 }
 
 bool
+RouteCache::IncStability (Ipv4Address node)
+{
+  NS_LOG_FUNCTION (this << node);
+  std::map<Ipv4Address, NodeStab>::const_iterator i = m_nodeCache.find (node);
+  if (i == m_nodeCache.end ())
+    {
+      NS_LOG_INFO ("The initial stability " << m_initStability.GetSeconds ());
+      NodeStab ns (m_initStability);
+      m_nodeCache[node] = ns;
+      return false;
+    }
+  else
+    {
+      NodeStab ns (Time (i->second.GetNodeStability () * m_stabilityIncrFactor));
+      m_nodeCache[node] = ns;
+      return true;
+    }
+  return false;
+}
+
+bool
+RouteCache::DecStability (Ipv4Address node)
+{
+  NS_LOG_FUNCTION (this << node);
+  std::map<Ipv4Address, NodeStab>::const_iterator i = m_nodeCache.find (node);
+  if (i == m_nodeCache.end ())
+    {
+      NodeStab ns (m_initStability);
+      m_nodeCache[node] = ns;
+      return false;
+    }
+  else
+    {
+      NodeStab ns (Time (i->second.GetNodeStability () / m_stabilityDecrFactor));
+      m_nodeCache[node] = ns;
+      return true;
+    }
+  return false;
+}
+
+bool
 RouteCache::AddRoute_Link (RouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source)
 {
   NS_LOG_FUNCTION (this << source);
@@ -511,34 +552,31 @@
   for (uint32_t i = 0; i < nodelist.size () - 1; i++)
     {
       NodeStab ns;
-      ns.SetNodeStability (Seconds (m_initStability));
-      ns.SetStabilityIncrFactor (m_stabilityIncrFactor);
-      ns.SetStabilityDecrFactor (m_stabilityDecrFactor);
+      ns.SetNodeStability (m_initStability);
 
       if (m_nodeCache.find (nodelist[i]) == m_nodeCache.end ())
         {
           m_nodeCache[nodelist[i]] = ns;
         }
-      if (m_nodeCache.find (nodelist[i + 1]) == m_nodeCache.end ())
+      if (m_nodeCache.find (nodelist[i+1]) == m_nodeCache.end ())
         {
-          m_nodeCache[nodelist[i + 1]] = ns;
+          m_nodeCache[nodelist[i+1]] = ns;
         }
-      Link link (nodelist[i], nodelist[i + 1]);
+      Link link (nodelist[i], nodelist[i+1]);
       LinkStab stab;
-      stab.SetLinkStability (Seconds (m_initStability));
-      if (m_nodeCache[nodelist[i]].GetNodeStability () < m_nodeCache[nodelist[i + 1]].GetNodeStability ())
+      stab.SetLinkStability (m_initStability);
+      if (m_nodeCache[nodelist[i]].GetNodeStability () < m_nodeCache[nodelist[i+1]].GetNodeStability ())
         {
           stab.SetLinkStability (m_nodeCache[nodelist[i]].GetNodeStability ());
         }
       else
         {
-          stab.SetLinkStability (m_nodeCache[nodelist[i + 1]].GetNodeStability ());
+          stab.SetLinkStability (m_nodeCache[nodelist[i+1]].GetNodeStability ());
         }
-
-      if (stab.GetLinkStability () < (Seconds (m_minLifeTime)))
+      if (stab.GetLinkStability () < m_minLifeTime)
         {
-          NS_LOG_DEBUG ("stability: " << stab.GetLinkStability ());
-          stab.SetLinkStability (Seconds (m_minLifeTime));
+          NS_LOG_DEBUG ("Stability: " << stab.GetLinkStability ().GetSeconds ());
+          stab.SetLinkStability (m_minLifeTime);
         }
       m_linkCache[link] = stab;
       NS_LOG_DEBUG ("Add a new link");
@@ -555,24 +593,25 @@
 void
 RouteCache::UseExtends (RouteCacheEntry::IP_VECTOR rt)
 {
+  NS_LOG_FUNCTION (this);
   if (rt.size () < 2)
     {
-      NS_LOG_DEBUG ("The route is too short");
+      NS_LOG_INFO ("The route is too short");
     }
   for (RouteCacheEntry::IP_VECTOR::iterator i = rt.begin (); i != rt.end () - 1; ++i)
     {
-      Link link (*i, *(i + 1));
+      Link link (*i, *(i+1));
       if (m_linkCache.find (link) != m_linkCache.end ())
         {
-          if (m_linkCache[link].GetLinkStability () < Time (Seconds (m_useExtends)))
+          if (m_linkCache[link].GetLinkStability () < m_useExtends)
             {
-              m_linkCache[link].SetLinkStability (Time (Seconds (m_useExtends)));
+              m_linkCache[link].SetLinkStability (m_useExtends);
+              NS_LOG_DEBUG ("The time of the link " << m_linkCache[link].GetLinkStability ().GetSeconds ());
             }
-          NS_LOG_DEBUG ("The time of the link " << m_linkCache[link].GetLinkStability ().GetSeconds ());
         }
       else
         {
-          NS_LOG_DEBUG ("we cannot find a link in cache");
+          NS_LOG_INFO ("we cannot find a link in cache");
         }
     }
   // Increase the stability of the node cache
@@ -580,14 +619,14 @@
     {
       if (m_nodeCache.find (*i) != m_nodeCache.end ())
         {
-          NS_LOG_DEBUG ("increase the stability");
+          NS_LOG_DEBUG ("Increase the stability");
           if (m_nodeCache[*i].GetNodeStability () <= m_initStability)
             {
-              m_nodeCache[*i].IncStability ();
+              IncStability (*i);
             }
           else
             {
-              NS_LOG_DEBUG ("The node stability has already been increased");
+              NS_LOG_INFO ("The node stability has already been increased");
             }
         }
     }
@@ -609,8 +648,8 @@
   if (i == m_sortedRoutes.end ())
     {
       rtVector.push_back (rt);
-      m_sortedRoutes.erase (dst);   // erase the route entries for dst first
-      /*
+      m_sortedRoutes.erase (dst);   // Erase the route entries for dst first
+      /**
        * Save the new route cache along with the destination address in map
        */
       std::pair<std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator, bool> result =
@@ -621,8 +660,8 @@
     {
       rtVector = i->second;
       NS_LOG_DEBUG ("The existing route size " << rtVector.size () << " for destination address " << dst);
-      /*
-       * Drop the most aged packet when buffer reaches to max
+      /**
+       * \brief Drop the most aged packet when buffer reaches to max
        */
       if (rtVector.size () >= m_maxEntriesEachDst)
         {
@@ -643,12 +682,12 @@
               // This sort function will sort the route cache entries based on the size of route in each of the
               // route entries
               rtVector.sort (CompareRoutesExpire);
-              NS_LOG_DEBUG ("The first time" << rtVector.front ().GetExpireTime ().GetSeconds () << " The second time "
-                                             << rtVector.back ().GetExpireTime ().GetSeconds ());
+              NS_LOG_DEBUG ("The first time" << rtVector.front().GetExpireTime().GetSeconds() << " The second time "
+                  << rtVector.back ().GetExpireTime ().GetSeconds ());
               NS_LOG_DEBUG ("The first hop" << rtVector.front ().GetVector ().size () << " The second hop "
-                                            << rtVector.back ().GetVector ().size ());
+                  << rtVector.back ().GetVector ().size ());
               m_sortedRoutes.erase (dst);               // erase the route entries for dst first
-              /*
+              /**
                * Save the new route cache along with the destination address in map
                */
               std::pair<std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator, bool> result =
@@ -657,7 +696,7 @@
             }
           else
             {
-              NS_LOG_DEBUG ("The newly found route is expired");
+              NS_LOG_INFO ("The newly found route is already expired");
             }
         }
     }
@@ -676,9 +715,9 @@
       if (routeVector == newVector)
         {
           NS_LOG_DEBUG ("Found same routes in the route cache with the vector size "
-                        << rt.GetDestination () << " " << rtVector.size ());
-          NS_LOG_DEBUG ("The new route expire time " << rt.GetExpireTime ().GetSeconds ()
-                                                     << " the original expire time " << i->GetExpireTime ().GetSeconds ());
+              << rt.GetDestination() << " " << rtVector.size());
+          NS_LOG_DEBUG ("The new route expire time " << rt.GetExpireTime().GetSeconds()
+              << " the original expire time " << i->GetExpireTime().GetSeconds());
           if (rt.GetExpireTime () > i->GetExpireTime ())
             {
               i->SetExpireTime (rt.GetExpireTime ());
@@ -699,6 +738,7 @@
 bool
 RouteCache::DeleteRoute (Ipv4Address dst)
 {
+  NS_LOG_FUNCTION (this << dst);
   Purge (); // purge the route cache first to remove timeout entries
   if (m_sortedRoutes.erase (dst) != 0)
     {
@@ -713,37 +753,36 @@
 RouteCache::DeleteAllRoutesIncludeLink (Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node)
 {
   NS_LOG_FUNCTION (this << errorSrc << unreachNode << node);
-  if (IsLinkCache ())
+  if(IsLinkCache ())
     {
       /*
-       * the followings are for cleaning the broken link in linkcache
+       * The followings are for cleaning the broken link in linkcache
        *
        */
-      Link link (errorSrc, unreachNode);
-      if (m_linkCache.erase (link) == 0)
+      Link link1 (errorSrc, unreachNode);
+      Link link2 (unreachNode, errorSrc);
+      // erase the two kind of links to make sure the link is removed from the link cache
+      NS_LOG_DEBUG ("Erase the route ");
+      m_linkCache.erase (link1);
+      m_linkCache.erase (link2);
+
+      std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.find (errorSrc);
+      if (i == m_nodeCache.end ())
         {
-          NS_LOG_LOGIC ("Cut route unsuccessful and erase the route");
+          NS_LOG_LOGIC ("Update the node stability unsuccessfully");
         }
       else
         {
-          std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.find (errorSrc);
-          if (i == m_nodeCache.end ())
-            {
-              NS_LOG_LOGIC ("Update the node stability unsuccessfully");
-            }
-          else
-            {
-              i->second.DecStability ();
-            }
-          i = m_nodeCache.find (unreachNode);
-          if (i == m_nodeCache.end ())
-            {
-              NS_LOG_LOGIC ("Update the node stability unsuccessfully");
-            }
-          else
-            {
-              i->second.DecStability ();
-            }
+          DecStability (i->first);
+        }
+      i = m_nodeCache.find (unreachNode);
+      if (i == m_nodeCache.end ())
+        {
+          NS_LOG_LOGIC ("Update the node stability unsuccessfully");
+        }
+      else
+        {
+          DecStability (i->first);
         }
       PurgeLinkNode ();
       UpdateNetGraph ();
@@ -845,10 +884,8 @@
             }
           ++j;
           if (!IsLinkCache ())
-            {
-              m_sortedRoutes.erase (jtmp);
-            }
-          if (rtVector.size ())
+            m_sortedRoutes.erase (jtmp);
+          if (rtVector.size())
             {
               /*
                * Save the new route cache along with the destination address in map
@@ -867,6 +904,7 @@
 void
 RouteCache::PrintVector (std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this);
   /*
    * Check elements in a route vector, used when one wants to check the IP addresses saved in
    */
@@ -887,10 +925,11 @@
 void
 RouteCache::PrintRouteVector (std::list<RouteCacheEntry> route)
 {
+  NS_LOG_FUNCTION (this);
   for (std::list<RouteCacheEntry>::iterator i = route.begin (); i != route.end (); i++)
     {
-      std::vector<Ipv4Address> path = i->GetVector ();
-      NS_LOG_DEBUG ("Route NO. ");
+      std::vector<Ipv4Address> path = i->GetVector();
+      NS_LOG_INFO ("Route NO. ");
       PrintVector (path);
     }
 }
@@ -898,6 +937,7 @@
 void
 RouteCache::Purge ()
 {
+  NS_LOG_FUNCTION (this);
   //Trying to purge the route cache
   if (m_sortedRoutes.empty ())
     {
@@ -905,7 +945,7 @@
       return;
     }
   for (std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator i =
-         m_sortedRoutes.begin (); i != m_sortedRoutes.end (); )
+          m_sortedRoutes.begin (); i != m_sortedRoutes.end (); )
     {
       // Loop of route cache entry with the route size
       std::map<Ipv4Address, std::list<RouteCacheEntry> >::iterator itmp = i;
@@ -914,7 +954,7 @@
        */
       Ipv4Address dst = i->first;
       std::list<RouteCacheEntry> rtVector = i->second;
-      NS_LOG_DEBUG ("The route vector size of1 " << dst << " " << rtVector.size ());
+      NS_LOG_DEBUG ("The route vector size of 1 " << dst << " " << rtVector.size());
       if (rtVector.size ())
         {
           for (std::list<RouteCacheEntry>::iterator j = rtVector.begin (); j != rtVector.end (); )
@@ -936,7 +976,7 @@
                   ++j;
                 }
             }
-          NS_LOG_DEBUG ("The route vector size of2 " << dst << " " << rtVector.size ());
+          NS_LOG_DEBUG ("The route vector size of 2 " << dst << " " << rtVector.size());
           if (rtVector.size ())
             {
               ++i;
@@ -965,6 +1005,7 @@
 void
 RouteCache::Print (std::ostream &os)
 {
+  NS_LOG_FUNCTION (this);
   Purge ();
   os << "\nDSR Route Cache\n"
      << "Destination\tGateway\t\tInterface\tFlag\tExpire\tHops\n";
@@ -983,14 +1024,14 @@
 uint16_t
 RouteCache::CheckUniqueAckId (Ipv4Address nextHop)
 {
-  NS_LOG_DEBUG ("The size of ack id cache " << m_ackIdCache.size ());
+  NS_LOG_FUNCTION (this);
   std::map<Ipv4Address, uint16_t>::const_iterator i =
     m_ackIdCache.find (nextHop);
   if (i == m_ackIdCache.end ())
     {
-      NS_LOG_LOGIC ("No Ack id for " << nextHop << " found");
-      m_ackIdCache[nextHop] = 0;
-      return 0;
+      NS_LOG_LOGIC ("No Ack id for " << nextHop << " found and use id 1 for the first network ack id");
+      m_ackIdCache[nextHop] = 1;
+      return 1;
     }
   else
     {
@@ -1015,6 +1056,7 @@
 bool
 RouteCache::IsNeighbor (Ipv4Address addr)
 {
+  NS_LOG_FUNCTION (this);
   PurgeMac ();  // purge the mac cache
   for (std::vector<Neighbor>::const_iterator i = m_nb.begin ();
        i != m_nb.end (); ++i)
@@ -1030,6 +1072,7 @@
 Time
 RouteCache::GetExpireTime (Ipv4Address addr)
 {
+  NS_LOG_FUNCTION (this);
   PurgeMac ();
   for (std::vector<Neighbor>::const_iterator i = m_nb.begin (); i
        != m_nb.end (); ++i)
@@ -1045,6 +1088,7 @@
 void
 RouteCache::UpdateNeighbor (std::vector<Ipv4Address> nodeList, Time expire)
 {
+  NS_LOG_FUNCTION (this);
   for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
     {
       for (std::vector<Ipv4Address>::iterator j = nodeList.begin (); j != nodeList.end (); ++j)
--- a/src/dsr/model/dsr-rcache.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-rcache.h	Sun May 06 20:52:24 2012 -0700
@@ -79,7 +79,6 @@
 
   \endverbatim
  */
-
 /**
  * \ingroup dsr
  * \brief DSR Route Cache Entry
@@ -89,90 +88,37 @@
   Ipv4Address m_low;
   Ipv4Address m_high;
   Link (Ipv4Address ip1, Ipv4Address ip2)
-  {
-    if (ip1 < ip2)
-      {
-        m_low = ip1;
-        m_high = ip2;
-      }
-    else
-      {
-        m_low = ip2;
-        m_high = ip1;
-      }
-  }
+    {
+      if (ip1 < ip2)
+        {
+          m_low = ip1;
+          m_high = ip2;
+        }
+      else
+        {
+          m_low = ip2;
+          m_high = ip1;
+        }
+    }
   bool operator < (Link const& L) const
-  {
-    if (m_low < L.m_low)
-      {
+    {
+      if (m_low < L.m_low)
         return true;
-      }
-    else if (m_low == L.m_low)
-      {
+      else if (m_low == L.m_low)
         return (m_high < L.m_high);
-      }
-    else
-      {
+      else
         return false;
-      }
-  }
+    }
   void Print () const;
 };
 
-class NodeStab
-{
-public:
-  /**
-   * \brief Constructor
-   */
-  NodeStab ();
-  /**
-   * \brief Destructor
-   */
-  virtual ~NodeStab ();
-
-  void SetStabilityIncrFactor (double stabilityIncrFactor)
-  {
-    m_stabilityIncrFactor = stabilityIncrFactor;
-  }
-  double GetStabilityIncrFactor () const
-  {
-    return m_stabilityIncrFactor;
-  }
-  void SetStabilityDecrFactor (double stabilityDecrFactor)
-  {
-    m_stabilityDecrFactor = stabilityDecrFactor;
-  }
-  double GetStabilityDecrFactor () const
-  {
-    return m_stabilityDecrFactor;
-  }
-
-  void IncStability ();
-
-  void DecStability ();
-
-  void SetNodeStability (Time nodeStab)
-  {
-    m_nodeStability = nodeStab + Simulator::Now ();
-  }
-  Time GetNodeStability () const
-  {
-    return m_nodeStability - Simulator::Now ();
-  }
-private:
-  Time m_nodeStability;
-  double m_stabilityIncrFactor;
-  double m_stabilityDecrFactor;
-};
-
 class LinkStab
 {
 public:
   /**
    * \brief Constructor
    */
-  LinkStab ();
+  LinkStab (Time linkStab = Simulator::Now ());
   /**
    * \brief Destructor
    */
@@ -188,6 +134,7 @@
   }
 
   void Print () const;
+
 private:
   /*
    * The link stability lifetime expected, when the time is due, the link expires the expiration happens
@@ -196,6 +143,31 @@
   Time m_linkStability;
 };
 
+class NodeStab
+{
+public:
+  /**
+   * \brief Constructor
+   */
+//  NodeStab ();
+  NodeStab (Time nodeStab = Simulator::Now ());
+  /**
+   * \brief Destructor
+   */
+  virtual ~NodeStab ();
+
+  void SetNodeStability (Time nodeStab)
+  {
+    m_nodeStability = nodeStab + Simulator::Now ();
+  }
+  Time GetNodeStability () const
+  {
+    return m_nodeStability - Simulator::Now ();
+  }
+private:
+  Time m_nodeStability;
+};
+
 class RouteCacheEntry
 {
 public:
@@ -266,36 +238,37 @@
   bool operator== (RouteCacheEntry const & o) const
   {
     if (m_path.size () != o.m_path.size ())
-      {
-        NS_ASSERT (false);
-        return false;
-      }
+    {
+      NS_ASSERT (false);
+      return false;
+    }
     IP_VECTOR::const_iterator j = o.m_path.begin ();
     for (IP_VECTOR::const_iterator i = m_path.begin (); i
          != m_path.end (); i++, j++)
+    {
+      /*
+       * Verify if neither the entry are not 0 and they equal to each other
+       */
+      if (((*i) == 0) || ((*j) == 0))
       {
-        /*
-         * Verify if neither the entry are not 0 and they equal to each other
-         */
-        if (((*i) == 0) || ((*j) == 0))
-          {
-            return false;
-          }
-        else if (!((*i) == (*j)) )
-          {
-            return false;
-          }
-        else
-          {
-            return true;
-          }
+        return false;
+      }
+      else if (!((*i) == (*j)) )
+      {
+        return false;
       }
+      else
+      {
+        return true;
+      }
+    }
     return false;
   }
   // \}
+
+private:
   // / RREP_ACK timer
   Timer m_ackTimer;
-private:
   // / The destination Ip address
   Ipv4Address m_dst;
   // / brief The IP address constructed route
@@ -389,43 +362,43 @@
   {
     m_badLinkLifetime = t;
   }
-  double GetStabilityDecrFactor () const
+  uint64_t GetStabilityDecrFactor () const
   {
     return m_stabilityDecrFactor;
   }
-  void SetStabilityDecrFactor (double decrFactor)
+  void SetStabilityDecrFactor (uint64_t decrFactor)
   {
     m_stabilityDecrFactor = decrFactor;
   }
-  double GetStabilityIncrFactor () const
+  uint64_t GetStabilityIncrFactor () const
   {
     return m_stabilityIncrFactor;
   }
-  void SetStabilityIncrFactor (double incrFactor)
+  void SetStabilityIncrFactor (uint64_t incrFactor)
   {
     m_stabilityIncrFactor = incrFactor;
   }
-  double GetInitStability () const
+  Time GetInitStability () const
   {
     return m_initStability;
   }
-  void SetInitStability (double initStability)
+  void SetInitStability (Time initStability)
   {
     m_initStability = initStability;
   }
-  double GetMinLifeTime () const
+  Time GetMinLifeTime () const
   {
     return m_minLifeTime;
   }
-  void SetMinLifeTime (double minLifeTime)
+  void SetMinLifeTime (Time minLifeTime)
   {
     m_minLifeTime = minLifeTime;
   }
-  double GetUseExtends () const
+  Time GetUseExtends () const
   {
     return m_useExtends;
   }
-  void SetUseExtends (double useExtends)
+  void SetUseExtends (Time useExtends)
   {
     m_useExtends = useExtends;
   }
@@ -566,11 +539,11 @@
   /*
    * Define the parameters for link cache type
    */
-  double m_stabilityDecrFactor;
-  double m_stabilityIncrFactor;
-  double m_initStability;
-  double m_minLifeTime;
-  double m_useExtends;
+  uint64_t m_stabilityDecrFactor;
+  uint64_t m_stabilityIncrFactor;
+  Time m_initStability;
+  Time m_minLifeTime;
+  Time m_useExtends;
   /*
    * Define the route cache data structure
    */
@@ -587,12 +560,12 @@
   bool m_isLinkCache;
   // / Check if save the sub route entries or not
   bool m_subRoute;
-  /*
+  /**
    * The link cache to update all the link status, bi-link is two link for link is a struct
    * when the weight is calculated we normalized them: 100*weight/max of Weight
    */
   #define MAXWEIGHT 0xFFFF;
-  /*
+  /**
    * Current network graph state for this node, double is weight, which is calculated by the node information
    * and link information, any time some changes of link cache and node cache
    * change the weight and then recompute the best choice for each node
@@ -602,23 +575,27 @@
   std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR> m_bestRoutesTable_link;
   std::map<Link, LinkStab> m_linkCache;
   std::map<Ipv4Address, NodeStab> m_nodeCache;
-  //used by LookupRoute when LinkCache
+  // used by LookupRoute when LinkCache
   bool LookupRoute_Link (Ipv4Address id, RouteCacheEntry & rt);
+
+  bool IncStability (Ipv4Address node);
+
+  bool DecStability (Ipv4Address node);
+
 public:
   /**
    * \brief dijsktra algorithm to get the best route from m_netGraph and update the m_bestRoutesTable_link
    * \when current graph information has changed
-   *
    */
   void SetCacheType (std::string type);
   bool IsLinkCache ();
   bool AddRoute_Link (RouteCacheEntry::IP_VECTOR nodelist, Ipv4Address node);
-  /*
-   *  USE MAXWEIGHT TO REPRESENT MAX; USE BROADCAST ADDRESS TO REPRESENT NULL PRECEEDING ADDRESS
+  /**
+   *  \brief USE MAXWEIGHT TO REPRESENT MAX; USE BROADCAST ADDRESS TO REPRESENT NULL PRECEEDING ADDRESS
    */
   void RebuildBestRouteTable (Ipv4Address source);
   void PurgeLinkNode ();
-  /*
+  /**
    * When a link from the Route Cache is used in routing a packet originated or salvaged
    * by that node, the stability metric for each of the two endpoint nodes of that link is incremented by the
    * amount of time since that link was last used. When a link is used in a route chosen for a packet originated or
@@ -630,7 +607,7 @@
    */
   void UpdateNetGraph ();
   //---------------------------------------------------------------------------------------
-  /*
+  /**
    * The following code handles link-layer acks
    */
   // / link failure callback
--- a/src/dsr/model/dsr-routing.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-routing.cc	Sun May 06 20:52:24 2012 -0700
@@ -39,11 +39,17 @@
 #include <algorithm>
 #include <iostream>
 
+#include "ns3/enum.h"
 #include "ns3/string.h"
 #include "ns3/ptr.h"
 #include "ns3/log.h"
 #include "ns3/assert.h"
 #include "ns3/uinteger.h"
+#include "ns3/packet.h"
+#include "ns3/boolean.h"
+#include "ns3/node-list.h"
+#include "ns3/double.h"
+#include "ns3/pointer.h"
 #include "ns3/object-vector.h"
 #include "ns3/ipv4-address.h"
 #include "ns3/ipv4-header.h"
@@ -53,17 +59,12 @@
 #include "ns3/trace-source-accessor.h"
 #include "ns3/random-variable.h"
 #include "ns3/icmpv4-l4-protocol.h"
-#include "ns3/pointer.h"
 #include "ns3/adhoc-wifi-mac.h"
 #include "ns3/wifi-net-device.h"
-#include "ns3/packet.h"
-#include "ns3/boolean.h"
 #include "ns3/inet-socket-address.h"
 #include "ns3/udp-l4-protocol.h"
 #include "ns3/udp-socket-factory.h"
 #include "ns3/tcp-socket-factory.h"
-#include "ns3/node-list.h"
-#include "ns3/double.h"
 
 #include "dsr-rreq-table.h"
 #include "dsr-rcache.h"
@@ -138,20 +139,16 @@
                    TimeValue (Seconds (300)),
                    MakeTimeAccessor (&DsrRouting::m_maxCacheTime),
                    MakeTimeChecker ())
-    .AddAttribute ("RreqEntryTimeout","Maximum time for the route request entry to time out.",
-                   TimeValue (Seconds (30)),
-                   MakeTimeAccessor (&DsrRouting::m_maxRreqTime),
-                   MakeTimeChecker ())
     .AddAttribute ("MaxEntriesEachDst","Maximum number of route entries for a single destination to respond.",
                    UintegerValue (20),
                    MakeUintegerAccessor (&DsrRouting::m_maxEntriesEachDst),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("SendBuffInterval","How often to check send buffer for packet with route.",
-                   TimeValue (Seconds (50)),
+                   TimeValue (Seconds (500)),
                    MakeTimeAccessor (&DsrRouting::m_sendBuffInterval),
                    MakeTimeChecker ())
     .AddAttribute ("NodeTraversalTime","The time it takes to traverse two neighboring nodes.",
-                   TimeValue (MicroSeconds (2)),
+                   TimeValue (MilliSeconds (40)),
                    MakeTimeAccessor (&DsrRouting::m_nodeTraversalTime),
                    MakeTimeChecker ())
     .AddAttribute ("RreqRetries","Maximum number of retransmissions for request discovery of a route.",
@@ -159,9 +156,9 @@
                    MakeUintegerAccessor (&DsrRouting::m_rreqRetries),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("MaintenanceRetries","Maximum number of retransmissions for data packets from maintenance buffer.",
-                   UintegerValue (3),
-                   MakeUintegerAccessor (&DsrRouting::m_maxMaintRexmt),
-                   MakeUintegerChecker<uint32_t> ())
+                   DoubleValue (2),
+                   MakeDoubleAccessor (&DsrRouting::m_maxMaintRexmt),
+                   MakeDoubleChecker<uint32_t> ())
     .AddAttribute ("RequestTableSize","Maximum number of request entries in the request table.",
                    UintegerValue (64),
                    MakeUintegerAccessor (&DsrRouting::m_requestTableSize),
@@ -169,7 +166,7 @@
     .AddAttribute ("RequestIdSize","Maximum number of request source Ids in the request table.",
                    UintegerValue (16),
                    MakeUintegerAccessor (&DsrRouting::m_requestTableIds),
-                   MakeUintegerChecker<uint16_t> ())
+                   MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("UniqueRequestIdSize","Maximum number of request Ids in the request table for a single destination.",
                    UintegerValue (256),
                    MakeUintegerAccessor (&DsrRouting::m_maxRreqId),
@@ -179,9 +176,9 @@
                    MakeTimeAccessor (&DsrRouting::m_nonpropRequestTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("DiscoveryHopLimit","The max discovery hop limit for route requests.",
-                   UintegerValue (255),
-                   MakeUintegerAccessor (&DsrRouting::m_discoveryHopLimit),
-                   MakeUintegerChecker<uint8_t> ())
+                   DoubleValue (255),
+                   MakeDoubleAccessor (&DsrRouting::m_discoveryHopLimit),
+                   MakeDoubleChecker<uint32_t> ())
     .AddAttribute ("MaxSalvageCount","The max salvage count for a single data packet.",
                    UintegerValue (15),
                    MakeUintegerAccessor (&DsrRouting::m_maxSalvageCount),
@@ -199,7 +196,7 @@
                    MakeUintegerAccessor (&DsrRouting::m_broadcastJitter),
                    MakeUintegerChecker<uint16_t> ())
     .AddAttribute ("PassiveAckTimeout","The time a packet in maintenance buffer wait for passive acknowledgment.",
-                   TimeValue (MicroSeconds (4)),
+                   TimeValue (MilliSeconds (100)),
                    MakeTimeAccessor (&DsrRouting::m_passiveAckTimeout),
                    MakeTimeChecker ())
     .AddAttribute ("TryPassiveAcks","The number of passive acknowledgment to use.",
@@ -223,29 +220,45 @@
                    MakeStringAccessor (&DsrRouting::m_cacheType),
                    MakeStringChecker ())
     .AddAttribute ("StabilityDecrFactor","The stability decrease factor for link cache",
-                   DoubleValue (2.0),
-                   MakeDoubleAccessor (&DsrRouting::m_stabilityDecrFactor),
-                   MakeDoubleChecker<double> ())
+                   UintegerValue (2),
+                   MakeUintegerAccessor (&DsrRouting::m_stabilityDecrFactor),
+                   MakeUintegerChecker<uint64_t> ())
     .AddAttribute ("StabilityIncrFactor","The stability increase factor for link cache",
-                   DoubleValue (4.0),
-                   MakeDoubleAccessor (&DsrRouting::m_stabilityIncrFactor),
-                   MakeDoubleChecker<double> ())
+                   UintegerValue (4),
+                   MakeUintegerAccessor (&DsrRouting::m_stabilityIncrFactor),
+                   MakeUintegerChecker<uint64_t> ())
     .AddAttribute ("InitStability","The initial stability factor for link cache",
-                   DoubleValue (25.0),
-                   MakeDoubleAccessor (&DsrRouting::m_initStability),
-                   MakeDoubleChecker<double> ())
+                   TimeValue (Seconds (25)),
+                   MakeTimeAccessor (&DsrRouting::m_initStability),
+                   MakeTimeChecker ())
     .AddAttribute ("MinLifeTime","The minimal life time for link cache",
-                   DoubleValue (1.0),
-                   MakeDoubleAccessor (&DsrRouting::m_minLifeTime),
-                   MakeDoubleChecker<double> ())
+                   TimeValue (Seconds (1)),
+                   MakeTimeAccessor (&DsrRouting::m_minLifeTime),
+                   MakeTimeChecker ())
     .AddAttribute ("UseExtends","The extension time for link cache",
-                   DoubleValue (120.0),
-                   MakeDoubleAccessor (&DsrRouting::m_useExtends),
-                   MakeDoubleChecker<double> ())
+                   TimeValue (Seconds (120)),
+                   MakeTimeAccessor (&DsrRouting::m_useExtends),
+                   MakeTimeChecker ())
     .AddAttribute ("EnableSubRoute","Enables saving of sub route when receiving route error messages, only available when using path route cache",
                    BooleanValue (true),
                    MakeBooleanAccessor (&DsrRouting::m_subRoute),
                    MakeBooleanChecker ())
+    .AddAttribute ("RetransIncr","The increase time for retransmission timer when facing network congestion",
+                   TimeValue (MilliSeconds (20)),
+                   MakeTimeAccessor (&DsrRouting::m_retransIncr),
+                   MakeTimeChecker ())
+    .AddAttribute ("MaxNetworkQueueSize","The max number of packet to save in the network queue.",
+                   UintegerValue (400),
+                   MakeUintegerAccessor (&DsrRouting::m_maxNetworkSize),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("MaxNetworkQueueDelay","The max time for a packet to stay in the network queue.",
+                   TimeValue (Seconds (30.0)),
+                   MakeTimeAccessor (&DsrRouting::m_maxNetworkDelay),
+                   MakeTimeChecker ())
+    .AddAttribute ("NumPriorityQueues","The max number of packet to save in the network queue.",
+                   UintegerValue (2),
+                   MakeUintegerAccessor (&DsrRouting::m_numPriorityQueues),
+                   MakeUintegerChecker<uint32_t> ())
     .AddTraceSource ("Tx", "Send DSR packet.",
                      MakeTraceSourceAccessor (&DsrRouting::m_txPacketTrace))
     .AddTraceSource ("Drop", "Drop DSR packet",
@@ -283,7 +296,7 @@
 
   // Check the send buffer for sending packets
   m_sendBuffTimer.SetFunction (&DsrRouting::SendBuffTimerExpire, this);
-  m_sendBuffTimer.Schedule (Seconds (0));
+  m_sendBuffTimer.Schedule (Seconds (100));
 }
 
 DsrRouting::~DsrRouting ()
@@ -322,6 +335,24 @@
 void DsrRouting::Start ()
 {
   NS_LOG_FUNCTION (this << "Start DSR Routing protocol");
+  Ptr<dsr::RouteCache> routeCache = CreateObject<dsr::RouteCache> ();
+  // Configure the path cache parameters
+  routeCache->SetCacheType (m_cacheType);
+  routeCache->SetSubRoute (m_subRoute);
+  routeCache->SetMaxCacheLen (m_maxCacheLen);
+  routeCache->SetCacheTimeout (m_maxCacheTime);
+  routeCache->SetMaxEntriesEachDst (m_maxEntriesEachDst);
+  // Parameters for link cache
+  routeCache->SetStabilityDecrFactor (m_stabilityDecrFactor);
+  routeCache->SetStabilityIncrFactor (m_stabilityIncrFactor);
+  routeCache->SetInitStability (m_initStability);
+  routeCache->SetMinLifeTime (m_minLifeTime);
+  routeCache->SetUseExtends (m_useExtends);
+  routeCache->ScheduleTimer ();
+  // The call back to handle link error and send error message to appropriate nodes
+  routeCache->SetCallback (MakeCallback (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
+  SetRouteCache (routeCache);
+
   if (m_mainAddress == Ipv4Address ())
     {
       Ipv4Address loopback ("127.0.0.1");
@@ -329,7 +360,7 @@
         {
           // Use primary address, if multiple
           Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
-          m_broadcast = m_ipv4->GetAddress (i, 0).GetBroadcast ();
+          m_broadcast = m_ipv4->GetAddress (i, 0).GetBroadcast();
           NS_LOG_DEBUG ("The addr " << addr);
           if (addr != loopback)
             {
@@ -352,47 +383,70 @@
                 }
 
               // trace back to link mac drop event to process tx error call back
-              mac->TraceConnectWithoutContext ("TxErrHeader", m_routeCache->GetTxErrorCallback ());
-              m_routeCache->AddArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
+              mac->TraceConnectWithoutContext ("TxErrHeader", routeCache->GetTxErrorCallback ());
+              routeCache->AddArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
               break;
             }
         }
+      NS_ASSERT (m_mainAddress != Ipv4Address () && m_broadcast != Ipv4Address());
     }
 
+  NS_LOG_DEBUG ("The number queues " << m_numPriorityQueues);
+  for (uint32_t i = 0; i < m_numPriorityQueues; i++)
+  {
+    // Set the network queue max size and the delay
+    NS_LOG_DEBUG ("The network size " << m_maxNetworkSize << " and the network delay " << m_maxNetworkDelay.GetSeconds());
+    Ptr<dsr::DsrNetworkQueue> queue_i = CreateObject<dsr::DsrNetworkQueue> (m_maxNetworkSize,m_maxNetworkDelay);
+    std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator, bool> result_i = m_priorityQueue.insert (std::make_pair (i, queue_i));
+    NS_ASSERT_MSG (result_i.second, "Error in creating queues");
+  }
+  Ptr<dsr::RreqTable> rreqTable = CreateObject<dsr::RreqTable> ();
   // Set the initial hop limit
-  m_rreqTable->SetInitHopLimit (m_discoveryHopLimit);
+  rreqTable->SetInitHopLimit (m_discoveryHopLimit);
   // Configure the request table parameters
-  m_rreqTable->SetRreqTableSize (m_requestTableSize);
-  m_rreqTable->SetRreqIdSize (m_requestTableIds);
-  m_rreqTable->SetUniqueRreqIdSize (m_maxRreqId);
-  m_rreqTable->SetRreqExpire (m_maxRreqTime);
+  rreqTable->SetRreqTableSize (m_requestTableSize);
+  rreqTable->SetRreqIdSize (m_requestTableIds);
+  rreqTable->SetUniqueRreqIdSize (m_maxRreqId);
+  SetRequestTable (rreqTable);
   // Set the send buffer parameters
   m_sendBuffer.SetMaxQueueLen (m_maxSendBuffLen);
   m_sendBuffer.SetSendBufferTimeout (m_sendBufferTimeout);
+  // Set the error buffer parameters using just the send buffer parameters
+  m_errorBuffer.SetMaxQueueLen (m_maxSendBuffLen);
+  m_errorBuffer.SetErrorBufferTimeout (m_sendBufferTimeout);
   // Set the maintenance buffer parameters
   m_maintainBuffer.SetMaxQueueLen (m_maxMaintainLen);
   m_maintainBuffer.SetMaintainBufferTimeout (m_maxMaintainTime);
   // Set the gratuitous reply table size
   m_graReply.SetGraTableSize (m_graReplyTableSize);
-  // Configure the path cache parameters
-  m_routeCache->SetCacheType (m_cacheType);
-  m_routeCache->SetSubRoute (m_subRoute);
-  m_routeCache->SetMaxCacheLen (m_maxCacheLen);
-  m_routeCache->SetCacheTimeout (m_maxCacheTime);
-  m_routeCache->SetMaxEntriesEachDst (m_maxEntriesEachDst);
-  // parameters for link cache
-  m_routeCache->SetStabilityDecrFactor (m_stabilityDecrFactor);
-  m_routeCache->SetStabilityIncrFactor (m_stabilityIncrFactor);
-  m_routeCache->SetInitStability (m_initStability);
-  m_routeCache->SetMinLifeTime (m_minLifeTime);
-  m_routeCache->SetUseExtends (m_useExtends);
-  m_routeCache->ScheduleTimer ();
-  // The call back to handle link error and send error message to appropriate nodes
-  m_routeCache->SetCallback (MakeCallback (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
   NS_LOG_DEBUG ("Starting DSR on node " << m_mainAddress);
 }
 
 void
+DsrRouting::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = 0;
+  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
+    {
+      // Disable layer 2 link state monitoring (if possible)
+      Ptr<NetDevice> dev = m_ipv4->GetNetDevice (i);
+      Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
+      if (wifi != 0)
+        {
+          Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
+          if (mac != 0)
+            {
+              mac->TraceDisconnectWithoutContext ("TxErrHeader",
+                                                  m_routeCache->GetTxErrorCallback ());
+              m_routeCache->DelArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
+            }
+        }
+    }
+  Ipv4L4Protocol::DoDispose ();
+}
+
+void
 DsrRouting::SetNode (Ptr<Node> node)
 {
   m_node = node;
@@ -431,9 +485,50 @@
   return m_rreqTable;
 }
 
+bool DsrRouting::IsLinkCache ()
+{
+  return m_routeCache->IsLinkCache ();
+}
+
+void DsrRouting::UseExtends (RouteCacheEntry::IP_VECTOR rt)
+{
+  m_routeCache->UseExtends (rt);
+}
+
+bool DsrRouting::LookupRoute (Ipv4Address id, RouteCacheEntry & rt)
+{
+  return m_routeCache->LookupRoute (id, rt);
+}
+
+bool DsrRouting::AddRoute_Link (RouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source)
+{
+  Ipv4Address nextHop = SearchNextHop (source, nodelist);
+  m_errorBuffer.DropPacketForErrLink (source, nextHop);
+  return m_routeCache->AddRoute_Link (nodelist, source);
+}
+
+bool DsrRouting::AddRoute (RouteCacheEntry & rt)
+{
+  std::vector<Ipv4Address> nodelist = rt.GetVector ();
+  Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodelist);
+  m_errorBuffer.DropPacketForErrLink (m_mainAddress, nextHop);
+  return m_routeCache->AddRoute (rt);
+}
+
+void DsrRouting::DeleteAllRoutesIncludeLink (Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node)
+{
+  m_routeCache->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, node);
+}
+
+bool DsrRouting::UpdateRouteEntry (Ipv4Address dst)
+{
+  return m_routeCache->UpdateRouteEntry (dst);
+}
+
 Ipv4Address
 DsrRouting::GetIPfromMAC (Mac48Address address)
 {
+  NS_LOG_FUNCTION (this << address);
   int32_t nNodes = NodeList::GetNNodes ();
   for (int32_t i = 0; i < nNodes; ++i)
     {
@@ -451,6 +546,7 @@
 
 void DsrRouting::PrintVector (std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this);
   /*
    * Check elements in a route vector
    */
@@ -470,7 +566,9 @@
 
 Ipv4Address DsrRouting::SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
 {
+  NS_LOG_FUNCTION (this << ipv4Address);
   Ipv4Address nextHop;
+  NS_LOG_DEBUG ("the vector size " << vec.size ());
   if (vec.size () == 2)
     {
       NS_LOG_DEBUG ("The two nodes are neighbors");
@@ -484,10 +582,11 @@
           NS_LOG_DEBUG ("We have reached to the final destination " << ipv4Address << " " << vec.back ());
           return ipv4Address;
         }
-      for (std::vector<Ipv4Address>::iterator i = vec.begin (); i != vec.end (); ++i)
+      for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
         {
           if (ipv4Address == (*i))
             {
+              NS_LOG_DEBUG (ipv4Address << " and " << *i);
               nextHop = *(++i);
               return nextHop;
             }
@@ -509,21 +608,6 @@
   return m_ipv4Route;
 }
 
-void
-DsrRouting::CutRoute (Ipv4Address ourAdd, std::vector<Ipv4Address>& nodeList)
-{
-  NS_LOG_FUNCTION (this << ourAdd);
-  std::vector<Ipv4Address> newRoute = nodeList;
-  nodeList.clear ();
-
-  std::vector<Ipv4Address>::iterator it = find (newRoute.begin (), newRoute.end (), ourAdd);
-
-  for (std::vector<Ipv4Address>::iterator i = it; i != newRoute.end (); ++i)
-    {
-      nodeList.push_back (*i);
-    }
-}
-
 int
 DsrRouting::GetProtocolNumber (void) const
 {
@@ -531,15 +615,7 @@
   return PROT_NUMBER;
 }
 
-void
-DsrRouting::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = 0;
-  Ipv4L4Protocol::DoDispose ();
-}
-
-uint32_t
+uint16_t
 DsrRouting::GetIDfromIP (Ipv4Address address)
 {
   int32_t nNodes = NodeList::GetNNodes ();
@@ -549,28 +625,41 @@
       Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
       if (ipv4->GetAddress (1, 0).GetLocal () == address)
         {
-          return i;
+          return uint16_t(i);
         }
     }
-  return 255;
+  return 256;
 }
 
 Ipv4Address
-DsrRouting::GetIPfromID (uint32_t id)
+DsrRouting::GetIPfromID (uint16_t id)
 {
-  if (id >= 255)
+  if (id >= 256)
     {
       NS_LOG_DEBUG ("Exceed the node range");
       return "0.0.0.0";
     }
   else
     {
-      Ptr<Node> node = NodeList::GetNode (id);
+      Ptr<Node> node = NodeList::GetNode (uint32_t (id));
       Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
       return ipv4->GetAddress (1, 0).GetLocal ();
     }
 }
 
+uint32_t
+DsrRouting::GetPriority (DsrMessageType messageType)
+{
+  if (messageType == DSR_CONTROL_PACKET)
+    {
+      return 0;
+    }
+  else
+    {
+      return 1;
+    }
+}
+
 void DsrRouting::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop, uint8_t protocol)
 {
   NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
@@ -585,7 +674,7 @@
           NS_LOG_DEBUG ("creating new packet");
           /*
            * Copy the packet and save a copy to the send buffer.
-           * For some reason, when queue the original packet to the buffer,
+           * if only queue the original packet to the buffer,
            * when dequeue the packet, it turns to be empty.
            */
           Ptr<Packet> dequeP = ConstCast<Packet> (entry.GetPacket ());
@@ -595,8 +684,12 @@
           Ipv4Address source = entry.GetSrc ();
           Ipv4Address destination = entry.GetDst ();
 
+          // Send the data packet out before schedule the next packet transmission
+          SendPacket (dequeP, source, nextHop, protocol);
+
           DsrRoutingHeader dsrRoutingHeader;
           p->RemoveHeader (dsrRoutingHeader);
+          Ptr<Packet> cleanP = p->Copy ();
           uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
           newPacket->RemoveAtStart (offset);
 
@@ -610,17 +703,19 @@
           newPacket->RemoveHeader (sourceRoute);
           uint8_t salvage = sourceRoute.GetSalvage ();
 
+          // TODO
           DsrOptionAckReqHeader ackReq;
           newPacket->RemoveHeader (ackReq);
           /*
            * Get the node list address
            */
           std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
-          Ipv4Address address1 = nodeList.front ();
+          Ipv4Address address1 = nodeList[1];
           Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);
           NS_LOG_DEBUG ("The next hop address" << nextHop);
           if (nextHop == "0.0.0.0")
             {
+              PacketNewRoute (cleanP, m_mainAddress, destination, protocol);
               return;
             }
           RouteCacheEntry salvageRoute;
@@ -639,14 +734,32 @@
                 {
                   m_routeCache->UseExtends (nodeList);
                 }
-              PacketKey packetKey;
-              packetKey.m_ackId = entry.GetAckId ();
-              packetKey.m_ourAdd = entry.GetOurAdd ();
-              packetKey.m_nextHop = entry.GetNextHop ();
-              packetKey.m_source = entry.GetSrc ();
-              packetKey.m_destination = entry.GetDst ();
-              packetKey.m_segsLeft = entry.GetSegsLeft ();
-              SchedulePacketRetry (entry, packetKey, protocol);
+
+              NetworkKey networkKey;
+              networkKey.m_ackId = entry.GetAckId ();
+              networkKey.m_ourAdd = entry.GetOurAdd ();
+              networkKey.m_nextHop = entry.GetNextHop ();
+              networkKey.m_source = entry.GetSrc ();
+              networkKey.m_destination = entry.GetDst ();
+
+              PassiveKey passiveKey;
+              passiveKey.m_ackId = 0;
+              passiveKey.m_source = entry.GetSrc ();
+              passiveKey.m_destination = entry.GetDst ();
+              passiveKey.m_segsLeft = entry.GetSegsLeft ();
+
+              m_addressForwardCnt[networkKey] = 0;
+              m_passiveCnt[passiveKey] = 0;
+
+              if (nextHop != destination)
+                {
+                  SchedulePassivePacketRetry (entry, false, protocol);
+                }
+              else
+                {
+                  // This is the first network retry
+                  ScheduleNetworkPacketRetry (entry, true, protocol);
+                }
             }
           else
             {
@@ -654,45 +767,24 @@
                * This code block create a packet and attach a route error option to it
                */
               m_routeCache->DeleteAllRoutesIncludeLink (source, nextHop, m_mainAddress);
-
               /*
                * If the salvage is not 0, use the first address in the route as the error dst in error header
                * otherwise use the source of packet as the error destination
                */
+              Ipv4Address errorDst;
               if (salvage)
                 {
-                  if (address1 == m_mainAddress)
-                    {
-                      DsrOptionRerrUnreachHeader rerr;
-                      rerr.SetErrorType (1);
-                      rerr.SetErrorSrc (address1);
-                      rerr.SetUnreachNode (nextHop);
-                      rerr.SetErrorDst (address1);
-                      rerr.SetSalvage (salvage);       // Set the value about whether to salvage a packet or not
-                      SendErrorRequest (rerr, protocol);
-                    }
-                  else
-                    {
-                      SendUnreachError (nextHop, address1, salvage, protocol);
-                    }
+                  errorDst = address1;
                 }
               else
                 {
-                  if (source == m_mainAddress)
-                    {
-                      DsrOptionRerrUnreachHeader rerr;
-                      rerr.SetErrorType (1);
-                      rerr.SetErrorSrc (source);
-                      rerr.SetUnreachNode (nextHop);
-                      rerr.SetErrorDst (source);
-                      rerr.SetSalvage (salvage);     // Set the value about whether to salvage a packet or not
-                      SendErrorRequest (rerr, protocol);
-                    }
-                  else
-                    {
-                      SendUnreachError (nextHop, source, salvage, protocol);
-                    }
+                  errorDst = source;
                 }
+              SendUnreachError (nextHop, errorDst, destination, salvage, protocol);
+              /*
+               * here we cancel the packet retransmission time for all the packets have next hop address
+               * as nextHop
+               */
             }
           if (m_maintainBuffer.GetSize () != 0 && m_maintainBuffer.Find (nextHop))
             {
@@ -735,6 +827,8 @@
 
           DsrRoutingHeader dsrRoutingHeader;
           Ptr<Packet> copyP = packet->Copy ();
+          Ptr<Packet> dsrPacket = packet->Copy ();
+          dsrPacket->RemoveHeader (dsrRoutingHeader);
           uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
           copyP->RemoveAtStart (offset); // Here the processed size is 8 bytes, which is the fixed sized extension header
           // The packet to get ipv4 header
@@ -782,6 +876,7 @@
 
                   if (nextHop == "0.0.0.0")
                     {
+                      PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
                       return;
                     }
 
@@ -791,7 +886,7 @@
                   dsrRoutingHeader.SetMessageType (1);
                   dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
                   dsrRoutingHeader.SetDestId (255);
-                  dsrRoutingHeader.SetPayloadLength (length + 4);
+                  dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 4);
                   dsrRoutingHeader.AddDsrOption (newUnreach);
                   dsrRoutingHeader.AddDsrOption (sourceRoute);
 
@@ -799,7 +894,22 @@
                   newPacket->AddHeader (dsrRoutingHeader); // Add the routing header with rerr and sourceRoute attached to it
                   Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
                   m_ipv4Route->SetOutputDevice (dev);
-                  m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+                  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+                  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+                  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+                  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+                  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+
+                  if (dsrNetworkQueue->Enqueue (newEntry))
+                    {
+                      Scheduler (priority);
+                    }
+                  else
+                    {
+                      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+                    }
                 }
             }
           else
@@ -814,7 +924,7 @@
               Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);  // Get the next hop address for the route
               if (nextHop == "0.0.0.0")
                 {
-                  PacketNewRoute (cleanP, m_mainAddress, destination, protocol);
+                  PacketNewRoute (dsrPacket, m_mainAddress, destination, protocol);
                   return;
                 }
               uint8_t salvage = 0;
@@ -822,43 +932,52 @@
               sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
               sourceRoute.SetSalvage (salvage);
 
-              DsrOptionAckReqHeader ackReq;
-              m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-              ackReq.SetAckId (m_ackId);
-
-              uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-              NS_LOG_DEBUG ("the length of source route header " << (uint32_t)(sourceRoute.GetLength ()));
-              NS_LOG_DEBUG ("the length of ack request header " << (uint32_t)(ackReq.GetLength ()));
-
-              dsrRoutingHeader.SetPayloadLength (length + 4);
+              uint8_t length = sourceRoute.GetLength ();
+              dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
               dsrRoutingHeader.AddDsrOption (sourceRoute);
-              dsrRoutingHeader.AddDsrOption (ackReq);
               cleanP->AddHeader (dsrRoutingHeader);
+              // Send the data packet out before schedule the next packet transmission
+              SendPacket (cleanP, m_mainAddress, nextHop, protocol);
               Ptr<const Packet> mtP = cleanP->Copy ();
               // Put the data packet in the maintenance queue for data packet retransmission
               MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
-                                                      /*source=*/ m_mainAddress, /*destination=*/ destination, /*ackId=*/ m_ackId,
-                                                      /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
+                                          /*source=*/ m_mainAddress, /*destination=*/ destination, /*ackId=*/ 0,
+                                          /*SegsLeft=*/nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
               bool result = m_maintainBuffer.Enqueue (newEntry); // Enqueue the packet the the maintenance buffer
               if (result)
                 {
-                  Ptr<Packet> newPacket = cleanP->Copy ();
-                  PacketKey packetKey;
-                  packetKey.m_ackId = newEntry.GetAckId ();
-                  packetKey.m_ourAdd = newEntry.GetOurAdd ();
-                  packetKey.m_nextHop = newEntry.GetNextHop ();
-                  packetKey.m_source = newEntry.GetSrc ();
-                  packetKey.m_destination = newEntry.GetDst ();
-                  packetKey.m_segsLeft = newEntry.GetSegsLeft ();
-                  SchedulePacketRetry (newEntry, packetKey, protocol);
+                  NetworkKey networkKey;
+                  networkKey.m_ackId = newEntry.GetAckId ();
+                  networkKey.m_ourAdd = newEntry.GetOurAdd ();
+                  networkKey.m_nextHop = newEntry.GetNextHop ();
+                  networkKey.m_source = newEntry.GetSrc ();
+                  networkKey.m_destination = newEntry.GetDst ();
+
+                  PassiveKey passiveKey;
+                  passiveKey.m_ackId = 0;
+                  passiveKey.m_source = newEntry.GetSrc ();
+                  passiveKey.m_destination = newEntry.GetDst ();
+                  passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
+
+                  m_addressForwardCnt[networkKey] = 0;
+                  m_passiveCnt[passiveKey] = 0;
+                  if (nextHop != destination)
+                    {
+                      SchedulePassivePacketRetry (newEntry, false, protocol);
+                    }
+                  else
+                    {
+                      // This is the first network retry
+                      ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                    }
                 }
-              //we need to suspend the normal timer that checks the send buffer
-              //until we are done sending packets
+              // we need to suspend the normal timer that checks the send buffer
+              // until we are done sending packets
               if (!m_sendBuffTimer.IsSuspended ())
                 {
                   m_sendBuffTimer.Suspend ();
                 }
-              Simulator::Schedule (m_sendBuffInterval, &DsrRouting::CheckSendBuffer, this);
+              Simulator::Schedule (m_sendBuffInterval, &DsrRouting::SendBuffTimerExpire, this);
               return;
             }
         }
@@ -996,41 +1115,54 @@
       sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));     // The segmentsLeft field will indicate the hops to go
       sourceRoute.SetSalvage (salvage);
 
-      DsrOptionAckReqHeader ackReq;
-      m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-      ackReq.SetAckId (m_ackId);
-
-      uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-      dsrRoutingHeader.SetPayloadLength (length + 4);
+      uint8_t length = sourceRoute.GetLength ();
+      dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
       dsrRoutingHeader.AddDsrOption (sourceRoute);
-      dsrRoutingHeader.AddDsrOption (ackReq);
       cleanP->AddHeader (dsrRoutingHeader);
+      // Send the data packet out before schedule the next packet transmission
+      SendPacket (cleanP, source, nextHop, protocol);
       Ptr<const Packet> mtP = cleanP->Copy ();
       SetRoute (nextHop, m_mainAddress);
       // Put the data packet in the maintenance queue for data packet retransmission
       MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
-                                              /*source=*/ source, /*destination=*/ destination, /*ackId=*/ m_ackId,
-                                              /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
+                                              /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
+                                              /*SegsLeft=*/nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
       bool result = m_maintainBuffer.Enqueue (newEntry);     // Enqueue the packet the the maintenance buffer
 
       if (result)
         {
-          PacketKey packetKey;
-          packetKey.m_ackId = newEntry.GetAckId ();
-          packetKey.m_ourAdd = newEntry.GetOurAdd ();
-          packetKey.m_nextHop = newEntry.GetNextHop ();
-          packetKey.m_source = newEntry.GetSrc ();
-          packetKey.m_destination = newEntry.GetDst ();
-          packetKey.m_segsLeft = newEntry.GetSegsLeft ();
-          SchedulePacketRetry (newEntry, packetKey, protocol);
+          NetworkKey networkKey;
+          networkKey.m_ackId = newEntry.GetAckId ();
+          networkKey.m_ourAdd = newEntry.GetOurAdd ();
+          networkKey.m_nextHop = newEntry.GetNextHop ();
+          networkKey.m_source = newEntry.GetSrc ();
+          networkKey.m_destination = newEntry.GetDst ();
+
+          PassiveKey passiveKey;
+          passiveKey.m_ackId = 0;
+          passiveKey.m_source = newEntry.GetSrc ();
+          passiveKey.m_destination = newEntry.GetDst ();
+          passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
+
+          m_addressForwardCnt[networkKey] = 0;
+          m_passiveCnt[passiveKey] = 0;
+          if (nextHop != destination)
+            {
+              SchedulePassivePacketRetry (newEntry, false, protocol);
+            }
+          else
+            {
+              // This is the first network retry
+              ScheduleNetworkPacketRetry (newEntry, true, protocol);
+            }
         }
     }
 }
 
 void
-DsrRouting::SendUnreachError (Ipv4Address errorHop, Ipv4Address destination, uint8_t salvage, uint8_t protocol)
+DsrRouting::SendUnreachError (Ipv4Address errorHop, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << errorHop << destination << (uint32_t)salvage << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << errorHop << destination << originalDst << (uint32_t)salvage << (uint32_t)protocol);
   DsrRoutingHeader dsrRoutingHeader;
   dsrRoutingHeader.SetNextHeader (protocol);
   dsrRoutingHeader.SetMessageType (1);
@@ -1042,12 +1174,14 @@
   rerrUnreachHeader.SetErrorSrc (m_mainAddress);
   rerrUnreachHeader.SetUnreachNode (errorHop);
   rerrUnreachHeader.SetErrorDst (destination);
-  rerrUnreachHeader.SetSalvage (salvage);     // Set the value about whether to salvage a packet or not
+  rerrUnreachHeader.SetOriginalDst (originalDst);
+  rerrUnreachHeader.SetSalvage (salvage);                       // Set the value about whether to salvage a packet or not
   uint8_t rerrLength = rerrUnreachHeader.GetLength ();
 
   RouteCacheEntry toDst;
   bool findRoute = m_routeCache->LookupRoute (destination, toDst);
   // Queue the packet if there is no route pre-existing
+  Ptr<Packet> newPacket = Create<Packet> ();
   if (!findRoute)
     {
       NS_LOG_INFO (Simulator::Now ().GetSeconds ()
@@ -1055,12 +1189,11 @@
 
       dsrRoutingHeader.SetPayloadLength (rerrLength + 2);
       dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
-      Ptr<Packet> newPacket = Create<Packet> ();
       newPacket->AddHeader (dsrRoutingHeader);
       Ptr<Packet> p = newPacket->Copy ();
-      SendBuffEntry newEntry (p, destination, m_sendBufferTimeout);
-      newEntry.SetErrHeader (true);        // Note it as an error packet
-      bool result = m_sendBuffer.Enqueue (newEntry);     // Enqueue the packet in send buffer
+      // Save the error packet in the error buffer
+      ErrorBuffEntry newEntry (p, destination, m_mainAddress, errorHop, m_sendBufferTimeout, protocol);
+      bool result = m_errorBuffer.Enqueue (newEntry);                    // Enqueue the packet in send buffer
       if (result)
         {
           NS_LOG_INFO (Simulator::Now ().GetSeconds ()
@@ -1082,6 +1215,8 @@
       Ipv4Address nextHop = SearchNextHop (m_mainAddress, nodeList);
       if (nextHop == "0.0.0.0")
         {
+          NS_LOG_DEBUG ("The route is not right");
+          PacketNewRoute (newPacket, m_mainAddress, destination, protocol);
           return;
         }
       DsrOptionSRHeader sourceRoute;
@@ -1094,17 +1229,31 @@
       uint8_t srLength = sourceRoute.GetLength ();
       uint8_t length = (srLength + rerrLength);
 
-      dsrRoutingHeader.SetNextHeader (protocol);
-      dsrRoutingHeader.SetPayloadLength (length + 4);
+      dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 4);
       dsrRoutingHeader.AddDsrOption (rerrUnreachHeader);
       dsrRoutingHeader.AddDsrOption (sourceRoute);
-      Ptr<Packet> newPacket = Create<Packet> ();
       newPacket->AddHeader (dsrRoutingHeader);
 
       SetRoute (nextHop, m_mainAddress);
       Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
       m_ipv4Route->SetOutputDevice (dev);
-      m_downTarget (newPacket, m_mainAddress, nextHop, protocol, m_ipv4Route);
+      NS_LOG_INFO ("Send the packet to the next hop address " << nextHop << " from " << m_mainAddress << " with the size " << newPacket->GetSize());
+
+      uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+      std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+      Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+      NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+      DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+
+      if (dsrNetworkQueue->Enqueue (newEntry))
+        {
+          Scheduler (priority);
+        }
+      else
+        {
+          NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+        }
     }
 }
 
@@ -1124,14 +1273,29 @@
   dsrRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
 
   uint8_t length = (sourceRoute.GetLength () + rerr.GetLength ());
-  dsrRoutingHeader.SetPayloadLength (length + 4);
+  dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 4);
   dsrRoutingHeader.AddDsrOption (rerr);
   dsrRoutingHeader.AddDsrOption (sourceRoute);
   Ptr<Packet> packet = Create<Packet> ();
   packet->AddHeader (dsrRoutingHeader);
   Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
   route->SetOutputDevice (dev);
-  m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
+
+  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+   DsrNetworkQueueEntry newEntry (packet, m_mainAddress, nextHop, Simulator::Now (), route);
+
+  if (dsrNetworkQueue->Enqueue (newEntry))
+    {
+      Scheduler (priority);
+    }
+  else
+    {
+      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+    }
 }
 
 void
@@ -1160,7 +1324,6 @@
                        << "s " << m_mainAddress << " there is no route for this packet, queue the packet");
 
           Ptr<Packet> p = packet->Copy ();
-          m_newPacketSize = packet->GetSize ();
           SendBuffEntry newEntry (p, destination, m_sendBufferTimeout, protocol);     // Create a new entry for send buffer
           bool result = m_sendBuffer.Enqueue (newEntry);     // Enqueue the packet in send buffer
           if (result)
@@ -1177,6 +1340,10 @@
                    */
                   SendInitialRequest (source, destination, protocol);
                 }
+              else
+                {
+                  NS_LOG_DEBUG ("There is existing route request timer and the request count here " << m_rreqTable->GetRreqCnt (destination));
+                }
             }
         }
       else
@@ -1205,53 +1372,245 @@
           sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));       // The segmentsLeft field will indicate the hops to go
           sourceRoute.SetSalvage (salvage);
 
-          DsrOptionAckReqHeader ackReq;
-          m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-          ackReq.SetAckId (m_ackId);
+          uint8_t length = sourceRoute.GetLength ();
 
-          uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-
-          dsrRoutingHeader.SetPayloadLength (length + 4);
+          dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
           dsrRoutingHeader.AddDsrOption (sourceRoute);
-          dsrRoutingHeader.AddDsrOption (ackReq);
           cleanP->AddHeader (dsrRoutingHeader);
+          // Send the data packet out before schedule the next packet transmission
+          SendPacket (cleanP, source, nextHop, protocol);
 
           Ptr<const Packet> mtP = cleanP->Copy ();
+          NS_LOG_DEBUG ("maintain packet size " << cleanP->GetSize());
           // Put the data packet in the maintenance queue for data packet retransmission
           MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
-                                                  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ m_ackId,
-                                                  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
+                                      /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
+                                      /*SegsLeft=*/nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
           bool result = m_maintainBuffer.Enqueue (newEntry);       // Enqueue the packet the the maintenance buffer
           if (result)
             {
-              Ptr<Packet> newPacket = cleanP->Copy ();
-              /*
-               * Schedule the packet retransmission
-               */
-              PacketKey packetKey;
-              packetKey.m_ackId = newEntry.GetAckId ();
-              packetKey.m_ourAdd = newEntry.GetOurAdd ();
-              packetKey.m_nextHop = newEntry.GetNextHop ();
-              packetKey.m_source = newEntry.GetSrc ();
-              packetKey.m_destination = newEntry.GetDst ();
-              packetKey.m_segsLeft = newEntry.GetSegsLeft ();
-              PacketKey networkKey = packetKey;
-              networkKey.m_segsLeft = 0;
+              NetworkKey networkKey;
+              networkKey.m_ackId = newEntry.GetAckId ();
+              networkKey.m_ourAdd = newEntry.GetOurAdd ();
+              networkKey.m_nextHop = newEntry.GetNextHop ();
+              networkKey.m_source = newEntry.GetSrc ();
+              networkKey.m_destination = newEntry.GetDst ();
+
+              PassiveKey passiveKey;
+              passiveKey.m_ackId = 0;
+              passiveKey.m_source = newEntry.GetSrc ();
+              passiveKey.m_destination = newEntry.GetDst ();
+              passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
+
               m_addressForwardCnt[networkKey] = 0;
-              SchedulePacketRetry (newEntry, packetKey, protocol);
+              m_passiveCnt[passiveKey] = 0;
+              if (nextHop != destination)
+                {
+                  SchedulePassivePacketRetry (newEntry, false, protocol);
+                }
+              else
+                {
+                  // This is the first network retry
+                  ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                }
             }
           // Try to send packet from *previously* queued entries from send buffer if any
-          SendPacket (sourceRoute, nextHop, protocol);
+          Simulator::Schedule (MilliSeconds (UniformVariable ().GetInteger (0,100)),
+                               &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
         }
     }
 }
 
+uint16_t
+DsrRouting::AddAckReqHeader (Ptr<Packet>& packet, Ipv4Address nextHop)
+{
+  NS_LOG_FUNCTION (this << packet << nextHop);
+  // This packet is used to peek option type
+  Ptr<Packet> dsrP = packet->Copy ();
+  Ptr<Packet> tmpP = packet->Copy ();
+
+  DsrRoutingHeader dsrRoutingHeader;
+  dsrP->RemoveHeader (dsrRoutingHeader);          // Remove the DSR header in whole
+  uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
+  uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
+  uint32_t destinationId = dsrRoutingHeader.GetDestId ();
+  uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
+  tmpP->RemoveAtStart (offset);       // Here the processed size is 8 bytes, which is the fixed sized extension header
+
+  // Get the number of routers' address field
+  uint8_t buf[2];
+  tmpP->CopyData (buf, sizeof(buf));
+  uint8_t numberAddress = (buf[1] - 2) / 4;
+  DsrOptionSRHeader sourceRoute;
+  sourceRoute.SetNumberAddress (numberAddress);
+  tmpP->RemoveHeader (sourceRoute);               // this is a clean packet without any dsr involved headers
+
+  DsrOptionAckReqHeader ackReq;
+  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
+  ackReq.SetAckId (m_ackId);
+
+  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
+  DsrRoutingHeader newDsrRoutingHeader;
+  newDsrRoutingHeader.SetNextHeader (protocol);
+  newDsrRoutingHeader.SetMessageType (2);
+  newDsrRoutingHeader.SetSourceId (sourceId);
+  newDsrRoutingHeader.SetDestId (destinationId);
+  newDsrRoutingHeader.SetPayloadLength (length + 4);
+  newDsrRoutingHeader.AddDsrOption (sourceRoute);
+  newDsrRoutingHeader.AddDsrOption (ackReq);
+  dsrP->AddHeader (newDsrRoutingHeader);
+  // give the dsrP value to packet and then return
+  packet = dsrP;
+  return m_ackId;
+}
+
 void
-DsrRouting::SendPacket (DsrOptionSRHeader const &sourceRoute,
-                        Ipv4Address nextHop,
-                        uint8_t protocol)
+DsrRouting::SendPacket (Ptr<Packet> packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol)
+{
+  NS_LOG_FUNCTION (this << packet << source << nextHop << (uint32_t)protocol);
+  // Send out the data packet
+  m_ipv4Route = SetRoute (nextHop, m_mainAddress);
+  Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
+  m_ipv4Route->SetOutputDevice (dev);
+
+  uint32_t priority = GetPriority (DSR_DATA_PACKET);
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), m_ipv4Route);
+
+  if (dsrNetworkQueue->Enqueue (newEntry))
+    {
+      Scheduler (priority);
+    }
+  else
+    {
+      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+    }
+}
+
+void
+DsrRouting::Scheduler (uint32_t priority)
+{
+  NS_LOG_FUNCTION (this);
+  PriorityScheduler (priority, true);
+}
+
+void
+DsrRouting::PriorityScheduler (uint32_t priority, bool continueWithFirst)
 {
-  NS_LOG_FUNCTION (this << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << priority << continueWithFirst);
+  NS_LOG_DEBUG ("Scheduler looking for packets in network queue");
+  uint32_t numPriorities;
+  if (continueWithFirst)
+    {
+      numPriorities = 0;
+    }
+  else
+    {
+      numPriorities = priority;
+    }
+  // priorities range from 0 to m_numPriorityQueues, with 0 as the highest priority
+  for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
+  {
+    std::map<uint32_t, Ptr<DsrNetworkQueue> >::iterator q = m_priorityQueue.find (i);
+    Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = q->second;
+    uint32_t queueSize = dsrNetworkQueue->GetSize ();
+    if (queueSize == 0)
+    {
+      if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
+      {
+        i = 0;
+      }
+      else
+      {
+        i++;
+      }
+    }
+    else
+    {
+      uint32_t totalQueueSize;
+      for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator j = m_priorityQueue.begin (); j != m_priorityQueue.end (); j++)
+        {
+          NS_LOG_DEBUG ("The size of the network queue for " << j->first << " is " << j->second->GetSize());
+          totalQueueSize += j->second->GetSize ();
+          NS_LOG_DEBUG ("And the total size is " << totalQueueSize);
+        }
+      if (totalQueueSize > 5)
+        {
+          // Here the queue size is larger than 5, we need to increase the retransmission timer for each packet in the network queue
+          IncreaseRetransTimer ();
+        }
+      DsrNetworkQueueEntry newEntry;
+      dsrNetworkQueue->Dequeue (newEntry);
+      if (SendRealDown (newEntry))
+      {
+        NS_LOG_DEBUG("Packet sent by Dsr. Calling PriorityScheduler after some time");
+        //packet was successfully sent down. call scheduler after some time
+        Simulator::Schedule (MicroSeconds (UniformVariable ().GetInteger (0, 1000)),
+            &DsrRouting::PriorityScheduler,this, i, false);
+      }
+      else
+      {
+        // packet was dropped by Dsr. Call scheduler immediately so that we can
+        // send another packet immediately.
+        NS_LOG_DEBUG("Packet dropped by Dsr. Calling PriorityScheduler immediately");
+        Simulator::Schedule (Seconds (0), &DsrRouting::PriorityScheduler, this, i, false);
+      }
+      if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
+      {
+        i = 0;
+      }
+      else
+      {
+        i++;
+      }
+    }
+  }
+}
+
+void
+DsrRouting::IncreaseRetransTimer ()
+{
+  NS_LOG_FUNCTION (this);
+  // We may want to get the queue first and then we need to save a vector of the entries here and then find
+  uint32_t priority = GetPriority (DSR_DATA_PACKET);
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+
+  std::vector<DsrNetworkQueueEntry> newNetworkQueue = dsrNetworkQueue->GetQueue ();
+  for (std::vector<DsrNetworkQueueEntry>::iterator i = newNetworkQueue.begin (); i != newNetworkQueue.end (); i++)
+    {
+      Ipv4Address nextHop = i->GetNextHopAddress ();
+      for (std::map<NetworkKey, Timer>::iterator j = m_addressForwardTimer.begin (); j != m_addressForwardTimer.end (); j++)
+        {
+          if (nextHop == j->first.m_nextHop)
+            {
+              NS_LOG_DEBUG ("The network delay left is " << j->second.GetDelayLeft());
+              j->second.SetDelay (j->second.GetDelayLeft () + m_retransIncr);
+              NS_LOG_DEBUG ("The new network delay time is " << j->second.GetDelayLeft ());
+            }
+        }
+    }
+}
+
+bool
+DsrRouting::SendRealDown (DsrNetworkQueueEntry & newEntry)
+{
+  NS_LOG_FUNCTION (this);
+  Ipv4Address source = newEntry.GetSourceAddress ();
+  Ipv4Address nextHop = newEntry.GetNextHopAddress ();
+  Ptr<Packet> packet = newEntry.GetPacket ()->Copy ();
+  Ptr<Ipv4Route> route = newEntry.GetIpv4Route ();
+  m_downTarget (packet, source, nextHop, GetProtocolNumber(), route);
+  return true;
+}
+
+void
+DsrRouting::SendPacketFromBuffer (DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop, uint8_t protocol)
+{
+  NS_LOG_FUNCTION (this << nextHop << (uint32_t)protocol);
   NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
 
   // Reconstruct the route and Retransmit the data packet
@@ -1261,6 +1620,9 @@
 
   NS_LOG_INFO ("The nexthop address " << nextHop << " the source " << source << " the destination " << destination);
 
+  /*
+   * Here we try to find data packet from send buffer, if packet with this destiantion found, send it out
+   */
   if (m_sendBuffer.Find (destination))
     {
       SendBuffEntry entry;
@@ -1269,8 +1631,86 @@
           Ptr<Packet> packet = entry.GetPacket ()->Copy ();
           NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
 
+          NS_LOG_DEBUG ("This is the data packet");
+          Ptr<Packet> p = packet->Copy ();      // get a copy of the packet
+          // Set the source route option
+          DsrRoutingHeader dsrRoutingHeader;
+          dsrRoutingHeader.SetNextHeader (protocol);
+          dsrRoutingHeader.SetMessageType (2);
+          dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
+          dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
+
+          uint8_t length = sourceRoute.GetLength ();
+          dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
+          dsrRoutingHeader.AddDsrOption (sourceRoute);
+
+          p->AddHeader (dsrRoutingHeader);
+          // Send the data packet out before schedule the next packet transmission
+          NS_LOG_DEBUG ("Send out the data packet");
+          SendPacket (p, source, nextHop, protocol);
+
+          Ptr<const Packet> mtP = p->Copy ();
+          // Put the data packet in the maintenance queue for data packet retransmission
+          MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
+                                                  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
+                                                  /*SegsLeft=*/nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
+          bool result = m_maintainBuffer.Enqueue (newEntry);       // Enqueue the packet the the maintenance buffer
+
+          if (result)
+            {
+              NetworkKey networkKey;
+              networkKey.m_ackId = newEntry.GetAckId ();
+              networkKey.m_ourAdd = newEntry.GetOurAdd ();
+              networkKey.m_nextHop = newEntry.GetNextHop ();
+              networkKey.m_source = newEntry.GetSrc ();
+              networkKey.m_destination = newEntry.GetDst ();
+
+              PassiveKey passiveKey;
+              passiveKey.m_ackId = 0;
+              passiveKey.m_source = newEntry.GetSrc ();
+              passiveKey.m_destination = newEntry.GetDst ();
+              passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
+
+              m_addressForwardCnt[networkKey] = 0;
+              m_passiveCnt[passiveKey] = 0;
+              if (nextHop != destination)
+                {
+                  SchedulePassivePacketRetry (newEntry, false, protocol);
+                }
+              else
+                {
+                  // This is the first network retry
+                  ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                }
+            }
+
+          if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
+            {
+              NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
+              Simulator::Schedule (MilliSeconds (UniformVariable ().GetInteger (0,100)),
+                                   &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
+            }
+        }
+      else
+        {
+          NS_LOG_DEBUG ("All queued packets are out-dated for the destination in send buffer");
+        }
+    }
+  /*
+   * Here we try to find data packet from send buffer, if packet with this destiantion found, send it out
+   */
+  else if (m_errorBuffer.Find (destination))
+    {
+      ErrorBuffEntry entry;
+      if (m_errorBuffer.Dequeue (destination, entry))
+        {
+          Ptr<Packet> packet = entry.GetPacket ()->Copy ();
+          NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
+
           DsrRoutingHeader dsrRoutingHeader;
           Ptr<Packet> copyP = packet->Copy ();
+          Ptr<Packet> dsrPacket = packet->Copy ();
+          dsrPacket->RemoveHeader (dsrRoutingHeader);
           uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
           copyP->RemoveAtStart (offset);       // Here the processed size is 8 bytes, which is the fixed sized extension header
           /*
@@ -1282,14 +1722,18 @@
 
           uint8_t optionType = 0;
           optionType = *(data);
+          NS_LOG_DEBUG ("The option type value in send packet " << (uint32_t)optionType);
           if (optionType == 3)
             {
+              NS_LOG_DEBUG ("The packet is error packet");
               Ptr<dsr::DsrOptions> dsrOption;
               DsrOptionHeader dsrOptionHeader;
 
               uint8_t errorType = *(data + 2);
+              NS_LOG_DEBUG ("The error type");
               if (errorType == 1)
                 {
+                  NS_LOG_DEBUG ("The packet is route error unreach packet");
                   DsrOptionRerrUnreachHeader rerr;
                   copyP->RemoveHeader (rerr);
                   NS_ASSERT (copyP->GetSize () == 0);
@@ -1300,6 +1744,7 @@
                   newUnreach.SetErrorSrc (rerr.GetErrorSrc ());
                   newUnreach.SetUnreachNode (rerr.GetUnreachNode ());
                   newUnreach.SetErrorDst (rerr.GetErrorDst ());
+                  newUnreach.SetOriginalDst (rerr.GetOriginalDst ());
                   newUnreach.SetSalvage (rerr.GetSalvage ());       // Set the value about whether to salvage a packet or not
 
                   std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
@@ -1308,7 +1753,7 @@
                   newRoutingHeader.SetMessageType (1);
                   newRoutingHeader.SetSourceId (GetIDfromIP (rerr.GetErrorSrc ()));
                   newRoutingHeader.SetDestId (GetIDfromIP (rerr.GetErrorDst ()));
-                  newRoutingHeader.SetPayloadLength (length + 4);
+                  newRoutingHeader.SetPayloadLength (uint16_t(length) + 4);
                   newRoutingHeader.AddDsrOption (newUnreach);
                   newRoutingHeader.AddDsrOption (sourceRoute);
                   if (m_routeCache->IsLinkCache ())
@@ -1320,90 +1765,62 @@
                   newPacket->AddHeader (newRoutingHeader);       // Add the extension header with rerr and sourceRoute attached to it
                   Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
                   m_ipv4Route->SetOutputDevice (dev);
-                  m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
-                }
-            }
-          else
-            {
-              Ptr<Packet> p = packet->Copy ();      // get a copy of the packet
-              // Set the source route option
-              dsrRoutingHeader.SetNextHeader (protocol);
-              dsrRoutingHeader.SetMessageType (2);
-              dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
-              dsrRoutingHeader.SetDestId (GetIDfromIP (destination));
 
-              DsrOptionAckReqHeader ackReq;
-              m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-              ackReq.SetAckId (m_ackId);
+                  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+                  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+                  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+                  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
 
-              uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-              dsrRoutingHeader.SetPayloadLength (length + 4);
-              dsrRoutingHeader.AddDsrOption (sourceRoute);
-              dsrRoutingHeader.AddDsrOption (ackReq);
+                  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
 
-              p->AddHeader (dsrRoutingHeader);
-              Ptr<const Packet> mtP = p->Copy ();
-              // Put the data packet in the maintenance queue for data packet retransmission
-              MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
-                                                      /*source=*/ source, /*destination=*/ destination, /*ackId=*/ m_ackId,
-                                                      /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
-              bool result = m_maintainBuffer.Enqueue (newEntry);       // Enqueue the packet the the maintenance buffer
-
-              if (result)
-                {
-                  // Send out data packet
-                  NS_LOG_DEBUG ("Send out packet with ack id " << m_ackId);
-                  // Schedule the packet retry timer
-                  PacketKey packetKey;
-                  packetKey.m_ackId = newEntry.GetAckId ();
-                  packetKey.m_ourAdd = newEntry.GetOurAdd ();
-                  packetKey.m_nextHop = newEntry.GetNextHop ();
-                  packetKey.m_source = newEntry.GetSrc ();
-                  packetKey.m_destination = newEntry.GetDst ();
-                  packetKey.m_segsLeft = newEntry.GetSegsLeft ();
-                  PacketKey networkKey = packetKey;
-                  networkKey.m_segsLeft = 0;
-                  m_addressForwardCnt[networkKey] = 0;
-                  SchedulePacketRetry (newEntry, packetKey, protocol);
+                  if (dsrNetworkQueue->Enqueue (newEntry))
+                    {
+                      Scheduler (priority);
+                    }
+                  else
+                    {
+                      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+                    }
                 }
             }
 
-          if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
-            {
-              NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
-              Simulator::Schedule (MilliSeconds (UniformVariable ().GetInteger (0,100)),
-                                   &DsrRouting::SendPacket,this,sourceRoute,nextHop,protocol);
-            }
-        }
-      else
-        {
-          NS_LOG_DEBUG ("All queued packets are out-dated for the destination");
+        if (m_errorBuffer.GetSize () != 0 && m_errorBuffer.Find (destination))
+          {
+            NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
+            Simulator::Schedule (MilliSeconds (UniformVariable ().GetInteger (0,100)),
+                                 &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
+          }
         }
     }
   else
     {
-      NS_LOG_DEBUG ("Packet not found in send buffer");
+      NS_LOG_DEBUG ("Packet not found in either the send or error buffer");
     }
 }
 
 bool
-DsrRouting::FindSamePackets (Ptr<Packet> packet, Ipv4Header const& ipv4Header, Ipv4Address source, Ipv4Address destination,
+DsrRouting::FindSamePackets (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination,
                              uint8_t segsLeft)
 {
-  NS_LOG_FUNCTION (this << packet << ipv4Header << source << destination << (uint32_t)segsLeft);
-  /*
-   * Get the source and destination address from ipv4 header
-   */
-  Ipv4Address ourAdd = ipv4Header.GetSource ();
-  Ipv4Address nextHop = ipv4Header.GetDestination ();
+  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
 
   Ptr<Packet> p = packet->Copy ();
-  MaintainBuffEntry newEntry (/*Packet=*/ p, /*Ipv4Address=*/ ourAdd, /*nextHop=*/ nextHop,
-                                          /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
-                                          /*SegsLeft=*/ segsLeft, /*expire time=*/ m_maxMaintainTime);
-  // Temporarily disable passive acknowledgment
-//  CancelPassivePacketTimer (newEntry);
-  return true;
+  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
+  MaintainBuffEntry newEntry;
+  newEntry.SetPacket (p);
+  newEntry.SetSrc (source);
+  newEntry.SetDst (destination);
+  newEntry.SetAckId (0);
+  newEntry.SetSegsLeft (segsLeft + 1);
+
+  if (m_maintainBuffer.PromiscEqual (newEntry))
+    {
+      // The PromiscEqual function will remove the maintain buffer entry if equal value found
+      // It only compares the source and destination address, ackId, and the segments left value
+      CancelPassivePacketTimer (newEntry);
+      return true;
+    }
+  return false;
 }
 
 void
@@ -1418,8 +1835,8 @@
    */
   Ptr<Packet> mainP = Create<Packet> ();
   MaintainBuffEntry newEntry (/*Packet=*/ mainP, /*ourAddress=*/ sender, /*nextHop=*/ receiver,
-                                          /*source=*/ realSrc, /*destination=*/ realDst, /*ackId=*/ ackId,
-                                          /*SegsLeft=*/ 0, /*expire time=*/ Simulator::Now ());
+                              /*source=*/ realSrc, /*destination=*/ realDst, /*ackId=*/ ackId,
+                              /*SegsLeft=*/0, /*expire time=*/ Simulator::Now ());
   CancelNetworkPacketTimer (newEntry);
 }
 
@@ -1427,77 +1844,75 @@
 DsrRouting::CancelNetworkPacketTimer (MaintainBuffEntry & mb)
 {
   NS_LOG_FUNCTION (this);
-  PacketKey packetKey;
-  packetKey.m_ackId = mb.GetAckId ();
-  packetKey.m_ourAdd = mb.GetOurAdd ();
-  packetKey.m_nextHop = mb.GetNextHop ();
-  packetKey.m_source = mb.GetSrc ();
-  packetKey.m_destination = mb.GetDst ();
-  packetKey.m_segsLeft = 0;
+  NetworkKey networkKey;
+  networkKey.m_ackId = mb.GetAckId ();
+  networkKey.m_ourAdd = mb.GetOurAdd ();
+  networkKey.m_nextHop = mb.GetNextHop ();
+  networkKey.m_source = mb.GetSrc ();
+  networkKey.m_destination = mb.GetDst ();
   /*
    * Here we have found the entry for send retries, so we get the value and increase it by one
    */
-  m_addressForwardCnt[packetKey] = 0;
-  m_addressForwardCnt.erase (packetKey);
+  m_addressForwardCnt[networkKey] = 0;
+  m_addressForwardCnt.erase (networkKey);
 
   NS_LOG_INFO ("ackId " << mb.GetAckId () << " ourAdd " << mb.GetOurAdd () << " nextHop " << mb.GetNextHop ()
                         << " source " << mb.GetSrc () << " destination " << mb.GetDst ()
                         << " segsLeft " << (uint32_t)mb.GetSegsLeft ()
-               );
+                        );
   // Find the network acknowledgment timer
-  std::map<PacketKey, Timer>::const_iterator i =
-    m_addressForwardTimer.find (packetKey);
+  std::map<NetworkKey, Timer>::const_iterator i =
+      m_addressForwardTimer.find (networkKey);
   if (i == m_addressForwardTimer.end ())
     {
-      NS_LOG_DEBUG ("did not find the packet timer");
+      NS_LOG_INFO ("did not find the packet timer");
     }
   else
     {
-      NS_LOG_DEBUG ("did find the packet timer");
+      NS_LOG_INFO ("did find the packet timer");
       /*
        * Schedule the packet retry
        * Push back the nextHop, source, destination address
        */
-      m_addressForwardTimer[packetKey].Cancel ();
-      m_addressForwardTimer[packetKey].Remove ();
-      if (m_addressForwardTimer[packetKey].IsRunning ())
+      m_addressForwardTimer[networkKey].Cancel ();
+      m_addressForwardTimer[networkKey].Remove ();
+      if (m_addressForwardTimer[networkKey].IsRunning ())
         {
-          NS_LOG_DEBUG ("Timer not canceled");
+          NS_LOG_INFO ("Timer not canceled");
         }
-      m_addressForwardTimer.erase (packetKey);
+      m_addressForwardTimer.erase (networkKey);
     }
-  // Erase the maintenance entry
-  if (m_maintainBuffer.AllEqual (mb))
-    {
-      NS_LOG_DEBUG ("Remove same maintenance buffer entry based on network acknowledgment");
-    }
+    // Erase the maintenance entry
+    // yet this does not check the segments left value here
+    if (m_maintainBuffer.NetworkEqual (mb))
+      {
+        NS_LOG_INFO ("Remove same maintenance buffer entry based on network acknowledgment");
+      }
 }
 
 void
 DsrRouting::CancelPassivePacketTimer (MaintainBuffEntry & mb)
 {
   NS_LOG_FUNCTION (this);
-  PacketKey passiveKey;
+  PassiveKey passiveKey;
   passiveKey.m_ackId = 0;
-  passiveKey.m_ourAdd = mb.GetOurAdd ();
-  passiveKey.m_nextHop = mb.GetNextHop ();
   passiveKey.m_source = mb.GetSrc ();
   passiveKey.m_destination = mb.GetDst ();
   passiveKey.m_segsLeft = mb.GetSegsLeft ();
 
-  m_addressForwardCnt[passiveKey] = 0;
-  m_addressForwardCnt.erase (passiveKey);
+  m_passiveCnt[passiveKey] = 0;
+  m_passiveCnt.erase (passiveKey);
 
   // Find the passive acknowledgment timer
-  std::map<PacketKey, Timer>::const_iterator j =
-    m_passiveAckTimer.find (passiveKey);
+  std::map<PassiveKey, Timer>::const_iterator j =
+      m_passiveAckTimer.find (passiveKey);
   if (j == m_passiveAckTimer.end ())
     {
-      NS_LOG_DEBUG ("did not find the passive timer");
+      NS_LOG_INFO ("did not find the passive timer");
     }
   else
     {
-      NS_LOG_DEBUG ("find the passive timer");
+      NS_LOG_INFO ("find the passive timer");
       /*
        * Cancel passive acknowledgment timer
        */
@@ -1505,15 +1920,10 @@
       m_passiveAckTimer[passiveKey].Remove ();
       if (m_passiveAckTimer[passiveKey].IsRunning ())
         {
-          NS_LOG_DEBUG ("Timer not canceled");
+          NS_LOG_INFO ("Timer not canceled");
         }
       m_passiveAckTimer.erase (passiveKey);
     }
-  // Erase the maintenance entry
-  if (m_maintainBuffer.PromiscEqual (mb))
-    {
-      NS_LOG_DEBUG ("Remove same maintenance buffer entry based on passive acknowledgment");
-    }
 }
 
 void
@@ -1534,15 +1944,14 @@
 
       if (m_maintainBuffer.GetSize () && m_maintainBuffer.Find (nextHop))
         {
-          NS_LOG_DEBUG ("Cancel the packet timer for next maintenance entry");
-
+          NS_LOG_INFO ("Cancel the packet timer for next maintenance entry");
           Simulator::Schedule (MilliSeconds (UniformVariable ().GetInteger (0,100)),
                                &DsrRouting::CancelPacketTimerNextHop,this,nextHop,protocol);
         }
     }
   else
     {
-      NS_LOG_DEBUG ("Maintenance buffer entry not found");
+      NS_LOG_INFO ("Maintenance buffer entry not found");
     }
 }
 
@@ -1550,10 +1959,6 @@
 DsrRouting::SalvagePacket (Ptr<const Packet> packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol)
 {
   NS_LOG_FUNCTION (this << packet << source << dst << (uint32_t)protocol);
-  /*
-   * Look in the route cache for other routes for this destination
-   */
-  RouteCacheEntry toDst;
   // Create two copies of packet
   Ptr<Packet> p = packet->Copy ();
   Ptr<Packet> newPacket = packet->Copy ();
@@ -1573,9 +1978,10 @@
   sourceRoute.SetNumberAddress (numberAddress);
   newPacket->RemoveHeader (sourceRoute);
   uint8_t salvage = sourceRoute.GetSalvage ();
-
-  NS_LOG_DEBUG ("The salvage value get from remove headers " << (uint32_t)salvage);
-
+  /*
+   * Look in the route cache for other routes for this destination
+   */
+  RouteCacheEntry toDst;
   bool findRoute = m_routeCache->LookupRoute (dst, toDst);
   if (findRoute && (salvage < m_maxSalvageCount))
     {
@@ -1598,19 +2004,19 @@
       DsrOptionSRHeader sourceRoute;
       sourceRoute.SetSalvage (salvage);
       sourceRoute.SetNodesAddress (nodeList);     // Save the whole route in the source route header of the packet
+      sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));     // The segmentsLeft field will indicate the hops to go
+      DsrOptionAckReqHeader ackReq;
+      m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
+      ackReq.SetAckId (m_ackId);
       if (m_routeCache->IsLinkCache ())
         {
           m_routeCache->UseExtends (nodeList);
         }
-      sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));     // The segmentsLeft field will indicate the hops to go
-      DsrOptionAckReqHeader ackReq;
-      m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-      ackReq.SetAckId (m_ackId);
 
       uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
       NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ())
                                                     << " length of ack request header " << (uint32_t)(ackReq.GetLength ()));
-      newDsrRoutingHeader.SetPayloadLength (length + 4);
+      newDsrRoutingHeader.SetPayloadLength (uint16_t(length) + 4);
       newDsrRoutingHeader.AddDsrOption (sourceRoute);
       newDsrRoutingHeader.AddDsrOption (ackReq);
       p->AddHeader (newDsrRoutingHeader);
@@ -1619,7 +2025,22 @@
       Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
       m_ipv4Route->SetOutputDevice (dev);
       // Send out the data packet
-      m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+      uint32_t priority = GetPriority (DSR_DATA_PACKET);
+      std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+      Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+      NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+      DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+
+      if (dsrNetworkQueue->Enqueue (newEntry))
+        {
+          Scheduler (priority);
+        }
+      else
+        {
+          NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+        }
       /*
        * Mark the next hop address in blacklist
        */
@@ -1633,66 +2054,106 @@
 }
 
 void
-DsrRouting::SchedulePacketRetry (MaintainBuffEntry & mb,
-                                 PacketKey const & packetKey,
-                                 uint8_t protocol)
+DsrRouting::SchedulePassivePacketRetry (MaintainBuffEntry & mb,
+                                        bool onlyPassive,
+                                        uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << onlyPassive << (uint32_t)protocol);
   Ipv4Address nextHop = mb.GetNextHop ();
   Ipv4Address source = mb.GetSrc ();
   Ipv4Address dst = mb.GetDst ();
-  bool isPassive = mb.GetPassive ();
-  // Temporarily disable passive acknowledgment option
-  isPassive = false;
-  NS_LOG_DEBUG ("Sending passive packet retry or network one " << isPassive);
 
-  // Make two copies of the packet key
-  PacketKey networkKey = packetKey;
-  PacketKey passiveKey = packetKey;
+  PassiveKey passiveKey;
+  passiveKey.m_ackId = 0;
+  passiveKey.m_source = mb.GetSrc ();
+  passiveKey.m_destination = mb.GetDst ();
+  passiveKey.m_segsLeft = mb.GetSegsLeft ();
 
-  if (isPassive && nextHop != dst)
+  if (m_passiveAckTimer.find (passiveKey) == m_passiveAckTimer.end ())
     {
-      // There is no ack id for passive key, so 0 it
-      passiveKey.m_ackId = 0;
-      if (m_addressForwardTimer.find (passiveKey) == m_addressForwardTimer.end ())
-        {
-          Timer timer (Timer::CANCEL_ON_DESTROY);
-          m_addressForwardTimer[passiveKey] = timer;
-        }
-      m_sendRetries = 0; // initialize the send retry times to 0
-      m_sendRetries++;
-      // decrease the passive acknowledgment count
-      m_tryPassiveAcks = (m_tryPassiveAcks - 1);
-      if (!m_tryPassiveAcks)
-        {
-          NS_LOG_DEBUG ("Passive acknowledgment is over");
-          isPassive = false;
-        }
-      NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
-      m_addressForwardTimer[passiveKey].SetFunction (&DsrRouting::PacketScheduleTimerExpire, this);
-      m_addressForwardTimer[passiveKey].Remove ();
-      m_addressForwardTimer[passiveKey].SetArguments (mb, passiveKey, protocol, isPassive);
-      // forward count
-      m_addressForwardCnt[passiveKey] = m_sendRetries;
-      NS_LOG_DEBUG ("The packet retries time is " << m_sendRetries);
-      m_addressForwardTimer[passiveKey].Schedule (m_passiveAckTimeout);
-      return;
+      Timer timer (Timer::CANCEL_ON_DESTROY);
+      m_passiveAckTimer[passiveKey] = timer;
     }
-  else
+  NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
+  m_passiveAckTimer[passiveKey].SetFunction (&DsrRouting::PassiveScheduleTimerExpire, this);
+  m_passiveAckTimer[passiveKey].Remove ();
+  m_passiveAckTimer[passiveKey].SetArguments (mb, onlyPassive, protocol);
+  m_passiveAckTimer[passiveKey].Schedule (m_passiveAckTimeout);
+}
+
+void
+DsrRouting::ScheduleNetworkPacketRetry (MaintainBuffEntry & mb,
+                                        bool isFirst,
+                                        uint8_t protocol)
+{
+  Ptr<Packet> p = Create<Packet> ();
+  Ptr<Packet> dsrP = Create<Packet> ();
+  // The new entry will be used for retransmission
+  NetworkKey networkKey;
+  Ipv4Address nextHop = mb.GetNextHop ();
+  Ipv4Address source = mb.GetSrc ();
+  Ipv4Address dst = mb.GetDst ();
+  NS_LOG_DEBUG ("is the first retry or not " << isFirst);
+  if (isFirst)
     {
-      // There is no segments left value for network key, so 0 it
-      networkKey.m_segsLeft = 0;
+      // This is the very first network packet retry
+      p = mb.GetPacket ()->Copy ();
+      // Here we add the ack request header to the data packet for network acknowledgement
+      uint16_t ackId = AddAckReqHeader (p, nextHop);
+      dsrP = p->Copy ();
+      MaintainBuffEntry newEntry = mb;
+      // The function AllEqual will find the exact entry and delete it if found
+      m_maintainBuffer.AllEqual (mb);
+      newEntry.SetPacket (dsrP);
+      newEntry.SetAckId (ackId);
+      newEntry.SetExpireTime (m_maxMaintainTime);
+
+      networkKey.m_ackId = newEntry.GetAckId ();
+      networkKey.m_ourAdd = newEntry.GetOurAdd ();
+      networkKey.m_nextHop = newEntry.GetNextHop ();
+      networkKey.m_source = newEntry.GetSrc ();
+      networkKey.m_destination = newEntry.GetDst ();
+
+      m_addressForwardCnt[networkKey] = 0;
+      m_maintainBuffer.Enqueue (newEntry);
 
       if (m_addressForwardTimer.find (networkKey) == m_addressForwardTimer.end ())
         {
           Timer timer (Timer::CANCEL_ON_DESTROY);
           m_addressForwardTimer[networkKey] = timer;
         }
+
+      // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
+      m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
+      m_addressForwardTimer[networkKey].Remove ();
+      m_addressForwardTimer[networkKey].SetArguments (newEntry, protocol);
+      NS_LOG_DEBUG ("The packet retries time for " << newEntry.GetAckId() << " is " << m_sendRetries
+          << " and the delay time is " << Time (2 * m_nodeTraversalTime));
+      // Back-off mechanism
+      m_addressForwardTimer[networkKey].Schedule (Time (2 * m_nodeTraversalTime));
+    }
+  else
+    {
+      networkKey.m_ackId = mb.GetAckId ();
+      networkKey.m_ourAdd = mb.GetOurAdd ();
+      networkKey.m_nextHop = mb.GetNextHop ();
+      networkKey.m_source = mb.GetSrc ();
+      networkKey.m_destination = mb.GetDst ();
       /*
        * Here we have found the entry for send retries, so we get the value and increase it by one
        */
       m_sendRetries = m_addressForwardCnt[networkKey];
       NS_LOG_DEBUG ("The packet retry we have done " << m_sendRetries);
+
+      p = mb.GetPacket ()->Copy ();
+      dsrP = mb.GetPacket ()->Copy ();
+
+      NS_LOG_DEBUG ("The packet with dsr header " << dsrP->GetSize());
+      networkKey.m_ackId = mb.GetAckId ();
+      networkKey.m_ourAdd = mb.GetOurAdd ();
+      networkKey.m_nextHop = mb.GetNextHop ();
+      networkKey.m_source = mb.GetSrc ();
+      networkKey.m_destination = mb.GetDst ();
       /*
        *  If a data packet has been attempted SendRetries times at the maximum TTL without
        *  receiving any ACK, all data packets destined for the corresponding destination SHOULD be
@@ -1700,162 +2161,146 @@
        *
        *  The maxMaintRexmt also needs to decrease one for the passive ack packet
        */
-      Ptr<Packet> p = mb.GetPacket ()->Copy ();
-      Ptr<Packet> dsrP = p->Copy ();
-      Ptr<Packet> salP = p->Copy ();
-      Ptr<Packet> retransP = p->Copy ();
-      // The packet retries time has exceed the max maintenance retransmission times
-      if (m_sendRetries > m_maxMaintRexmt)
-        {
-          NS_LOG_LOGIC ("Packet transmissions to " << nextHop << " has been attempted SendRetries times for " << networkKey.m_ackId);
-          DsrRoutingHeader dsrRoutingHeader;
-          dsrP->RemoveHeader (dsrRoutingHeader);          // Remove the dsr header in whole
-          uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
-          p->RemoveAtStart (offset);
-
-          // Get the number of routers' address field
-          uint8_t buf[2];
-          p->CopyData (buf, sizeof(buf));
-          uint8_t numberAddress = (buf[1] - 2) / 4;
-          NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
-          DsrOptionSRHeader sourceRoute;
-          sourceRoute.SetNumberAddress (numberAddress);
-          p->RemoveHeader (sourceRoute);
-          std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
-          uint8_t salvage = sourceRoute.GetSalvage ();
-          Ipv4Address address1 = nodeList.front ();
-          NS_LOG_DEBUG ("address1 " << address1);
+      /*
+       * Check if the send retry time for a certain packet has already passed max maintenance retransmission
+       * time or not
+       */
 
-          CutRoute (m_mainAddress, nodeList);
-          NS_LOG_DEBUG ("The route vector after cut and the route source " << nodeList.front ());
-//          PrintVector (nodeList);
-          // Delete the route cache entry
-          RouteCacheEntry toDst;
-          // Cancel the packet timer for maintenance buffer entry
-          CancelNetworkPacketTimer (mb);
-          /*
-           * Mark the next hop address in blacklist
-           */
-//          NS_LOG_DEBUG ("Save the next hop node in blacklist");
-//          m_rreqTable->MarkLinkAsUnidirectional (nextHop, m_blacklistTimeout);
-          // Delete all the routes including the links
-          m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
-          // After deleting the broken link from all routes, need to salvage the packet right after dropping it
-          SalvagePacket (salP, source, dst, protocol);
-          /*
-           * If the salvage is not 0, use the first address in the route as the error dst in error header
-           * otherwise use the source of packet as the error destination
-           */
-          if (salvage)
-            {
-              if (address1 == m_mainAddress)
-                {
-                  DsrOptionRerrUnreachHeader rerr;
-                  rerr.SetErrorType (1);
-                  rerr.SetErrorSrc (address1);
-                  rerr.SetUnreachNode (nextHop);
-                  rerr.SetErrorDst (address1);
-                  rerr.SetSalvage (salvage);       // Set the value about whether to salvage a packet or not
-                  SendErrorRequest (rerr, protocol);
-                }
-              else
-                {
-                  SendUnreachError (nextHop, address1, salvage, protocol);
-                }
-            }
-          else
-            {
-              if (source == m_mainAddress)
-                {
-                  DsrOptionRerrUnreachHeader rerr;
-                  rerr.SetErrorType (1);
-                  rerr.SetErrorSrc (source);
-                  rerr.SetUnreachNode (nextHop);
-                  rerr.SetErrorDst (source);
-                  rerr.SetSalvage (salvage);     // Set the value about whether to salvage a packet or not
-                  SendErrorRequest (rerr, protocol);
-                }
-              else
-                {
-                  SendUnreachError (nextHop, source, salvage, protocol);
-                }
-            }
-          CancelPacketTimerNextHop (nextHop, protocol);
-        }
-      else
-        {
-          m_sendRetries++;
-          // Send out the retransmission packet
-          m_ipv4Route = SetRoute (nextHop, m_mainAddress);
-          Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
-          m_ipv4Route->SetOutputDevice (dev);
-          m_downTarget (retransP, source, nextHop, GetProtocolNumber (), m_ipv4Route);
-          // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
-          m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::PacketScheduleTimerExpire, this);
-          m_addressForwardTimer[networkKey].Remove ();
-          m_addressForwardTimer[networkKey].SetArguments (mb, networkKey, protocol, false);
-          // forward count
-          m_addressForwardCnt[networkKey] = m_sendRetries;
-          NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId () << " is " << m_sendRetries);
-          // Back-off mechanism
-          m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries *  m_nodeTraversalTime));
-        }
+      // After m_tryPassiveAcks, schedule the packet retransmission using network acknowledgment option
+      m_addressForwardTimer[networkKey].SetFunction (&DsrRouting::NetworkScheduleTimerExpire, this);
+      m_addressForwardTimer[networkKey].Remove ();
+      m_addressForwardTimer[networkKey].SetArguments (mb, protocol);
+      NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId() << " is " << m_sendRetries
+          << " and the delay time is " << Time (2 * m_sendRetries *  m_nodeTraversalTime));
+      // Back-off mechanism
+      m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries * m_nodeTraversalTime));
     }
-  return;
 }
 
 void
-DsrRouting::AddAckReqHeader (Ptr<Packet> packet, DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop)
+DsrRouting::PassiveScheduleTimerExpire  (MaintainBuffEntry & mb,
+                                         bool onlyPassive,
+                                         uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << packet << nextHop);
-  // This packet is used to peek option type
-  Ptr<Packet> cleanP = packet->Copy ();
-
-  DsrOptionAckReqHeader ackReq;
-  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-  ackReq.SetAckId (m_ackId);
-
-  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-  DsrRoutingHeader dsrRoutingHeader;
-  dsrRoutingHeader.SetPayloadLength (length + 4);
-  dsrRoutingHeader.AddDsrOption (sourceRoute);
-  dsrRoutingHeader.AddDsrOption (ackReq);
-  cleanP->AddHeader (dsrRoutingHeader);
-}
-
-void
-DsrRouting::PacketScheduleTimerExpire  (MaintainBuffEntry & mb,
-                                        PacketKey const & pk,
-                                        uint8_t protocol,
-                                        bool isPassive)
-{
-  NS_LOG_FUNCTION (this << (uint32_t)protocol << isPassive);
+  NS_LOG_FUNCTION (this << onlyPassive << (uint32_t)protocol);
   Ipv4Address nextHop = mb.GetNextHop ();
   Ipv4Address source = mb.GetSrc ();
   Ipv4Address dst = mb.GetDst ();
   Ptr<const Packet> packet = mb.GetPacket ();
   SetRoute (nextHop, m_mainAddress);
   Ptr<Packet> p = packet->Copy ();
-  if (isPassive)
+
+  PassiveKey pk;
+  pk.m_ackId = 0;
+  pk.m_source = mb.GetSrc ();
+  pk.m_destination = mb.GetDst ();
+  pk.m_segsLeft = mb.GetSegsLeft ();
+
+  // Cancel passive ack timer
+  m_passiveAckTimer[pk].Cancel ();
+  m_passiveAckTimer[pk].Remove ();
+  if (m_passiveAckTimer[pk].IsRunning ())
     {
-      // Cancel passive ack timer
-      m_passiveAckTimer[pk].Cancel ();
-      m_passiveAckTimer[pk].Remove ();
-      if (m_passiveAckTimer[pk].IsRunning ())
-        {
-          NS_LOG_DEBUG ("Timer not canceled");
-        }
-      m_passiveAckTimer.erase (pk);
-      isPassive = false;
-      mb.SetPassive (false);
-      SchedulePacketRetry (mb, pk, protocol);
+      NS_LOG_DEBUG ("Timer not canceled");
+    }
+  m_passiveAckTimer.erase (pk);
+  // Send the data packet out before schedule the next packet transmission
+  SendPacket (p, source, nextHop, protocol);
+  // Increase the send retry times
+  m_passiveRetries = m_passiveCnt[pk];
+  if (m_passiveRetries < m_tryPassiveAcks)
+    {
+      m_passiveCnt[pk] = ++m_passiveRetries;
+      SchedulePassivePacketRetry (mb, onlyPassive, protocol);
+    }
+  else if (!onlyPassive)
+    {
+      // This is the first network acknowledgement retry
+      // Cancel the passive packet timer now and remove maintenance buffer entry for it
+      CancelPassivePacketTimer (mb);
+      ScheduleNetworkPacketRetry (mb, true, protocol);
     }
   else
     {
-      mb.SetPassive (false);
-      SchedulePacketRetry (mb, pk, protocol);
+      // This is the end of the data retransmission retries
+      CancelPassivePacketTimer (mb);
+      // The function AllEqual will find the exact entry and delete it if found
+      m_maintainBuffer.AllEqual (mb);
     }
-  return;
+}
+
+void
+DsrRouting::NetworkScheduleTimerExpire  (MaintainBuffEntry & mb,
+                                         uint8_t protocol)
+{
+  Ptr<Packet> p = mb.GetPacket ()->Copy ();
+  Ipv4Address source = mb.GetSrc ();
+  Ipv4Address nextHop = mb.GetNextHop ();
+  Ipv4Address dst = mb.GetDst ();
+
+  NetworkKey networkKey;
+  networkKey.m_ackId = mb.GetAckId ();
+  networkKey.m_ourAdd = mb.GetOurAdd ();
+  networkKey.m_nextHop = nextHop;
+  networkKey.m_source = source;
+  networkKey.m_destination = dst;
+
+  // Send the data packet out before schedule the next packet transmission
+  SendPacket (p, source, nextHop, protocol);
+  // Increase the send retry times
+  m_sendRetries = m_addressForwardCnt[networkKey];
+  NS_LOG_DEBUG ("The send retry time is " << m_sendRetries);
+  if (m_sendRetries >= m_maxMaintRexmt)
+    {
+      Ptr<Packet> dsrP = mb.GetPacket ()->Copy ();
+      // The packet retries time has exceed the max maintenance retransmission times
+      NS_LOG_LOGIC ("Packet transmissions to " << nextHop << " has been attempted SendRetries times for " << networkKey.m_ackId);
+      DsrRoutingHeader dsrRoutingHeader;
+      dsrP->RemoveHeader (dsrRoutingHeader);          // Remove the dsr header in whole
+      uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
+      p->RemoveAtStart (offset);
+
+      // Get the number of routers' address field
+      uint8_t buf[2];
+      p->CopyData (buf, sizeof(buf));
+      uint8_t numberAddress = (buf[1] - 2) / 4;
+      NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
+      DsrOptionSRHeader sourceRoute;
+      sourceRoute.SetNumberAddress (numberAddress);
+      p->RemoveHeader (sourceRoute);
+      std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
+      uint8_t salvage = sourceRoute.GetSalvage ();
+      Ipv4Address address1 = nodeList[1];
+      NS_LOG_DEBUG ("address1 " << address1);
+      PrintVector (nodeList);
+
+      // Delete all the routes including the links
+      m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
+      /*
+       * If the salvage is not 0, use the first address in the route as the error dst in error header
+       * otherwise use the source of packet as the error destination
+       */
+      Ipv4Address errorDst;
+      if (salvage)
+        {
+          errorDst = address1;
+        }
+      else
+        {
+          errorDst = source;
+        }
+      SendUnreachError (nextHop, errorDst, dst, salvage, protocol);
+      /*
+       * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
+       * Also salvage the packet for the all the packet destined for the nextHop address
+       */
+      CancelPacketTimerNextHop (nextHop, protocol);
+    }
+  else
+    {
+      m_addressForwardCnt[networkKey] = ++m_sendRetries;
+      ScheduleNetworkPacketRetry (mb, false, protocol);
+    }
 }
 
 void
@@ -1879,36 +2324,47 @@
 
   // We get the salvage value in sourceRoute header and set it to route error header if triggered error
   Ptr<Packet> p = packet->Copy ();
-  DsrOptionAckReqHeader ackReq;
-  m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-  ackReq.SetAckId (m_ackId);
+  uint8_t length = sourceRoute.GetLength ();
+  dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
+  dsrRoutingHeader.AddDsrOption (sourceRoute);
+  p->AddHeader (dsrRoutingHeader);
 
-  uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-  dsrRoutingHeader.SetPayloadLength (length + 4);
-  dsrRoutingHeader.AddDsrOption (sourceRoute);
-  dsrRoutingHeader.AddDsrOption (ackReq);
-  p->AddHeader (dsrRoutingHeader);
+  // Send the data packet out before schedule the next packet transmission
+  SendPacket (p, source, nextHop, protocol);
+
   Ptr<const Packet> mtP = p->Copy ();
 
   MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
                                           /*source=*/ source, /*destination=*/ targetAddress,
-                                          /*ackId=*/ m_ackId, /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
+                                          /*ackId=*/ m_ackId, /*SegsLeft=*/sourceRoute.GetSegmentsLeft(), /*expire time=*/ m_maxMaintainTime);
   bool result = m_maintainBuffer.Enqueue (newEntry);
 
   if (result)
     {
-      Ptr<Packet> newPacket = p->Copy ();
-      PacketKey packetKey;
-      packetKey.m_ackId = newEntry.GetAckId ();
-      packetKey.m_ourAdd = newEntry.GetOurAdd ();
-      packetKey.m_nextHop = newEntry.GetNextHop ();
-      packetKey.m_source = newEntry.GetSrc ();
-      packetKey.m_destination = newEntry.GetDst ();
-      packetKey.m_segsLeft = newEntry.GetSegsLeft ();
-      PacketKey networkKey = packetKey;
-      networkKey.m_segsLeft = 0;
+      NetworkKey networkKey;
+      networkKey.m_ackId = newEntry.GetAckId ();
+      networkKey.m_ourAdd = newEntry.GetOurAdd ();
+      networkKey.m_nextHop = newEntry.GetNextHop ();
+      networkKey.m_source = newEntry.GetSrc ();
+      networkKey.m_destination = newEntry.GetDst ();
+
+      PassiveKey passiveKey;
+      passiveKey.m_ackId = 0;
+      passiveKey.m_source = newEntry.GetSrc ();
+      passiveKey.m_destination = newEntry.GetDst ();
+      passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
+
       m_addressForwardCnt[networkKey] = 0;
-      SchedulePacketRetry (newEntry, packetKey, protocol);
+      m_passiveCnt[passiveKey] = 0;
+      if (nextHop != targetAddress)
+        {
+          SchedulePassivePacketRetry (newEntry, false, protocol);
+        }
+      else
+        {
+          // This is the first network retry
+          ScheduleNetworkPacketRetry (newEntry, true, protocol);
+        }
     }
 }
 
@@ -1931,24 +2387,32 @@
   dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
   dsrRoutingHeader.SetDestId (255);
 
-  DsrOptionRreqHeader rreqHeader;                                // has an alignment of 4n+0
-  rreqHeader.AddNodeAddress (m_mainAddress);                     // Add our own address in the header
+  DsrOptionRreqHeader rreqHeader;                                  // has an alignment of 4n+0
+  rreqHeader.AddNodeAddress (m_mainAddress);                       // Add our own address in the header
   rreqHeader.SetTarget (destination);
-  m_requestId = m_rreqTable->CheckUniqueRreqId (destination);       // Check the Id cache for duplicate ones
+  m_requestId = m_rreqTable->CheckUniqueRreqId (destination);      // Check the Id cache for duplicate ones
   rreqHeader.SetId (m_requestId);
-  // Increment the route request count, if entry not found, the function will create a new one
-  m_rreqTable->FindAndUpdate (destination);
 
-  dsrRoutingHeader.AddDsrOption (rreqHeader);         // Add the rreqHeader to the dsr extension header
+  dsrRoutingHeader.AddDsrOption (rreqHeader);                      // Add the rreqHeader to the dsr extension header
   uint8_t length = rreqHeader.GetLength ();
-  dsrRoutingHeader.SetPayloadLength (length + 2);
+  dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
   packet->AddHeader (dsrRoutingHeader);
 
-  // This function will increase the request count if found the entry, will create the entry if not found
-  m_rreqTable->FindAndUpdate (destination);
   // Schedule the route requests retry with non-propagation set true
   bool nonProp = true;
-  ScheduleRreqRetry (packet, source, destination, nonProp, protocol);
+  std::vector<Ipv4Address> address;
+  address.push_back (source);
+  address.push_back (destination);
+  /*
+   * Add the socket ip ttl tag to the packet to limit the scope of route requests
+   */
+  SocketIpTtlTag tag;
+  tag.SetTtl (0);
+  Ptr<Packet> nonPropPacket = packet->Copy ();
+  nonPropPacket->AddPacketTag (tag);
+  SendRequest (nonPropPacket, source);
+  // Schedule the next route request
+  ScheduleRreqRetry (packet, address, nonProp, m_requestId, protocol);
 }
 
 void
@@ -1956,80 +2420,106 @@
 {
   NS_LOG_FUNCTION (this << (uint32_t)protocol);
   NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
-  Ptr<Packet> packet = Create<Packet> ();
-  Ipv4Address destination = rerr.GetErrorSrc ();
-  Ipv4Address unreachAddress = rerr.GetUnreachNode ();
-  // Create an empty route ptr
-  Ptr<Ipv4Route> route = 0;
-  /*
-   * Construct the route request option header
-   */
-  DsrRoutingHeader dsrRoutingHeader;
-  dsrRoutingHeader.SetNextHeader (protocol);
-  dsrRoutingHeader.SetMessageType (1);
-  dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
-  dsrRoutingHeader.SetDestId (255);
-
-  if (m_mainAddress != destination)
+  uint8_t salvage = rerr.GetSalvage ();
+  Ipv4Address dst = rerr.GetOriginalDst ();
+  NS_LOG_DEBUG ("our own address here " << m_mainAddress << " error source " << rerr.GetErrorSrc () << " error destination " << rerr.GetErrorDst ()
+      << " error next hop " << rerr.GetUnreachNode () << " original dst " << rerr.GetOriginalDst ()
+     );
+  RouteCacheEntry toDst;
+  if (m_routeCache->LookupRoute (dst, toDst))
     {
       /*
-       * Send error request to the error source
+       * Found a route the dst, construct the source route option header
        */
-      NS_LOG_DEBUG ("Send error packet to the error source");
+      DsrOptionSRHeader sourceRoute;
+      std::vector<Ipv4Address> ip = toDst.GetVector ();
+      sourceRoute.SetNodesAddress (ip);
+      if (m_routeCache->IsLinkCache ())
+        {
+          m_routeCache->UseExtends (ip);
+        }
+      sourceRoute.SetSegmentsLeft ((ip.size () - 2));
+      sourceRoute.SetSalvage (salvage);
+      Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip);       // Get the next hop address
+      NS_LOG_DEBUG ("The nextHop address " << nextHop);
+      Ptr<Packet> packet = Create<Packet> ();
+      if (nextHop == "0.0.0.0")
+        {
+          NS_LOG_DEBUG ("Error next hop address");
+          PacketNewRoute (packet, m_mainAddress, dst, protocol);
+          return;
+        }
+      SetRoute (nextHop, m_mainAddress);
+      CancelRreqTimer (dst, true);
+      SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+      NS_LOG_LOGIC ("Route to " << dst << " found");
+      return;
+    }
+  else
+    {
+      NS_LOG_INFO ("No route found, initiate route error request");
+      Ptr<Packet> packet = Create<Packet> ();
+      Ipv4Address unreachAddress = rerr.GetUnreachNode ();
+      Ipv4Address originalDst = rerr.GetOriginalDst ();
+      // Create an empty route ptr
+      Ptr<Ipv4Route> route = 0;
+      /*
+       * Construct the route request option header
+       */
+      DsrRoutingHeader dsrRoutingHeader;
+      dsrRoutingHeader.SetNextHeader (protocol);
+      dsrRoutingHeader.SetMessageType (1);
+      dsrRoutingHeader.SetSourceId (GetIDfromIP (m_mainAddress));
+      dsrRoutingHeader.SetDestId (255);
+
       Ptr<Packet> dstP = Create<Packet> ();
       DsrOptionRreqHeader rreqHeader;                                // has an alignment of 4n+0
       rreqHeader.AddNodeAddress (m_mainAddress);                     // Add our own address in the header
-      rreqHeader.SetTarget (destination);
-      m_requestId = m_rreqTable->CheckUniqueRreqId (destination);       // Check the Id cache for duplicate ones
+      rreqHeader.SetTarget (originalDst);
+      m_requestId = m_rreqTable->CheckUniqueRreqId (originalDst);       // Check the Id cache for duplicate ones
       rreqHeader.SetId (m_requestId);
-      // This function will increase the request count if found the entry, will create the entry if not found
-      m_rreqTable->FindAndUpdate (destination);
 
       dsrRoutingHeader.AddDsrOption (rreqHeader);         // Add the rreqHeader to the dsr extension header
       dsrRoutingHeader.AddDsrOption (rerr);
       uint8_t length = rreqHeader.GetLength () + rerr.GetLength ();
-      dsrRoutingHeader.SetPayloadLength (length + 4);
+      dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 4);
       dstP->AddHeader (dsrRoutingHeader);
       // Schedule the route requests retry, propagate the route request message as it contains error
       bool nonProp = false;
-      if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
-        {
-          NS_LOG_DEBUG ("Only when there is no existing route request time when this one is triggered");
-          ScheduleRreqRetry (dstP, m_mainAddress, destination, nonProp, protocol);
-        }
-    }
-  else
-    {
+      std::vector<Ipv4Address> address;
+      address.push_back (m_mainAddress);
+      address.push_back (originalDst);
       /*
-       * Send error request to the unreachable node
+       * Add the socket ip ttl tag to the packet to limit the scope of route requests
        */
-      DsrOptionRreqHeader rreqHeader;                                // has an alignment of 4n+0
-      rreqHeader.AddNodeAddress (m_mainAddress);                     // Add our own address in the header
-      rreqHeader.SetTarget (unreachAddress);
-      m_requestId = m_rreqTable->CheckUniqueRreqId (unreachAddress);       // Check the Id cache for duplicate ones
-      rreqHeader.SetId (m_requestId);
-      // This function will increase the request count if found the entry, will create the entry if not found
-      m_rreqTable->FindAndUpdate (unreachAddress);
+      SocketIpTtlTag tag;
+      tag.SetTtl ((uint8_t)m_discoveryHopLimit);
+      Ptr<Packet> propPacket = dstP->Copy ();
+      propPacket->AddPacketTag (tag);
 
-      dsrRoutingHeader.AddDsrOption (rreqHeader);         // Add the rreqHeader to the dsr extension header
-      dsrRoutingHeader.AddDsrOption (rerr);
-      uint8_t length = rreqHeader.GetLength () + rerr.GetLength ();
-      dsrRoutingHeader.SetPayloadLength (length + 4);
-      packet->AddHeader (dsrRoutingHeader);
-      // Schedule the route requests retry, propagate the route request message as it contains error
-      bool nonProp = false;
-      if ((m_addressReqTimer.find (unreachAddress) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (unreachAddress) == m_nonPropReqTimer.end ()))
+      if ((m_addressReqTimer.find (originalDst) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (originalDst) == m_nonPropReqTimer.end ()))
+        {
+          NS_LOG_INFO ("Only when there is no existing route request time when the initial route request is scheduled");
+          SendRequest (propPacket, m_mainAddress);
+          ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
+        }
+      else
         {
-          NS_LOG_DEBUG ("Only when there is no existing route request time when this one is triggered");
-          ScheduleRreqRetry (packet, m_mainAddress, unreachAddress, nonProp, protocol);
+          NS_LOG_INFO ("There is existing route request, find the existing route request entry");
+          /*
+           * Cancel the route request timer first before scheduling the route request
+           * in this case, we do not want to remove the route request entry, so the isRemove value is false
+           */
+          CancelRreqTimer (originalDst, false);
+          ScheduleRreqRetry (dstP, address, nonProp, m_requestId, protocol);
         }
     }
 }
 
 void
-DsrRouting::CancelRreqTimer (Ipv4Address dst)
+DsrRouting::CancelRreqTimer (Ipv4Address dst, bool isRemove)
 {
-  NS_LOG_FUNCTION (this << dst);
+  NS_LOG_FUNCTION (this << dst << isRemove);
   // Cancel the non propagation request timer if found
   if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
     {
@@ -2064,35 +2554,37 @@
       NS_LOG_DEBUG ("Timer not canceled");
     }
   m_addressReqTimer.erase (dst);
-
-  // remove the route request entry from route request table
-  m_rreqTable->RemoveRreqEntry (dst);
+  /*
+   * If the route request is scheduled to remove the route request entry
+   * Remove the route request entry with the route retry times done for certain destination
+   */
+  if (isRemove)
+    {
+      // remove the route request entry from route request table
+      m_rreqTable->RemoveRreqEntry (dst);
+    }
 }
 
 void
-DsrRouting::ScheduleRreqRetry (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dst, bool nonProp, uint8_t protocol)
+DsrRouting::ScheduleRreqRetry (Ptr<Packet> packet, std::vector<Ipv4Address> address, bool nonProp, uint32_t requestId, uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << packet << source << dst << nonProp << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << packet << nonProp << requestId << (uint32_t)protocol);
+  Ipv4Address source = address[0];
+  Ipv4Address dst = address[1];
   if (nonProp)
     {
-      nonProp = false;
+      // The nonProp route request is only sent out only and is already used
       if (m_nonPropReqTimer.find (dst) == m_nonPropReqTimer.end ())
         {
           Timer timer (Timer::CANCEL_ON_DESTROY);
           m_nonPropReqTimer[dst] = timer;
         }
-      /*
-       * Add the socket ip ttl tag to the packet to limit the scope of route requests
-       */
-      SocketIpTtlTag tag;
-      tag.SetTtl (0);
-      Ptr<Packet> nonPropPacket = packet->Copy ();
-      nonPropPacket->AddPacketTag (tag);
-      SendRequest (nonPropPacket, source);
-      NS_LOG_DEBUG ("Check the route request entry3 " << source << " " << dst);
-      m_nonPropReqTimer[dst].SetFunction (&DsrRouting::ScheduleRreqRetry, this);
+      std::vector<Ipv4Address> address;
+      address.push_back (source);
+      address.push_back (dst);
+      m_nonPropReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
       m_nonPropReqTimer[dst].Remove ();
-      m_nonPropReqTimer[dst].SetArguments (packet, source, dst, nonProp, protocol);
+      m_nonPropReqTimer[dst].SetArguments (packet, address, requestId, protocol);
       m_nonPropReqTimer[dst].Schedule (m_nonpropRequestTimeout);
     }
   else
@@ -2105,43 +2597,57 @@
           NS_LOG_DEBUG ("Timer not canceled");
         }
       m_nonPropReqTimer.erase (dst);
-      /*
-       * Add the socket ip ttl tag to the packet to limit the scope of route requests
-       */
-      SocketIpTtlTag tag;
-      tag.SetTtl (m_discoveryHopLimit);
-      packet->AddPacketTag (tag);
+
       if (m_addressReqTimer.find (dst) == m_addressReqTimer.end ())
         {
           Timer timer (Timer::CANCEL_ON_DESTROY);
           m_addressReqTimer[dst] = timer;
         }
+      std::vector<Ipv4Address> address;
+      address.push_back (source);
+      address.push_back (dst);
       m_addressReqTimer[dst].SetFunction (&DsrRouting::RouteRequestTimerExpire, this);
       m_addressReqTimer[dst].Remove ();
-      m_addressReqTimer[dst].SetArguments (packet, source, dst, protocol);
-      // Increase the request count
-      m_rreqTable->FindAndUpdate (dst);
+      m_addressReqTimer[dst].SetArguments (packet, address, requestId, protocol);
+      Time rreqDelay;
       // back off mechanism for sending route requests
-      Time rreqDelay = Time (pow (m_rreqTable->GetRreqCnt (dst), 2) * m_requestPeriod);
+      if (m_rreqTable->GetRreqCnt (dst))
+        {
+          // When the route request count is larger than 0
+          rreqDelay = Time (pow (m_rreqTable->GetRreqCnt (dst), 2) * m_requestPeriod);
+        }
+      else
+        {
+          // This is the first route request retry
+          rreqDelay = m_requestPeriod;
+        }
       NS_LOG_DEBUG ("The request count for the destination " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with time value " << rreqDelay);
       if (rreqDelay > m_maxRequestPeriod)
         {
           // use the max request period
-          NS_LOG_DEBUG ("The max request delay time " << m_maxRequestPeriod.GetSeconds ());
+          NS_LOG_DEBUG ("The max request delay time " << m_maxRequestPeriod.GetSeconds());
           m_addressReqTimer[dst].Schedule (m_maxRequestPeriod);
         }
       else
         {
-          NS_LOG_DEBUG ("The request delay time " << rreqDelay.GetSeconds ());
+          NS_LOG_DEBUG ("The request delay time " << rreqDelay.GetSeconds());
           m_addressReqTimer[dst].Schedule (rreqDelay);
         }
+
     }
 }
 
 void
-DsrRouting::RouteRequestTimerExpire (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol)
+DsrRouting::RouteRequestTimerExpire (Ptr<Packet> packet, std::vector<Ipv4Address> address, uint32_t requestId, uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << packet << source << dst << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << packet << requestId << (uint32_t)protocol);
+  // Get a clean packet without dsr header
+  Ptr<Packet> dsrP = packet->Copy ();
+  DsrRoutingHeader dsrRoutingHeader;
+  dsrP->RemoveHeader (dsrRoutingHeader);          // Remove the dsr header in whole
+
+  Ipv4Address source = address[0];
+  Ipv4Address dst = address[1];
   RouteCacheEntry toDst;
   if (m_routeCache->LookupRoute (dst, toDst))
     {
@@ -2150,7 +2656,6 @@
        */
       DsrOptionSRHeader sourceRoute;
       std::vector<Ipv4Address> ip = toDst.GetVector ();
-//      PrintVector (ip);
       sourceRoute.SetNodesAddress (ip);
       if (m_routeCache->IsLinkCache ())
         {
@@ -2163,11 +2668,13 @@
       NS_LOG_DEBUG ("The nextHop address " << nextHop);
       if (nextHop == "0.0.0.0")
         {
+          NS_LOG_DEBUG ("Error next hop address");
+          PacketNewRoute (dsrP, source, dst, protocol);
           return;
         }
       SetRoute (nextHop, m_mainAddress);
-      CancelRreqTimer (dst);
-      SendPacket (sourceRoute, nextHop, protocol);
+      CancelRreqTimer (dst, true);
+      SendPacketFromBuffer (sourceRoute, nextHop, protocol);
       NS_LOG_LOGIC ("Route to " << dst << " found");
       return;
     }
@@ -2180,15 +2687,21 @@
   if (m_rreqTable->GetRreqCnt (dst) >= m_rreqRetries)
     {
       NS_LOG_LOGIC ("Route discovery to " << dst << " has been attempted " << m_rreqRetries << " times");
-      CancelRreqTimer (dst);
+      CancelRreqTimer (dst, true);
       NS_LOG_DEBUG ("Route not found. Drop packet with dst " << dst);
       m_sendBuffer.DropPacketWithDst (dst);
     }
   else
     {
-      SendRequest (packet, source);
-      NS_LOG_DEBUG ("Check the route request entry1 " << source << " " << dst);
-      ScheduleRreqRetry (packet, source, dst, false, protocol);
+      SocketIpTtlTag tag;
+      tag.SetTtl ((uint8_t)m_discoveryHopLimit);
+      Ptr<Packet> propPacket = packet->Copy ();
+      propPacket->AddPacketTag (tag);
+      // Increase the request count
+      m_rreqTable->FindAndUpdate (dst);
+      SendRequest (propPacket, source);
+      NS_LOG_DEBUG ("Check the route request entry " << source << " " << dst);
+      ScheduleRreqRetry (packet, address, false, requestId, protocol);
     }
   return;
 }
@@ -2202,7 +2715,21 @@
   /*
    * The destination address here is directed broadcast address
    */
-  m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
+  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
+
+  if (dsrNetworkQueue->Enqueue (newEntry))
+    {
+      Scheduler (priority);
+    }
+  else
+    {
+      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+    }
 }
 
 void
@@ -2210,7 +2737,7 @@
 {
   NS_LOG_FUNCTION (this << packet);
   /*
-   * this is a forwarding case when sending route requests, a random delay time [0, m_broadcastJitter]
+   * This is a forwarding case when sending route requests, a random delay time [0, m_broadcastJitter]
    * used before forwarding as link-layer broadcast
    */
   Simulator::Schedule (MilliSeconds (UniformVariable ().GetInteger (0, m_broadcastJitter)), &DsrRouting::SendRequest, this,
@@ -2233,7 +2760,6 @@
       /**
        * Push back the node addresses other than those between srcAddress and our own ip address
        */
-//      PrintVector (nodeList);
       std::vector<Ipv4Address>::iterator before = find (nodeList.begin (), nodeList.end (), srcAddress);
       for (std::vector<Ipv4Address>::iterator i = nodeList.begin (); i != before; ++i)
         {
@@ -2245,7 +2771,6 @@
         {
           m_finalRoute.push_back (*j);
         }
-//      PrintVector (m_finalRoute);
       DsrOptionRrepHeader rrep;
       rrep.SetNodesAddress (m_finalRoute);           // Set the node addresses in the route reply header
       // Get the real reply source and destination
@@ -2265,7 +2790,7 @@
       dsrRoutingHeader.SetDestId (GetIDfromIP (replyDst));
 
       uint8_t length = rrep.GetLength ();        // Get the length of the rrep header excluding the type header
-      dsrRoutingHeader.SetPayloadLength (length + 2);
+      dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
       dsrRoutingHeader.AddDsrOption (rrep);
       Ptr<Packet> newPacket = Create<Packet> ();
       newPacket->AddHeader (dsrRoutingHeader);
@@ -2292,7 +2817,22 @@
   Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (m_mainAddress));
   route->SetOutputDevice (dev);
   NS_LOG_INFO ("The output device " << dev << " packet is: " << *packet);
-  m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
+
+  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
+
+  if (dsrNetworkQueue->Enqueue (newEntry))
+    {
+      Scheduler (priority);
+    }
+  else
+    {
+      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+    }
 }
 
 void
@@ -2311,7 +2851,7 @@
                                  Ipv4Address source,
                                  Ipv4Address destination,
                                  Ptr<Ipv4Route> route,
-                                 uint16_t hops)
+                                 double hops)
 {
   NS_LOG_FUNCTION (this << packet << source << destination);
   Simulator::Schedule (Time (2 * m_nodeTraversalTime * (hops - 1 + UniformVariable ().GetValue (0,1))), &DsrRouting::SendReply, this, packet, source, destination, route);
@@ -2344,7 +2884,7 @@
   ack.SetRealDst (realDst);
 
   uint8_t length = ack.GetLength ();
-  dsrRoutingHeader.SetPayloadLength (length + 2);
+  dsrRoutingHeader.SetPayloadLength (uint16_t(length) + 2);
   dsrRoutingHeader.AddDsrOption (ack);
 
   Ptr<Packet> packet = Create<Packet> ();
@@ -2352,7 +2892,22 @@
   Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
   route->SetOutputDevice (dev);
   NS_LOG_DEBUG ("Send out the ACK");
-  m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
+
+  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
+  Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
+  NS_LOG_DEBUG("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
+
+  if (dsrNetworkQueue->Enqueue (newEntry))
+    {
+      Scheduler (priority);
+    }
+  else
+    {
+      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+    }
 }
 
 enum Ipv4L4Protocol::RxStatus
@@ -2374,12 +2929,11 @@
   uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
   uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
   Ipv4Address source = GetIPfromID (sourceId);
-  NS_LOG_DEBUG ("The source address " << source);
+  NS_LOG_DEBUG ("The source address " << source << " with source id " << sourceId);
   /*
    * Get the IP source and destination address
    */
   Ipv4Address src = ip.GetSource ();
-  Ipv4Address dst = ip.GetDestination ();
 
   bool isPromisc = false;
   uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();        // Get the offset for option header, 8 bytes in this case
@@ -2401,7 +2955,7 @@
   uint8_t segmentsLeft = 0;
 
   optionType = *(data);
-  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType);
+  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet size " << p->GetSize());
   dsrOption = GetOption (optionType);       // Get the relative dsr option and demux to the process function
 
   if (optionType == 1)        // This is the request option
@@ -2478,9 +3032,9 @@
         }
       else
         {
-          if (segmentsLeft != 0)
+          if (segmentsLeft == 0)
             {
-              // / get the next header
+              // / Get the next header
               uint8_t nextHeader = dsrRoutingHeader.GetNextHeader ();
               Ptr<Ipv4L3Protocol> l3proto = m_node->GetObject<Ipv4L3Protocol> ();
               Ptr<Ipv4L4Protocol> nextProto = l3proto->GetProtocol (nextHeader);
@@ -2489,6 +3043,7 @@
                   // we need to make a copy in the unlikely event we hit the
                   // RX_ENDPOINT_UNREACH code path
                   // Here we can use the packet that has been get off whole DSR header
+                  NS_LOG_DEBUG ("The packet size here " << copy->GetSize());
                   NS_LOG_DEBUG ("The packet received " << *copy);
                   enum Ipv4L4Protocol::RxStatus status =
                     nextProto->Receive (copy, ip, incomingInterface);
@@ -2502,16 +3057,20 @@
                       case Ipv4L4Protocol::RX_CSUM_FAILED:
                         break;
                       case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
-                        if (ip.GetDestination ().IsBroadcast () == true
-                            || ip.GetDestination ().IsMulticast () == true)
-                          {
-                            break;       // Do not reply to broadcast or multicast
-                          }
+                      if (ip.GetDestination ().IsBroadcast () == true
+                          || ip.GetDestination ().IsMulticast () == true)
+                        {
+                          break;       // Do not reply to broadcast or multicast
+                        }
+                      // Another case to suppress ICMP is a subnet-directed broadcast
                     }
-                  // Another case to suppress ICMP is a subnet-directed broadcast
-                 return status;
+                  return status;
                 }
             }
+          else
+            {
+              NS_LOG_INFO ("This is not the final destination, the packet has already been forward to next hop");
+            }
         }
     }
   else
@@ -2535,7 +3094,7 @@
        */
 //            SendError (rerrUnsupportHeader, 0, protocol); // Send the error packet
     }
-  return Ipv4L4Protocol::RX_ENDPOINT_UNREACH;
+  return Ipv4L4Protocol::RX_OK;
 }
 
 void
--- a/src/dsr/model/dsr-routing.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-routing.h	Sun May 06 20:52:24 2012 -0700
@@ -62,12 +62,14 @@
 #include "ns3/event-garbage-collector.h"
 #include "ns3/test.h"
 
+#include "dsr-network-queue.h"
 #include "dsr-rcache.h"
 #include "dsr-rreq-table.h"
 #include "dsr-maintain-buff.h"
 #include "dsr-option-header.h"
 #include "dsr-fs-header.h"
 #include "dsr-rsendbuff.h"
+#include "dsr-errorbuff.h"
 #include "dsr-gratuitous-reply-table.h"
 
 namespace ns3 {
@@ -138,16 +140,28 @@
     * \return the request table
     */
   Ptr<dsr::RreqTable> GetRequestTable () const;
+
+  ///\functions used to direct to route cache
+  //\{
+  bool IsLinkCache ();
+  void UseExtends (RouteCacheEntry::IP_VECTOR rt);
+  bool LookupRoute (Ipv4Address id, RouteCacheEntry & rt);
+  bool AddRoute_Link (RouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source);
+  bool AddRoute (RouteCacheEntry & rt);
+  void DeleteAllRoutesIncludeLink (Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node);
+  bool UpdateRouteEntry (Ipv4Address dst);
+  //\}
+
   /**
     * \brief Get the node id from ip address.
     * \return the node id
     */
-  uint32_t GetIDfromIP (Ipv4Address address);
+  uint16_t GetIDfromIP (Ipv4Address address);
   /**
     * \brief Get the ip address from id.
     * \return the ip address for the id
     */
-  Ipv4Address GetIPfromID (uint32_t id);
+  Ipv4Address GetIPfromID (uint16_t id);
   /**
     * \brief Get the Ip address from mac address.
     * \return the ip address
@@ -163,10 +177,6 @@
     */
   Ipv4Address SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec);
   /**
-    * \brief Cut the route before our own ip address
-    */
-  void CutRoute (Ipv4Address ourAdd, std::vector<Ipv4Address>& nodeList);
-  /**
     * \brief Get the dsr protocol number.
     * \return protocol number
     */
@@ -193,9 +203,14 @@
    */
   Ptr<Ipv4Route> SetRoute (Ipv4Address nextHop, Ipv4Address srcAddress);
   /*
+   * \brief Set the priority of the packet in network queue
+   * \return the priority value
+   */
+  uint32_t GetPriority (DsrMessageType messageType);
+  /*
    * \brief This function is responsible for sending error packets in case of break link to next hop
    */
-  void SendUnreachError (Ipv4Address errorHop, Ipv4Address destination, uint8_t salvage, uint8_t protocol);
+  void SendUnreachError (Ipv4Address errorHop, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol);
   /*
    * \brief This function is responsible for forwarding error packets along the route
    */
@@ -210,17 +225,40 @@
   void Send (Ptr<Packet> packet, Ipv4Address source,
              Ipv4Address destination, uint8_t protocol, Ptr<Ipv4Route> route);
   /*
+   * \brief This function is called to add ack request header for network acknowledgement
+   */
+  uint16_t AddAckReqHeader (Ptr<Packet> &packet, Ipv4Address nextHop);
+  /*
+   * \brief This function is called by when really sending out the packet
+   */
+  void SendPacket (Ptr<Packet> packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol);
+  /*
+   * \brief This function is called to schedule sending packets from the network queue
+   */
+  void Scheduler (uint32_t priority);
+  /*
+   * \brief This function is called to schedule sending packets from the network queue by priority
+   */
+  void PriorityScheduler (uint32_t priority, bool continueWithFirst);
+  /*
+   * \brief This function is called to increase the retransmission timer for data packet in the network queue
+   */
+  void IncreaseRetransTimer ();
+  /*
+   * \brief This function is called to send packets down stack
+   */
+  bool SendRealDown (DsrNetworkQueueEntry & newEntry);
+  /*
    * This function is responsible for sending out data packets when have route, if no route found, it will
    * cache the packet and send out route requests
    */
-  void SendPacket (DsrOptionSRHeader const &sourceRoute,
-                   Ipv4Address nextHop,
-                   uint8_t protocol);
+  void SendPacketFromBuffer (DsrOptionSRHeader const &sourceRoute,
+                             Ipv4Address nextHop,
+                             uint8_t protocol);
   /*
    * \brief Find the similar entries in the maintenance buffer
    */
-  bool FindSamePackets (Ptr<Packet> packet, Ipv4Header const& ipv4Header, Ipv4Address source, Ipv4Address destination,
-                        uint8_t segsLeft);
+  bool FindSamePackets (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft);
   /*
    * Call the cancel packet retransmission timer function
    */
@@ -242,22 +280,28 @@
    */
   void SalvagePacket (Ptr<const Packet> packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol);
   /*
-   * Add ack request header to the data packet when need to use network acknowledgment
+   * Schedule the packet retransmission when the packet has not reached to the next hop address
    */
-  void AddAckReqHeader (Ptr<Packet> packet, DsrOptionSRHeader const &sourceRoute, Ipv4Address nextHop);
+  void SchedulePassivePacketRetry   (MaintainBuffEntry & mb,
+                                     bool onlyPassive,
+                                     uint8_t protocol);
   /*
    * Schedule the packet retransmission when the packet has not reached to the next hop address
    */
-  void SchedulePacketRetry   (MaintainBuffEntry & mb,
-                              PacketKey const & packetKey,
-                              uint8_t protocol);
+  void ScheduleNetworkPacketRetry   (MaintainBuffEntry & mb,
+                                     bool isFirst,
+                                     uint8_t protocol);
   /*
    * This function deals with packet retransmission timer expire
    */
-  void PacketScheduleTimerExpire  (MaintainBuffEntry & mb,
-                                   PacketKey const & pk,
-                                   uint8_t protocol,
-                                   bool isPassive);
+  void NetworkScheduleTimerExpire  (MaintainBuffEntry & mb,
+                                    uint8_t protocol);
+  /*
+   * This function deals with packet retransmission timer expire
+   */
+  void PassiveScheduleTimerExpire  (MaintainBuffEntry & mb,
+                                    bool onlyPassive,
+                                    uint8_t protocol);
   /*
    * Forward the packet using the route saved in the source route option header
    */
@@ -335,7 +379,7 @@
                             Ipv4Address source,
                             Ipv4Address destination,
                             Ptr<Ipv4Route> route,
-                            uint16_t hops);
+                            double hops);
   /*
    * Send network layer acknowledgment back to the earlier hop to notify the receipt of data packet
    */
@@ -394,15 +438,16 @@
   /**
    * \brief Cancel the route request timer.
    * \param dst The dst address of the route request timer
+   * \param isRemove whether to remove the route request entry or not
    */
-  void CancelRreqTimer (Ipv4Address dst);
+  void CancelRreqTimer (Ipv4Address dst, bool isRemove);
   /**
    * \brief Schedule the route request retry.
    * \param dst The dst address of the route request
    */
-  void ScheduleRreqRetry (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dst, bool nonProp, uint8_t protocol);
+  void ScheduleRreqRetry (Ptr<Packet> packet, std::vector<Ipv4Address> address, bool nonProp, uint32_t requestId, uint8_t protocol);
   // / Handle route discovery timer
-  void RouteRequestTimerExpire (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol);
+  void RouteRequestTimerExpire (Ptr<Packet> packet, std::vector<Ipv4Address> address, uint32_t requestId, uint8_t protocol);
 
 protected:
   /*
@@ -454,7 +499,11 @@
 
   Ipv4L4Protocol::DownTargetCallback m_downTarget;    // The callback for down layer
 
-  uint8_t m_discoveryHopLimit;             // / Maximum hops to go for route request
+  uint32_t m_maxNetworkSize;             // / Maximum network queue size
+
+  Time m_maxNetworkDelay;                // / Maximum network delay
+
+  uint32_t m_discoveryHopLimit;             // / Maximum hops to go for route request
 
   uint8_t m_maxSalvageCount;             // / Maximum # times to salvage a packet
 
@@ -462,7 +511,9 @@
 
   Time m_nonpropRequestTimeout;            // / The non-propagation request timeout
 
-  uint32_t  m_sendRetries;                // / # of retries have been sent for data packet
+  uint32_t m_sendRetries;                    // / # of retries have been sent for network acknowledgment
+
+  uint32_t m_passiveRetries;                 // / # of retries have been sent for passive acknowledgment
 
   uint32_t m_rreqRetries;                  // /< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
 
@@ -476,6 +527,8 @@
 
   SendBuffer m_sendBuffer;               // / The send buffer
 
+  ErrorBuffer m_errorBuffer;             // / The error buffer to save the error messages
+
   uint32_t  m_maxMaintainLen;            // / Max # of entries for maintainance buffer
 
   Time     m_maxMaintainTime;            // / Time out for maintainance buffer
@@ -490,7 +543,7 @@
 
   MaintainBuffer m_maintainBuffer;       // / The declaration of maintain buffer
 
-  uint16_t m_requestId;                  // / The id assigned to each route request
+  uint32_t m_requestId;                  // / The id assigned to each route request
 
   uint16_t m_ackId;                      // / The ack id assigned to each acknowledge
 
@@ -504,7 +557,7 @@
 
   Ipv4Address m_broadcast;                 // / The broadcast IP address
 
-  uint16_t m_broadcastJitter;              // / The max time to delay route request broadcast.
+  uint32_t m_broadcastJitter;              // / The max time to delay route request broadcast.
 
   Time  m_passiveAckTimeout;               // / The timeout value for passive acknowledge
 
@@ -522,42 +575,51 @@
 
   std::string m_cacheType;                // / The type of route cache
 
-  double m_stabilityDecrFactor;           // / The initial decrease factor for link cache
+  std::string m_routeSortType;         // / The type of route sort methods
 
-  double m_stabilityIncrFactor;           // / The initial increase factor for link cache
+  uint64_t m_stabilityDecrFactor;           // / The initial decrease factor for link cache
+
+  uint64_t m_stabilityIncrFactor;           // / The initial increase factor for link cache
 
-  double m_initStability;                 // / The initial stability value for link cache
+  Time m_initStability;                 // / The initial stability value for link cache
 
-  double m_minLifeTime;                   // / The min life time
+  Time m_minLifeTime;                   // / The min life time
 
-  double m_useExtends;                    // / The use extension of the life time for link cache
+  Time m_useExtends;                    // / The use extension of the life time for link cache
 
   bool m_subRoute;                        // / Whether to save sub route or not
 
-  std::vector<Ipv4Address> m_finalRoute; // / The route cache
+  Time m_retransIncr;                     // / the increase time for retransmission timer when face network congestion
+
+  std::vector<Ipv4Address> m_finalRoute;                 // / The route cache
 
   std::map<Ipv4Address, Timer> m_addressReqTimer;        // / Map IP address + RREQ timer.
 
   std::map<Ipv4Address, Timer> m_nonPropReqTimer;        // / Map IP address + RREQ timer.
 
-  std::map<PacketKey, Timer>  m_addressForwardTimer;   // / Map packet key + forward timer.
+  std::map<NetworkKey, Timer>  m_addressForwardTimer;    // / Map network key + forward timer.
+
+  std::map<NetworkKey, uint32_t> m_addressForwardCnt;      // / Map network key + forward counts.
 
-  std::map<PacketKey, uint32_t> m_addressForwardCnt;    // / Map packet key + forward counts.
+  std::map<PassiveKey, uint32_t> m_passiveCnt;             // / Map packet key + passive forward counts.
 
-  std::map<PacketKey, Timer> m_passiveAckTimer;               // / The timer for passive acknowledgment
+  std::map<PassiveKey, Timer> m_passiveAckTimer;         // / The timer for passive acknowledgment
 
   Ptr<dsr::RouteCache> m_routeCache;      // / A "drop-front" queue used by the routing layer to cache routes found.
 
   Ptr<dsr::RreqTable> m_rreqTable;        // / A "drop-front" queue used by the routing layer to cache route request sent.
 
+  uint32_t m_numPriorityQueues;
+
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> > m_priorityQueue;   // / priority queueus
+
   GraReply m_graReply;                    // / The gratuitous route reply.
 
   std::vector<Ipv4Address> m_clearList;   // / The node that is clear to send packet to
 
-  uint32_t m_newPacketSize;               // / The packet size of a newly created packet
-
   std::vector<Ipv4Address> m_addresses;   // / The bind ipv4 addresses with next hop, src, destination address in sequence
 };
 }  /* namespace dsr */
 }  /* namespace ns3 */
+
 #endif /* DSR_ROUTING_H */
--- a/src/dsr/model/dsr-rreq-table.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-rreq-table.cc	Sun May 06 20:52:24 2012 -0700
@@ -67,7 +67,7 @@
   Ipv4Address firstExpire;
   Time max = Seconds (0.0);
   for (std::map<Ipv4Address, RreqTableEntry >::const_iterator i =
-         rreqDstMap.begin (); i != rreqDstMap.end (); ++i)
+      rreqDstMap.begin (); i != rreqDstMap.end (); ++i)
     {
       Ipv4Address dst = i->first;
       RreqTableEntry rreqTableEntry = i->second;
@@ -83,33 +83,33 @@
 void
 RreqTable::FindAndUpdate (Ipv4Address dst)
 {
-  NS_LOG_LOGIC ("Find and update the route request entry for " << dst);
+  NS_LOG_FUNCTION (this << dst);
   std::map<Ipv4Address, RreqTableEntry >::const_iterator i =
     m_rreqDstMap.find (dst);
   if (i == m_rreqDstMap.end ())
     {
-      NS_LOG_DEBUG ("The request table entry not found");
+      NS_LOG_DEBUG ("The request table entry for " << dst << " not found");
       /*
        * Drop the most aged packet when buffer reaches to max
        */
       if (m_rreqDstMap.size () >= m_requestTableSize)
         {
           RemoveLeastExpire (m_rreqDstMap);
-          NS_LOG_DEBUG ("The request table size after erase ");
+          NS_LOG_DEBUG ("The request table size after erase " << (uint32_t)m_rreqDstMap.size ());
         }
       RreqTableEntry rreqTableEntry;
-      rreqTableEntry.m_reqNo = 0;
-      rreqTableEntry.m_expire = Simulator::Now ();
+      rreqTableEntry.m_reqNo = 1;
+      rreqTableEntry.m_expire = Simulator::Now();
       m_rreqDstMap [dst] = rreqTableEntry;
     }
   else
     {
-      NS_LOG_DEBUG ("Find the request table entry, increment the request count");
+      NS_LOG_INFO ("Find the request table entry for  " << dst << ", increment the request count");
       Ipv4Address dst = i->first;
       RreqTableEntry rreqTableEntry = i->second;
       NS_LOG_DEBUG ("The request count before incrementing " << rreqTableEntry.m_reqNo);
       rreqTableEntry.m_reqNo = (rreqTableEntry.m_reqNo + 1);
-      rreqTableEntry.m_expire = Simulator::Now ();
+      rreqTableEntry.m_expire = Simulator::Now();
       m_rreqDstMap [dst] = rreqTableEntry;
     }
 }
@@ -117,6 +117,7 @@
 void
 RreqTable::RemoveRreqEntry (Ipv4Address dst)
 {
+  NS_LOG_FUNCTION (this << dst);
   NS_LOG_DEBUG ("Remove rreq entry with index dst");
   std::map<Ipv4Address, RreqTableEntry >::const_iterator i =
     m_rreqDstMap.find (dst);
@@ -131,16 +132,15 @@
     }
 }
 
-uint16_t
+uint32_t
 RreqTable::GetRreqCnt (Ipv4Address dst)
 {
-  NS_LOG_DEBUG ("Get the request count for a certain dst");
+  NS_LOG_FUNCTION (this << dst);
   std::map<Ipv4Address, RreqTableEntry >::const_iterator i =
     m_rreqDstMap.find (dst);
   if (i == m_rreqDstMap.end ())
     {
       NS_LOG_DEBUG ("The request table entry not found");
-      FindAndUpdate (dst);
       return 0;
     }
   else
@@ -153,140 +153,14 @@
 
 // ----------------------------------------------------------------------------------------------------------
 /**
- * This part takes care of the route request from a specific source
- * need to ignore future route requests from same source for same destination with same identification
- */
-bool
-RreqTable::FindSrc (Ipv4Address source, Ipv4Address target, uint16_t id)
-{
-  Purge ();
-  std::map<Ipv4Address, std::list<SourceRreqEntry> >::const_iterator i =
-    m_rreqMap.find (source);
-  if (i == m_rreqMap.end ())
-    {
-      NS_LOG_LOGIC ("No Request entry for " << source << " found");
-      SourceRreqEntry sourceRreqEntry;
-      sourceRreqEntry.m_dst = target;
-      sourceRreqEntry.m_identification = id;
-      sourceRreqEntry.m_expire = m_rreqEntryExpire + Simulator::Now ();
-      NS_LOG_DEBUG ("The src rreq expire time " << sourceRreqEntry.m_expire);
-      std::list<SourceRreqEntry> rqVector;
-      rqVector.push_back (sourceRreqEntry);
-      m_rreqMap[source] = rqVector;
-      return false;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Request entry for " << source << " found in the cache");
-      std::list<SourceRreqEntry> rqVector = i->second;
-      for (std::list<SourceRreqEntry>::iterator j = rqVector.begin (); j != rqVector.end (); ++j)
-        {
-          SourceRreqEntry rreqEntry = *j;
-          if ((rreqEntry.m_dst == target) && (rreqEntry.m_identification == id))
-            {
-              NS_LOG_DEBUG ("Found the request entry for source node with address " << source);
-//              j = rqVector.erase (j);
-//              rqVector.push_back(*j);
-//              m_rreqMap[source] = rqVector;
-              return true;
-            }
-        }
-
-      SourceRreqEntry rreqEntry;
-      rreqEntry.m_dst = target;
-      rreqEntry.m_identification = id;
-      rreqEntry.m_expire = m_rreqEntryExpire + Simulator::Now ();
-      if (rqVector.size () >= m_requestIdSize)
-        {
-          // erase the first element when the size is larger than the request id size (default: 16)
-          rqVector.pop_front ();
-        }
-      // May need to check the size of the entry
-      rqVector.push_back (rreqEntry);
-      m_rreqMap[source] = rqVector;
-      return false;
-    }
-  return false;
-}
-
-void
-RreqTable::Purge ()
-{
-  //Trying to purge the rreq table
-  if (m_rreqMap.empty ())
-    {
-      NS_LOG_DEBUG ("The rreq table is empty");
-      return;
-    }
-
-  for (std::map<Ipv4Address, std::list<SourceRreqEntry> >::iterator i =
-         m_rreqMap.begin (); i != m_rreqMap.end (); )
-    {
-      // Loop of rreq table entry with the source entries
-      std::map<Ipv4Address, std::list<SourceRreqEntry> >::iterator itmp = i;
-      /*
-       * The rreq table entries
-       */
-      Ipv4Address dst = i->first;
-      std::list<SourceRreqEntry> rqVector = i->second;
-      NS_LOG_DEBUG ("The rqVector size for " << dst << " is " << rqVector.size ());
-      if (rqVector.size ())
-        {
-          for (std::list<SourceRreqEntry>::iterator j = rqVector.begin (); j != rqVector.end (); )
-            {
-              NS_LOG_DEBUG ("The expire time of every entry with expire time " << j->m_expire - Simulator::Now ());
-              /*
-               * First verify if the rreq table entry has expired or not
-               */
-              if (j->m_expire - Simulator::Now () <= Seconds (0))
-                {
-                  /*
-                   * When the expire time has passed, erase the certain rreq table entry
-                   */
-                  NS_LOG_DEBUG ("Erase the expired rreq table entry for " << dst << " with expire time " << j->m_expire - Simulator::Now ());
-                  j = rqVector.erase (j);
-                }
-              else
-                {
-                  ++j;
-                }
-            }
-          NS_LOG_DEBUG ("The rreq table entry for " << dst << " " << rqVector.size ());
-          if (rqVector.size ())
-            {
-              ++i;
-              m_rreqMap.erase (itmp); // erase the entry first
-              /*
-               * Save the new rreq table entry along with the destination address in map
-               */
-              std::pair<std::map<Ipv4Address, std::list<SourceRreqEntry> >::iterator, bool> result =
-                m_rreqMap.insert (std::make_pair (dst, rqVector));
-            }
-          else
-            {
-              ++i;
-              m_rreqMap.erase (itmp);
-            }
-        }
-      else
-        {
-          ++i;
-          m_rreqMap.erase (itmp);
-        }
-    }
-  return;
-}
-
-// ----------------------------------------------------------------------------------------------------------
-/**
  * This part takes care of the route request ID initialized from a specific source to one destination
  * Essentially a counter
  */
-uint16_t
+uint32_t
 RreqTable::CheckUniqueRreqId (Ipv4Address dst)
 {
   NS_LOG_DEBUG ("The size of id cache " << m_rreqIdCache.size ());
-  std::map<Ipv4Address, uint16_t>::const_iterator i =
+  std::map<Ipv4Address, uint32_t>::const_iterator i =
     m_rreqIdCache.find (dst);
   if (i == m_rreqIdCache.end ())
     {
@@ -297,10 +171,10 @@
   else
     {
       NS_LOG_LOGIC ("Request id for " << dst << " found in the cache");
-      uint16_t rreqId = m_rreqIdCache[dst];
+      uint32_t rreqId = m_rreqIdCache[dst];
       if (rreqId >= m_maxRreqId)
         {
-          NS_LOG_DEBUG ("The request id increase past the max value, so reset it to 0");
+          NS_LOG_DEBUG ("The request id increase past the max value, " << m_maxRreqId << " so reset it to 0");
           rreqId = 0;
           m_rreqIdCache[dst] = rreqId;
         }
@@ -314,7 +188,7 @@
     }
 }
 
-uint16_t
+uint32_t
 RreqTable::GetRreqSize ()
 {
   return m_rreqIdCache.size ();
--- a/src/dsr/model/dsr-rreq-table.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-rreq-table.h	Sun May 06 20:52:24 2012 -0700
@@ -67,7 +67,7 @@
  */
 struct RreqTableEntry
 {
-  uint16_t m_reqNo;
+  uint32_t m_reqNo;
   Time m_expire;
 };
 /*
@@ -76,8 +76,9 @@
  */
 struct SourceRreqEntry
 {
-  uint16_t m_identification;
+  uint32_t m_identification;
   Ipv4Address m_dst;
+  bool m_isError;
   Time m_expire;
 };
 /**
@@ -104,11 +105,11 @@
 
   // /\name Fields
   // \{
-  void SetInitHopLimit (uint8_t hl)
+  void SetInitHopLimit (uint32_t hl)
   {
     m_initHopLimit = hl;
   }
-  uint8_t GetInitHopLimit () const
+  uint32_t GetInitHopLimit () const
   {
     return m_initHopLimit;
   }
@@ -128,11 +129,11 @@
   {
     return m_requestIdSize;
   }
-  void SetUniqueRreqIdSize (uint16_t uid)
+  void SetUniqueRreqIdSize (uint32_t uid)
   {
     m_maxRreqId = uid;
   }
-  uint16_t GetUniqueRreqIdSize () const
+  uint32_t GetUniqueRreqIdSize () const
   {
     return m_maxRreqId;
   }
@@ -145,29 +146,16 @@
   // / Remove route request entry for dst
   void RemoveRreqEntry (Ipv4Address dst);
   // / Get the request count number for one destination address
-  uint16_t GetRreqCnt (Ipv4Address dst);
-
-  //----------------------------------------------------------------------------------------------------------
-  /*
-   * The following code deals with duplicate request ids
-   */
-  bool FindSrc (Ipv4Address source, Ipv4Address target, uint16_t id);
-  // / Purge the rreq table
-  void Purge ();
-  // / Set the source rreq expire time to the time of max route expire time
-  void SetRreqExpire (Time expire)
-  {
-    m_rreqEntryExpire = expire;
-  }
+  uint32_t GetRreqCnt (Ipv4Address dst);
 
   //----------------------------------------------------------------------------------------------------------
   /*
    * The following code generates new request id for each destination
    */
   // / Check for duplicate ids and save new entries if the id is not present in the table
-  uint16_t CheckUniqueRreqId (Ipv4Address dst);
+  uint32_t CheckUniqueRreqId (Ipv4Address dst);
   // / Get the request id size
-  uint16_t GetRreqSize ();
+  uint32_t GetRreqSize ();
 
   // ---------------------------------------------------------------------------------------------------------
   /*
@@ -189,6 +177,7 @@
   void PurgeNeighbor ();
 
 private:
+
   // / Timer for neighbor's list. Schedule Purge().
   Timer m_ntimer;
   // / The max # of requests to retransmit
@@ -202,19 +191,19 @@
   // / The source route entry expire time
   Time m_rreqEntryExpire;
   // / The initial hop limit
-  uint8_t m_initHopLimit;
+  uint32_t m_initHopLimit;
   // / The request table size
   uint32_t m_requestTableSize;
   // / The request source id size
   uint32_t m_requestIdSize;
   // / The unique request id for any destination
-  uint16_t m_maxRreqId;
+  uint32_t m_maxRreqId;
   // / The state of the unidirectional link
   LinkStates m_linkStates;
   // / Map of entries
   std::list<SourceRreqEntry> m_sourceRreq;
   // / The id cache to ensure all the ids are unique
-  std::map<Ipv4Address, uint16_t> m_rreqIdCache;
+  std::map<Ipv4Address, uint32_t> m_rreqIdCache;
   // / The cache to save route request table entries indexed with destination address
   std::map<Ipv4Address, RreqTableEntry > m_rreqDstMap;
   // / The cache to ensure all the route request from unique source
--- a/src/dsr/model/dsr-rsendbuff.cc	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-rsendbuff.cc	Sun May 06 20:52:24 2012 -0700
@@ -56,7 +56,7 @@
        != m_sendBuffer.end (); ++i)
     {
       NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid ()
-                                << " dst " << i->GetDestination () << " " << entry.GetDestination ());
+                   << " dst " << i->GetDestination () << " " << entry.GetDestination ());
 
       if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ())
           && (i->GetDestination () == entry.GetDestination ()))
--- a/src/dsr/model/dsr-rsendbuff.h	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/model/dsr-rsendbuff.h	Sun May 06 20:52:24 2012 -0700
@@ -51,8 +51,7 @@
     : m_packet (pa),
       m_dst (d),
       m_expire (exp + Simulator::Now ()),
-      m_protocol (p),
-      m_errHeader (false)
+      m_protocol (p)
   {
   }
   /**
@@ -97,14 +96,6 @@
   {
     return m_protocol;
   }
-  void SetErrHeader (bool e)
-  {
-    m_errHeader = e;
-  }
-  bool IsErrHeader () const
-  {
-    return m_errHeader;
-  }
   // \}
 private:
   // / Data packet
@@ -115,8 +106,6 @@
   Time m_expire;
   // / The protocol number
   uint8_t m_protocol;
-  // / bool value to test the error header
-  bool m_errHeader;
 };
 
 /**
--- a/src/dsr/wscript	Fri Jan 27 15:15:48 2012 -0800
+++ b/src/dsr/wscript	Sun May 06 20:52:24 2012 -0700
@@ -13,6 +13,8 @@
         'model/dsr-rcache.cc',
         'model/dsr-rreq-table.cc',
         'model/dsr-gratuitous-reply-table.cc',
+	'model/dsr-errorbuff.cc',
+	'model/dsr-network-queue.cc',
         'helper/dsr-helper.cc',
         'helper/dsr-main-helper.cc',
         ]
@@ -34,6 +36,8 @@
         'model/dsr-rcache.h',
         'model/dsr-rreq-table.h',
         'model/dsr-gratuitous-reply-table.h',
+	'model/dsr-errorbuff.h',
+	'model/dsr-network-queue.h',
         'helper/dsr-helper.h',
         'helper/dsr-main-helper.h',
         ]