src/dsr/model/dsr-options.cc
changeset 9293 854e085e1a01
parent 8976 4df4e7cd077f
child 9719 4031f7fdce5c
child 9782 ed82eb2702d0
--- a/src/dsr/model/dsr-options.cc	Mon Apr 08 11:54:22 2013 +0200
+++ b/src/dsr/model/dsr-options.cc	Mon Apr 08 07:26:20 2013 -0700
@@ -217,6 +217,25 @@
   return none;
 }
 
+Ipv4Address DsrOptions::ReverseSearchNextTwoHop  (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
+{
+  NS_LOG_FUNCTION (this << ipv4Address);
+  Ipv4Address nextTwoHop;
+  NS_LOG_DEBUG ("The vector size " << vec.size ());
+  NS_ASSERT (vec.size () > 2);
+  for (std::vector<Ipv4Address>::reverse_iterator ri = vec.rbegin (); ri != vec.rend (); ++ri)
+    {
+      if (ipv4Address == (*ri))
+        {
+          nextTwoHop = *(ri + 2);
+          return nextTwoHop;
+        }
+    }
+  NS_FATAL_ERROR ("next hop address not found, route corrupted");
+  Ipv4Address none = "0.0.0.0";
+  return none;
+}
+
 void DsrOptions::PrintVector (std::vector<Ipv4Address>& vec)
 {
   NS_LOG_FUNCTION (this);
@@ -240,10 +259,6 @@
 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)
@@ -384,7 +399,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionPad1::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionPad1::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
   Ptr<Packet> p = packet->Copy ();
@@ -423,7 +438,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionPadn::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionPadn::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
 
@@ -469,7 +484,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionRreq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionRreq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
   // Fields from IP header
@@ -490,7 +505,7 @@
   Ptr<Node> node = GetNodeWithAddress (ipv4Address);
   Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
 
-  Ptr<Packet> p = packet->Copy (); // The packet here doesn't contain the fixed size dsr header
+  Ptr<Packet> p = packet->Copy (); // Note: The packet here doesn't contain the fixed size dsr header
   /*
    * \brief Get the number of routers' address field before removing the header
    * \peek the packet and get the value
@@ -524,14 +539,19 @@
       m_dropTrace (packet); // call drop trace
       return 0;
     }
+  // Check the rreq id for verifying the request id
+  uint16_t requestId = rreq.GetId ();
   // The target address is where we want to send the data packets
   Ipv4Address targetAddress = rreq.GetTarget ();
   // Get the node list and source address from the route request header
   std::vector<Ipv4Address> mainVector = rreq.GetNodesAddresses ();
   std::vector<Ipv4Address> nodeList (mainVector);
+  // Get the real source address of this request, it will be used when checking if we have received the save
+  // route request before or not
+  Ipv4Address sourceAddress = nodeList.front ();
   PrintVector (nodeList);
   /*
-   * Construct the dsr routing header for future use
+   * Construct the dsr routing header for later use
    */
   DsrRoutingHeader dsrRoutingHeader;
   dsrRoutingHeader.SetNextHeader (protocol);
@@ -539,7 +559,26 @@
   dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
   dsrRoutingHeader.SetDestId (255);
 
-  if (CheckDuplicates (ipv4Address, nodeList))
+  // check whether we have received this request or not, if not, it will save the request in the table for
+  // later use, if not found, return false, and push the newly received source request entry in the cache
+
+  bool dupRequest = dsr->FindSourceEntry (sourceAddress, targetAddress, requestId);
+  /*
+   * Before processing the route request, we need to check two things
+   * 1. if this is the exact same request we have just received, ignore it
+   * 2. if our address is already in the path list, ignore it
+   * 3. otherwise process further
+   */
+  if (dupRequest)
+    {
+      NS_LOG_DEBUG ("We have received duplicate request");
+      // We have received this same route reqeust before, not forwarding it now
+      NS_LOG_LOGIC ("Duplicate request. Drop!");
+      m_dropTrace (packet); // call drop trace
+      return 0;
+    }
+
+  else if (CheckDuplicates (ipv4Address, nodeList))
     {
       /*
        * if the route contains the node address already, drop the request packet
@@ -552,6 +591,7 @@
     {
       // A node ignores all RREQs received from any node in its blacklist
       RouteCacheEntry toPrev;
+
       /*
        *  When the reverse route is created or updated, the following actions on the route are also carried out:
        *  3. the next hop in the routing table becomes the node from which the  RREQ was received
@@ -741,7 +781,7 @@
 
                   if (addRoute)
                     {
-                      NS_LOG_DEBUG ("We have added the route and search send buffer for packet with destination " << dst);
+                      NS_LOG_LOGIC ("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
                        */
@@ -935,7 +975,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionRrep::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionRrep::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
 
@@ -1134,7 +1174,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionSR::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionSR::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Address << ipv4Header << (uint32_t)protocol << isPromisc);
   Ptr<Packet> p = packet->Copy ();
@@ -1149,6 +1189,8 @@
   // The route size saved in the source route
   std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
   uint8_t segsLeft = sourceRoute.GetSegmentsLeft ();
+  /// TODO remove this one later
+  NS_LOG_DEBUG ("The segment left here " <<  (uint32_t) segsLeft);
   uint8_t salvage = sourceRoute.GetSalvage ();
   /*
    * Get the node from IP address and get the DSR extension object
@@ -1160,6 +1202,7 @@
    */
   Ipv4Address srcAddress = ipv4Header.GetSource ();
   Ipv4Address destAddress = ipv4Header.GetDestination ();
+
   // Get the node list destination
   Ipv4Address destination = nodeList.back ();
   /*
@@ -1169,26 +1212,62 @@
    */
   if (isPromisc)
     {
-      /*
-       * Get the node from Ip address and get the dsr routing object
-       */
-      Ptr<Node> node = GetNodeWithAddress (ipv4Address);
-      Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
-      bool findSame = dsr->FindSamePackets (packet, source, destination, segsLeft);
-
-      if (findSame)
-        {
-          NS_LOG_DEBUG ("Received one passive acknowledgment for a successfully delivered packet");
-        }
+      NS_LOG_LOGIC ("We process promiscuous receipt data packet");
       if (ContainAddressAfter (ipv4Address, destAddress, nodeList))
         {
-          NS_LOG_DEBUG ("Send back the gratuitous reply");
+          NS_LOG_LOGIC ("Send back the gratuitous reply");
           dsr->SendGratuitousReply (source, srcAddress, nodeList, protocol);
         }
-      else
+
+      uint16_t fragmentOffset = ipv4Header.GetFragmentOffset ();
+      uint16_t identification = ipv4Header.GetIdentification ();
+
+      /// TODO add the link ack over here
+
+      if (destAddress != destination)
         {
-          return 0;
+          NS_LOG_DEBUG ("Process the promiscuously received packet");
+          bool findPassive = false;
+          int32_t nNodes = NodeList::GetNNodes ();
+          for (int32_t i = 0; i < nNodes; ++i)
+            {
+              NS_LOG_DEBUG ("Working with node " << i);
+
+              Ptr<Node> node = NodeList::GetNode (i);
+              Ptr<dsr::DsrRouting> dsrNode = node->GetObject<dsr::DsrRouting> ();
+              // The source and destination addresses here are the real source and destination for the packet
+              findPassive = dsrNode->PassiveEntryCheck (packet, source, destination, segsLeft, fragmentOffset, identification, false);
+              if (findPassive)
+                {
+                  break;
+                }
+            }
+
+          if (findPassive)
+            {
+              NS_LOG_DEBUG ("We find one previously received passive entry");
+              /*
+               * Get the node from IP address and get the DSR extension object
+               * the srcAddress would be the source address from ip header
+               */
+              PrintVector (nodeList);
+
+              NS_LOG_DEBUG ("promisc source " << promiscSource);
+              Ptr<Node> node = GetNodeWithAddress (promiscSource);
+              Ptr<dsr::DsrRouting> dsrSrc = node->GetObject<dsr::DsrRouting> ();
+
+              /// TODO need to think about this part
+              /// TODO this is temporarily disabled to enable other
+              dsrSrc->CancelPassiveTimer (packet, source, destination, segsLeft);
+            }
+          else
+            {
+              NS_LOG_DEBUG ("Saved the entry for further use");
+              dsr->PassiveEntryCheck (packet, source, destination, segsLeft, fragmentOffset, identification, true);
+            }
         }
+      /// Safely terminate promiscuously received packet
+      return 0;
     }
   else
     {
@@ -1205,23 +1284,40 @@
       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);
+      /// When the option type is 160, means there is ACK request header after the source route, we need
+      /// to send back acknowledgment
       if (optionType == 160)
         {
-          NS_LOG_DEBUG ("Here we remove the ack request header and add ack header to the packet");
+          NS_LOG_LOGIC ("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
+           * If the node list is not empty, find the previous hop from the node list,
+           * otherwise, use srcAddress
            */
-          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);
+          Ipv4Address ackAddress = srcAddress;
+          if (!nodeList.empty ())
+            {
+                if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total number of ip addresses
+                  {
+                    NS_LOG_LOGIC ("Malformed header. Drop!");
+                    m_dropTrace (packet);
+                    return 0;
+                  }
+                if (numberAddress - segsLeft - 2 < 0) // The index is invalid
+                   {
+                      NS_LOG_LOGIC ("Malformed header. Drop!");
+                      m_dropTrace (packet);
+                      return 0;
+                   }
+                   ackAddress = nodeList[numberAddress - segsLeft - 2];
+            }
+           m_ipv4Route = SetRoute (ackAddress, ipv4Address);
+           NS_LOG_DEBUG ("Send back ACK to the earlier hop " << ackAddress << " from us " << ipv4Address);
+           dsr->SendAck (ackId, ackAddress, 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
@@ -1325,7 +1421,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionRerr::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionRerr::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
   Ptr<Packet> p = packet->Copy ();
@@ -1356,7 +1452,7 @@
       Ipv4Address unreachAddress = rerrUnreach.GetUnreachNode ();
       Ipv4Address errorSource = rerrUnreach.GetErrorSrc ();
 
-      NS_LOG_DEBUG ("The destination address and the unreachable node " << rerrUnreach.GetErrorDst () << " " << unreachAddress);
+      NS_LOG_DEBUG ("The error source is " <<  rerrUnreach.GetErrorDst () << "and the unreachable node is " << unreachAddress);
       /*
        * Get the serialized size of the rerr header
        */
@@ -1504,7 +1600,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionAckReq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionAckReq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
   /*
@@ -1524,9 +1620,6 @@
 
   NS_LOG_DEBUG ("The next header value " << (uint32_t)protocol);
 
-  Ipv4Address srcAddress = ipv4Header.GetSource ();
-  SetRoute (srcAddress, ipv4Address);
-
   return ackReq.GetSerializedSize ();
 }
 
@@ -1562,7 +1655,7 @@
   return OPT_NUMBER;
 }
 
-uint8_t DsrOptionAck::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc)
+uint8_t DsrOptionAck::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
 {
   NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
   /*