From bd96a9afb75d55e090036e2b232e432f527bd151 Mon Sep 17 00:00:00 2001 From: Borovkova Elena Date: Mon, 17 Aug 2009 10:58:09 +0400 Subject: [PATCH] sending RERR corrected --- examples/aodv-with-interface-down.cc | 213 ++++++++++++++++++++++ src/routing/aodv/aodv-packet.cc | 4 +- src/routing/aodv/aodv-routing-protocol.cc | 43 ++++- src/routing/aodv/aodv-rtable.cc | 8 +- src/routing/aodv/aodv-rtable.h | 2 +- 5 files changed, 263 insertions(+), 7 deletions(-) create mode 100644 examples/aodv-with-interface-down.cc diff --git a/examples/aodv-with-interface-down.cc b/examples/aodv-with-interface-down.cc new file mode 100644 index 000000000..64b420249 --- /dev/null +++ b/examples/aodv-with-interface-down.cc @@ -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 + */ + +#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 +#include + +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 = nodes.Get (size/2); + Ptr ipv4 = node->GetObject (); + Simulator::Schedule (Seconds (1), &Ipv4::SetDown, ipv4, 1); +} + diff --git a/src/routing/aodv/aodv-packet.cc b/src/routing/aodv/aodv-packet.cc index 069f8a949..16593cec6 100644 --- a/src/routing/aodv/aodv-packet.cc +++ b/src/routing/aodv/aodv-packet.cc @@ -712,9 +712,9 @@ RerrHeader::AddUnDestination (Ipv4Address dst, uint32_t seqNo ) bool RerrHeader::RemoveUnDestination (std::pair & un ) { - if (GetDestCount () == 0) + if (m_unreachableDstSeqNo.empty ()) return false; - std::map::iterator i = m_unreachableDstSeqNo.end (); + std::map::iterator i = m_unreachableDstSeqNo.begin (); un = *i; m_unreachableDstSeqNo.erase (i); return true; diff --git a/src/routing/aodv/aodv-routing-protocol.cc b/src/routing/aodv/aodv-routing-protocol.cc index d4559169d..a3d3e48ee 100644 --- a/src/routing/aodv/aodv-routing-protocol.cc +++ b/src/routing/aodv/aodv-routing-protocol.cc @@ -442,6 +442,9 @@ void RoutingProtocol::NotifyInterfaceDown (uint32_t i ) { NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ()); +// Ptr socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0)); +// m_socketAddresses.erase (socket); +// m_routingTable.DeleteAllRouteFromInterface (m_ipv4->GetAddress (i, 0)); // TODO } @@ -980,11 +983,20 @@ RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiver, Ipv4Address sen 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 = Create (); packet->AddHeader (rrepHeader); TypeHeader tHeader (AODVTYPE_RREP); @@ -1040,9 +1052,14 @@ RoutingProtocol::ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiv void RoutingProtocol::RecvError (Ptr p, Ipv4Address src ) { + NS_LOG_FUNCTION (this << " from " << src); RerrHeader rerrHeader; p->RemoveHeader (rerrHeader); bool noDelete = rerrHeader.GetNoDelete (); + if (noDelete) + { + + } std::map dstWithNextHopSrc; std::map unreachable; m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc); @@ -1081,6 +1098,8 @@ RoutingProtocol::RecvError (Ptr p, Ipv4Address src ) } if (!noDelete) m_routingTable.InvalidateRoutesWithDst (unreachable); + NS_LOG_LOGIC ("After receive RERR"); + m_routingTable.Print (std::cout); } void @@ -1237,6 +1256,10 @@ RoutingProtocol::Send (Ptr route, Ptr packet, const Ipv 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 precursors; std::map unreachable; @@ -1247,6 +1270,7 @@ RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop ) 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::const_iterator i = unreachable.begin (); i != unreachable.end ();) { if (!rerrHeader.AddUnDestination (i->first, i->second)) @@ -1266,8 +1290,20 @@ RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop ) ++i; } } + if (rerrHeader.GetDestCount () != 0) + { + TypeHeader typeHeader (AODVTYPE_RERR); + Ptr packet = Create (); + 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 @@ RoutingProtocol::SendRerrMessage (Ptr packet, std::vector p 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 @@ RoutingProtocol::SendRerrMessage (Ptr packet, std::vector p m_routingTable.LookupRoute (precursors.front (), toPrecursor); Ptr 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 , Ipv4InterfaceAddress>*/ std::make_pair(socket, toPrecursor.GetInterface ()), /*dst*/precursors.front (), /*TTL*/ 1, /*id*/0); return; @@ -1328,6 +1368,7 @@ RoutingProtocol::SendRerrMessage (Ptr packet, std::vector p { Ptr socket = FindSocketWithInterfaceAddress (*i); NS_ASSERT (socket); + NS_LOG_LOGIC ("broadcast RERR meassage from interface " << i->GetLocal()); SendPacketViaRawSocket (/*packet*/packet, /*pair , Ipv4InterfaceAddress>*/ std::make_pair(socket, toPrecursor.GetInterface ()), /*dst*/m_socketAddresses[socket].GetBroadcast (), /*TTL*/ 1, /*id*/0); } diff --git a/src/routing/aodv/aodv-rtable.cc b/src/routing/aodv/aodv-rtable.cc index 6dd85a072..b06ca3f0a 100644 --- a/src/routing/aodv/aodv-rtable.cc +++ b/src/routing/aodv/aodv-rtable.cc @@ -318,13 +318,15 @@ RoutingTable::SetEntryState (Ipv4Address id, RouteFlags state ) } void -RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map unreachable ) +RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map & unreachable ) { Purge (); unreachable.clear (); for (std::map::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 diff --git a/src/routing/aodv/aodv-rtable.h b/src/routing/aodv/aodv-rtable.h index 5d2a0e422..5d73b5184 100644 --- a/src/routing/aodv/aodv-rtable.h +++ b/src/routing/aodv/aodv-rtable.h @@ -220,7 +220,7 @@ public: /** * Lookup valid routing entries with next hop Address dst and not empty list of precursors. */ - void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map unreachable); + void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map & unreachable); /** * Update routing entries with this destinations as follows: * 1. The destination sequence number of this routing entry, if it