sending RERR corrected
authorBorovkova Elena <borovkovaes@iitp.ru>
Mon, 17 Aug 2009 10:58:09 +0400
changeset 5665 787190c03dd0
parent 5664 90aae51a4227
child 5666 e22f5d735495
sending RERR corrected
examples/aodv-with-interface-down.cc
src/routing/aodv/aodv-packet.cc
src/routing/aodv/aodv-routing-protocol.cc
src/routing/aodv/aodv-rtable.cc
src/routing/aodv/aodv-rtable.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/aodv-with-interface-down.cc	Mon Aug 17 10:58:09 2009 +0400
@@ -0,0 +1,213 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * 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
+ *
+ * This is an example script for AODV manet routing protocol. 
+ *
+ * Authors: Pavel Boyko <boyko@iitp.ru>
+ */
+
+#include "ns3/aodv-module.h"
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/contrib-module.h"
+#include "ns3/wifi-module.h" 
+#include "ns3/v4ping-helper.h"
+#include <iostream>
+#include <cmath>
+
+using namespace ns3;
+
+/**
+ * \brief Test script.
+ * 
+ * This script creates 1-dimensional grid topology and then ping last node from the first one:
+ * 
+ * [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.04]
+ * 
+ * ping 10.0.0.4
+ */
+class AodvExample 
+{
+public:
+  AodvExample ();
+  /// Configure script parameters, \return true on successful configuration
+  bool Configure (int argc, char **argv);
+  /// Run simulation
+  void Run ();
+  /// Report results
+  void Report (std::ostream & os);
+  
+private:
+  ///\name parameters
+  //\{
+  /// Number of nodes
+  uint32_t size;
+  /// Distance between nodes, meters
+  double step;
+  /// Simulation time, seconds
+  double totalTime;
+  /// Write per-device PCAP traces if true
+  bool pcap;
+  //\}
+  
+  ///\name network
+  //\{
+  NodeContainer nodes;
+  NetDeviceContainer devices;
+  Ipv4InterfaceContainer interfaces;
+  //\}
+  
+private:
+  void CreateNodes ();
+  void CreateDevices ();
+  void InstallInternetStack ();
+  void InstallApplications ();
+};
+
+int main (int argc, char **argv)
+{
+  AodvExample test;
+  if (! test.Configure(argc, argv)) 
+    NS_FATAL_ERROR ("Configuration failed. Aborted.");
+  
+  test.Run ();
+  test.Report (std::cout);
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+AodvExample::AodvExample () :
+  size (4),
+  step (120),
+  totalTime (10),
+  pcap (true)
+{
+}
+
+bool
+AodvExample::Configure (int argc, char **argv)
+{
+  // Enable AODV logs by default. Comment this if too noisy
+  // LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
+  
+  SeedManager::SetSeed(12345);
+  CommandLine cmd;
+  
+  cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
+  cmd.AddValue ("size", "Number of nodes.", size);
+  cmd.AddValue ("time", "Simulation time, s.", totalTime);
+  cmd.AddValue ("step", "Grid step, m", step);
+  
+  cmd.Parse (argc, argv);
+  return true;
+}
+
+void
+AodvExample::Run ()
+{
+//  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1)); // enable rts cts all the time.
+  CreateNodes ();
+  CreateDevices ();
+  InstallInternetStack ();
+  InstallApplications ();
+  
+  std::cout << "Starting simulation for " << totalTime << " s ...\n";
+  
+  Simulator::Stop (Seconds (totalTime));
+  Simulator::Run ();
+  Simulator::Destroy ();
+}
+
+void
+AodvExample::Report (std::ostream &)
+{ 
+}
+
+void
+AodvExample::CreateNodes ()
+{
+  std::cout << "Creating " << (unsigned)size << " nodes " << step << " m apart.\n";
+  nodes.Create (size);
+  // Name nodes
+  for (uint32_t i = 0; i < size; ++i)
+     {
+       std::ostringstream os;
+       os << "node-" << i;
+       Names::Add (os.str (), nodes.Get (i));
+     }
+  // Create static grid
+  MobilityHelper mobility;
+  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
+                                "MinX", DoubleValue (0.0),
+                                "MinY", DoubleValue (0.0),
+                                "DeltaX", DoubleValue (step),
+                                "DeltaY", DoubleValue (0),
+                                "GridWidth", UintegerValue (size),
+                                "LayoutType", StringValue ("RowFirst"));
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+  mobility.Install (nodes);
+}
+
+void
+AodvExample::CreateDevices ()
+{
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+  wifiMac.SetType ("ns3::AdhocWifiMac");
+  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+  wifiPhy.SetChannel (wifiChannel.Create ());
+  WifiHelper wifi = WifiHelper::Default ();
+  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("wifia-6mbs"), "RtsCtsThreshold", UintegerValue (0));
+  devices = wifi.Install (wifiPhy, wifiMac, nodes); 
+  
+  if (pcap)
+    {
+      wifiPhy.EnablePcapAll (std::string ("aodv"));
+    }
+}
+
+void
+AodvExample::InstallInternetStack ()
+{
+  AodvHelper aodv;
+  // you can configure AODV attributes here using aodv.Set(name, value)
+  InternetStackHelper stack;
+  stack.SetRoutingHelper (aodv);
+  stack.Install (nodes);
+  Ipv4AddressHelper address;
+  address.SetBase ("10.0.0.0", "255.0.0.0");
+  interfaces = address.Assign (devices);
+}
+
+void
+AodvExample::InstallApplications ()
+{
+  V4PingHelper ping (interfaces.GetAddress(size - 1));
+  ping.SetAttribute ("Verbose", BooleanValue (true));
+  
+  ApplicationContainer p = ping.Install (nodes.Get (0));
+  p.Start (Seconds (0));
+  p.Stop (Seconds (totalTime));
+
+  Ptr<Node> node = nodes.Get (size/2);
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Simulator::Schedule (Seconds (1), &Ipv4::SetDown, ipv4, 1);
+}
+
--- a/src/routing/aodv/aodv-packet.cc	Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-packet.cc	Mon Aug 17 10:58:09 2009 +0400
@@ -712,9 +712,9 @@
 bool
 RerrHeader::RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un )
 {
-  if (GetDestCount () == 0)
+  if (m_unreachableDstSeqNo.empty ())
     return false;
-  std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.end ();
+  std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.begin ();
   un = *i;
   m_unreachableDstSeqNo.erase (i);
   return true;
--- a/src/routing/aodv/aodv-routing-protocol.cc	Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-routing-protocol.cc	Mon Aug 17 10:58:09 2009 +0400
@@ -442,6 +442,9 @@
 RoutingProtocol::NotifyInterfaceDown (uint32_t i )
 {
   NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
+//  Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
+//  m_socketAddresses.erase (socket);
+//  m_routingTable.DeleteAllRouteFromInterface (m_ipv4->GetAddress (i, 0));
   // TODO
 }
 
@@ -980,11 +983,20 @@
   m_routingTable.LookupRoute (rrepHeader.GetDst (), toDst);
   toDst.InsertPrecursor (toOrigin.GetNextHop ());
   m_routingTable.Update (toDst);
+
   RoutingTableEntry toNextHopToDst;
   m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
   toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
   m_routingTable.Update (toNextHopToDst);
 
+  toOrigin.InsertPrecursor (toDst.GetNextHop ());
+  m_routingTable.Update (toOrigin);
+
+  RoutingTableEntry toNextHopToOrigin;
+  m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
+  toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
+  m_routingTable.Update (toNextHopToOrigin);
+
   Ptr<Packet> packet = Create<Packet> ();
   packet->AddHeader (rrepHeader);
   TypeHeader tHeader (AODVTYPE_RREP);
@@ -1040,9 +1052,14 @@
 void
 RoutingProtocol::RecvError (Ptr<Packet> p, Ipv4Address src )
 {
+  NS_LOG_FUNCTION (this << " from " << src);
   RerrHeader rerrHeader;
   p->RemoveHeader (rerrHeader);
   bool noDelete = rerrHeader.GetNoDelete ();
+  if (noDelete)
+    {
+
+    }
   std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
   std::map<Ipv4Address, uint32_t> unreachable;
   m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
@@ -1081,6 +1098,8 @@
     }
   if (!noDelete)
     m_routingTable.InvalidateRoutesWithDst (unreachable);
+  NS_LOG_LOGIC ("After receive RERR");
+  m_routingTable.Print (std::cout);
 }
 
 void
@@ -1237,6 +1256,10 @@
 void
 RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop )
 {
+  NS_LOG_FUNCTION (this << nextHop);
+  NS_LOG_LOGIC ("Before send RERR");
+  m_routingTable.Print(std::cout);
+
   RerrHeader rerrHeader;
   std::vector<Ipv4Address> precursors;
   std::map<Ipv4Address, uint32_t> unreachable;
@@ -1247,6 +1270,7 @@
   toNextHop.GetPrecursors (precursors);
   rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
   m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
+  NS_LOG_LOGIC ("number of unreachable destination " << unreachable.size ());
   for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i != unreachable.end ();)
     {
       if (!rerrHeader.AddUnDestination (i->first, i->second))
@@ -1266,8 +1290,20 @@
           ++i;
         }
     }
+  if (rerrHeader.GetDestCount () != 0)
+    {
+      TypeHeader typeHeader (AODVTYPE_RERR);
+      Ptr<Packet> packet = Create<Packet> ();
+      packet->AddHeader (rerrHeader);
+      packet->AddHeader (typeHeader);
+      NS_LOG_DEBUG ("RERR header");
+      rerrHeader.Print(std::cout);
+      SendRerrMessage (packet, precursors);
+    }
   unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
   m_routingTable.InvalidateRoutesWithDst (unreachable);
+  NS_LOG_LOGIC ("After send RERR");
+  m_routingTable.Print(std::cout);
 }
 
 void
@@ -1293,7 +1329,10 @@
   NS_LOG_FUNCTION(this);
 
   if (precursors.empty ())
-    return; // TODO too many unreachable destinations, but no precursors
+    {
+      NS_LOG_LOGIC ("No precursors");
+      return; // TODO too many unreachable destinations, but no precursors
+    }
   // If there is only one precursor, RERR SHOULD be unicast toward that precursor
   if (precursors.size () == 1)
     {
@@ -1301,6 +1340,7 @@
       m_routingTable.LookupRoute (precursors.front (), toPrecursor);
       Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
       NS_ASSERT (socket);
+      NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination() << " from " << toPrecursor.GetInterface ().GetLocal ());
       SendPacketViaRawSocket (/*packet*/packet, /*pair<Ptr<Socket> , Ipv4InterfaceAddress>*/ std::make_pair(socket, toPrecursor.GetInterface ()),
                                /*dst*/precursors.front (), /*TTL*/ 1, /*id*/0);
       return;
@@ -1328,6 +1368,7 @@
     {
       Ptr<Socket> socket = FindSocketWithInterfaceAddress (*i);
       NS_ASSERT (socket);
+      NS_LOG_LOGIC ("broadcast RERR meassage from interface " << i->GetLocal());
       SendPacketViaRawSocket (/*packet*/packet, /*pair<Ptr<Socket> , Ipv4InterfaceAddress>*/ std::make_pair(socket, toPrecursor.GetInterface ()),
                                /*dst*/m_socketAddresses[socket].GetBroadcast (), /*TTL*/ 1, /*id*/0);
     }
--- a/src/routing/aodv/aodv-rtable.cc	Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-rtable.cc	Mon Aug 17 10:58:09 2009 +0400
@@ -318,13 +318,15 @@
 }
 
 void
-RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> unreachable )
+RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
 {
   Purge ();
   unreachable.clear ();
   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
-    if ((i->second.GetNextHop () == nextHop) && (i->second.GetFlag () == VALID) && (!i->second.IsPrecursorListEmpty ()))
-      unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
+      if ((i->second.GetNextHop () == nextHop) && (i->second.GetFlag () == VALID) /*&& (!i->second.IsPrecursorListEmpty ())*/)
+        {
+          unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
+        }
 }
 
 void
--- a/src/routing/aodv/aodv-rtable.h	Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-rtable.h	Mon Aug 17 10:58:09 2009 +0400
@@ -220,7 +220,7 @@
   /**
    * Lookup valid routing entries with next hop Address dst and not empty list of precursors.
    */
-  void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> unreachable);
+  void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable);
   /**
    *   Update routing entries with this destinations as follows:
    *  1. The destination sequence number of this routing entry, if it