From 00f4f789b3d8718e9335d28c55e77a85f4bbbe87 Mon Sep 17 00:00:00 2001 From: Borovkova Elena Date: Tue, 21 Jul 2009 19:06:06 +0400 Subject: [PATCH] control of duplicated packet added --- examples/aodv2.cc | 213 +++++++++++++ examples/wscript | 3 + src/routing/aodv/aodv-routing-protocol.cc | 346 +++++++++++----------- src/routing/aodv/aodv-routing-protocol.h | 23 ++ 4 files changed, 407 insertions(+), 178 deletions(-) create mode 100644 examples/aodv2.cc diff --git a/examples/aodv2.cc b/examples/aodv2.cc new file mode 100644 index 000000000..78bea147f --- /dev/null +++ b/examples/aodv2.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 devices1; + NetDeviceContainer devices2; + Ipv4InterfaceContainer interfaces1; + Ipv4InterfaceContainer interfaces2; + //\} + +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 (150), + 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 () +{ + 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")); + devices1 = wifi.Install (wifiPhy, wifiMac, nodes); + devices2 = 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"); + interfaces1 = address.Assign (devices1); + interfaces2 = address.Assign (devices2); + +} + +void +AodvExample::InstallApplications () +{ + V4PingHelper ping (interfaces2.GetAddress(size - 1)); + ping.SetAttribute ("Verbose", BooleanValue (true)); + + ApplicationContainer p = ping.Install (nodes.Get (0)); + p.Start (Seconds (0)); + p.Stop (Seconds (totalTime)); +} + diff --git a/examples/wscript b/examples/wscript index d678ad31d..7fb4a5de1 100644 --- a/examples/wscript +++ b/examples/wscript @@ -3,6 +3,9 @@ def build(bld): obj = bld.create_ns3_program('aodv') obj.source = 'aodv.cc' + + obj = bld.create_ns3_program('aodv2') + obj.source = 'aodv2.cc' # obj = bld.create_ns3_program('hello-simulator') # obj.source = 'hello-simulator.cc' diff --git a/src/routing/aodv/aodv-routing-protocol.cc b/src/routing/aodv/aodv-routing-protocol.cc index 815505e61..6a5908fdc 100644 --- a/src/routing/aodv/aodv-routing-protocol.cc +++ b/src/routing/aodv/aodv-routing-protocol.cc @@ -58,18 +58,17 @@ NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol); void RoutingProtocol::InsertBroadcastId (Ipv4Address id, uint32_t bid) { + NS_LOG_FUNCTION(this); if (LookupBroadcastId (id, bid)) return; - struct BroadcastId broadcastId = - { id, bid, BCAST_ID_SAVE + Simulator::Now () }; + struct BroadcastId broadcastId = { id, bid, BCAST_ID_SAVE + Simulator::Now () }; m_broadcastIdCache.push_back (broadcastId); } bool RoutingProtocol::LookupBroadcastId (Ipv4Address id, uint32_t bid) { PurgeBroadcastId (); - std::vector::const_iterator i; - for (i = m_broadcastIdCache.begin (); i != m_broadcastIdCache.end (); ++i) + for (std::vector::const_iterator i = m_broadcastIdCache.begin (); i != m_broadcastIdCache.end (); ++i) if (i->src == id && i->id == bid) return true; return false; @@ -78,19 +77,45 @@ void RoutingProtocol::PurgeBroadcastId () { NS_LOG_FUNCTION(this); - std::vector::iterator i = remove_if ( - m_broadcastIdCache.begin (), m_broadcastIdCache.end (), IsExpired ()); + std::vector::iterator i = remove_if (m_broadcastIdCache.begin (), m_broadcastIdCache.end (), IsExpired ()); m_broadcastIdCache.erase (i, m_broadcastIdCache.end ()); } +void +RoutingProtocol::InsertPacketUid(Ipv4Address src, uint32_t uid) +{ + NS_LOG_FUNCTION(this); + if (LookupPacketUid (src, uid)) + return; + struct PacketUid packetUid = { src, uid, BCAST_ID_SAVE + Simulator::Now () }; + m_packetUidCache.push_back (packetUid); +} +bool +RoutingProtocol::LookupPacketUid(Ipv4Address src, uint32_t uid) +{ + PurgePacketUid (); + for (std::vector::const_iterator i = m_packetUidCache.begin (); i != m_packetUidCache.end (); ++i) + if (i->m_src == src && i->m_uid == uid) + { + NS_LOG_LOGIC("duplicated packet from " << src << " uid " << uid); + return true; + } + return false; +} + +void +RoutingProtocol::PurgePacketUid () +{ + NS_LOG_FUNCTION(this); + std::vector::iterator i = remove_if (m_packetUidCache.begin (), m_packetUidCache.end (), IsExpiredForPacket ()); + m_packetUidCache.erase (i, m_packetUidCache.end ()); +} + RoutingProtocol::RoutingProtocol () : - RTQ_TIMEOUT (Seconds (30)), RREQ_RETRIES (2), ACTIVE_ROUTE_TIMEOUT (Seconds ( - 3)), MY_ROUTE_TIMEOUT (Scalar (2) * ACTIVE_ROUTE_TIMEOUT), NET_DIAMETER ( - 35), NODE_TRAVERSAL_TIME (MilliSeconds (40)), ALLOWED_HELLO_LOSS (2), - BAD_LINK_LIFETIME (Seconds (3)), FREQUENCY (Seconds (0.5)), - m_broadcastID (0), m_seqNo (0), btimer (Timer::CANCEL_ON_DESTROY), - htimer (Timer::CANCEL_ON_DESTROY), ntimer (Timer::CANCEL_ON_DESTROY), - rtimer (Timer::CANCEL_ON_DESTROY), lrtimer (Timer::CANCEL_ON_DESTROY) + RTQ_TIMEOUT (Seconds (30)), RREQ_RETRIES (2), ACTIVE_ROUTE_TIMEOUT (Seconds (3)), MY_ROUTE_TIMEOUT (Scalar (2) * ACTIVE_ROUTE_TIMEOUT), + NET_DIAMETER (35), NODE_TRAVERSAL_TIME (MilliSeconds (40)), ALLOWED_HELLO_LOSS (2), BAD_LINK_LIFETIME (Seconds (3)), FREQUENCY (Seconds (0.5)), + m_broadcastID (0), m_seqNo (0), btimer (Timer::CANCEL_ON_DESTROY), htimer (Timer::CANCEL_ON_DESTROY), ntimer (Timer::CANCEL_ON_DESTROY), + rtimer (Timer::CANCEL_ON_DESTROY), lrtimer (Timer::CANCEL_ON_DESTROY) { NET_TRAVERSAL_TIME = Scalar (2 * NET_DIAMETER) * NODE_TRAVERSAL_TIME; @@ -102,29 +127,17 @@ RoutingProtocol::RoutingProtocol () : TypeId RoutingProtocol::GetTypeId (void) { - static TypeId - tid = - TypeId ("ns3::aodv::RoutingProtocol") .SetParent () .AddConstructor< - RoutingProtocol> () .AddAttribute ("HelloInterval", - "HELLO messages emission interval.", TimeValue (Seconds (1)), - MakeTimeAccessor (&RoutingProtocol::HELLO_INTERVAL), - MakeTimeChecker ()) .AddAttribute ("Broadcast id save", - "Broadcast id save interval.", TimeValue (Seconds (6)), - MakeTimeAccessor (&RoutingProtocol::BCAST_ID_SAVE), - MakeTimeChecker ()) .AddAttribute ("RreqRetries", - "Maximum number of retransmissions of RREQ to discover a route", - UintegerValue (2), MakeUintegerAccessor ( - &RoutingProtocol::RREQ_RETRIES), - MakeUintegerChecker ()) .AddAttribute ( - "NodeTraversalTime", - "Conservative estimate of the average one hop traversal time for packets and should include" - "queuing delays, interrupt processing times and transfer times.", - TimeValue (MilliSeconds (40)), MakeTimeAccessor ( - &RoutingProtocol::NODE_TRAVERSAL_TIME), MakeTimeChecker ()) .AddAttribute ( - "ActiveRouteTimeout", - "Period of time during which the route is considered to be valid", - TimeValue (Seconds (3)), MakeTimeAccessor ( - &RoutingProtocol::ACTIVE_ROUTE_TIMEOUT), MakeTimeChecker ()) + static TypeId tid = TypeId ("ns3::aodv::RoutingProtocol") .SetParent () .AddConstructor () .AddAttribute ( + "HelloInterval", "HELLO messages emission interval.", TimeValue (Seconds (1)), MakeTimeAccessor (&RoutingProtocol::HELLO_INTERVAL), + MakeTimeChecker ()) .AddAttribute ("Broadcast id save", "Broadcast id save interval.", TimeValue (Seconds (6)), MakeTimeAccessor ( + &RoutingProtocol::BCAST_ID_SAVE), MakeTimeChecker ()) .AddAttribute ("RreqRetries", + "Maximum number of retransmissions of RREQ to discover a route", UintegerValue (2), MakeUintegerAccessor (&RoutingProtocol::RREQ_RETRIES), + MakeUintegerChecker ()) .AddAttribute ("NodeTraversalTime", + "Conservative estimate of the average one hop traversal time for packets and should include" + "queuing delays, interrupt processing times and transfer times.", TimeValue (MilliSeconds (40)), MakeTimeAccessor ( + &RoutingProtocol::NODE_TRAVERSAL_TIME), MakeTimeChecker ()) .AddAttribute ("ActiveRouteTimeout", + "Period of time during which the route is considered to be valid", TimeValue (Seconds (3)), MakeTimeAccessor ( + &RoutingProtocol::ACTIVE_ROUTE_TIMEOUT), MakeTimeChecker ()) ; return tid; @@ -137,8 +150,7 @@ void RoutingProtocol::DoDispose () { m_ipv4 = 0; - for (std::map , Ipv4InterfaceAddress>::iterator iter = - m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++) + for (std::map , Ipv4InterfaceAddress>::iterator iter = m_socketAddresses.begin (); iter != m_socketAddresses.end (); iter++) { iter->first->Close (); } @@ -159,28 +171,24 @@ RoutingProtocol::Start () continue; // Create a socket to listen only on this interface - Ptr socket = Socket::CreateSocket (GetObject (), - TypeId::LookupByName ("ns3::UdpSocketFactory")); + Ptr socket = Socket::CreateSocket (GetObject (), TypeId::LookupByName ("ns3::UdpSocketFactory")); NS_ASSERT (socket != 0); - int status = - socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); + int status = socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); NS_ASSERT (status != -1); socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); - status = socket->Connect (InetSocketAddress (iface.GetBroadcast (), - AODV_PORT)); + status = socket->Connect (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); NS_ASSERT (status != -1); m_socketAddresses.insert (std::make_pair (socket, iface)); NS_LOG_INFO ("Interface " << iface << " used by AODV"); // Add local broadcast record to the routing table - Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress ( - iface.GetLocal ())); + Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), - /*know seqno=*/true, /*seqno=*/0, - /*iface=*/iface.GetLocal (), - /*hops=*/1, - /*next hop=*/iface.GetBroadcast (), - /*lifetime=*/Seconds (1e9)); // TODO use infty + /*know seqno=*/true, /*seqno=*/0, + /*iface=*/iface.GetLocal (), + /*hops=*/1, + /*next hop=*/iface.GetBroadcast (), + /*lifetime=*/Seconds (1e9)); // TODO use infty m_routingTable.AddRoute (rt); } @@ -190,8 +198,7 @@ RoutingProtocol::Start () } Ptr -RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header, - uint32_t oif, Socket::SocketErrno &sockerr) +RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &sockerr) { NS_LOG_FUNCTION (this << p->GetUid() << header.GetDestination()); Ptr rtentry; @@ -205,7 +212,7 @@ RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header, rtentry = rt.GetRoute (); NS_ASSERT (rtentry != 0); sockerr = Socket::ERROR_NOTERROR; - NS_LOG_LOGIC("exist route to " << rtentry->GetDestination()); + NS_LOG_LOGIC("exist route to " << rtentry->GetDestination() << " from iface " << rtentry->GetSource()); return rtentry; } else @@ -220,8 +227,7 @@ RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header, } bool -RoutingProtocol::RouteInput (Ptr p, const Ipv4Header &header, - Ptr idev, UnicastForwardCallback ucb, +RoutingProtocol::RouteInput (Ptr p, const Ipv4Header &header, Ptr idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) { NS_LOG_FUNCTION (this << p->GetUid() << header.GetDestination() << idev->GetAddress()); @@ -229,30 +235,37 @@ RoutingProtocol::RouteInput (Ptr p, const Ipv4Header &header, NS_ASSERT (m_ipv4 != 0); // Check if input device supports IP NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); - uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); + int32_t iif = m_ipv4->GetInterfaceForDevice (idev); Ipv4Address dst = header.GetDestination (); + Ipv4Address src = header.GetSource (); + + if (IsMyOwnPacket (src)) return true; // Local delivery to AODV interfaces - for (std::map , Ipv4InterfaceAddress>::const_iterator j = - m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + { + Ipv4InterfaceAddress iface = j->second; + if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif) + if (dst == iface.GetBroadcast ()) + { + if(LookupPacketUid(src, p->GetUid())) return true; + InsertPacketUid(src, p->GetUid()); + NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ()); + lcb (p, header, iif); + // TODO has TTL, forward + return true; + } + } + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) { Ipv4InterfaceAddress iface = j->second; - if (dst == iface.GetLocal ()) { NS_LOG_LOGIC ("Unicast local delivery to " << iface.GetLocal ()); lcb (p, header, iif); return true; } - if (dst == iface.GetBroadcast ()) - { - NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ()); - // TODO not duplicate - lcb (p, header, iif); - // TODO has TTL, forward - return true; - } } // TODO: local delivery to non-AODV interfaces @@ -287,7 +300,7 @@ RoutingProtocol::RouteInput (Ptr p, const Ipv4Header &header, void RoutingProtocol::SetIpv4 (Ptr ipv4) { - NS_LOG_FUNCTION (this); NS_ASSERT (ipv4 != 0); NS_ASSERT (m_ipv4 == 0); + NS_LOG_FUNCTION (this);NS_ASSERT (ipv4 != 0);NS_ASSERT (m_ipv4 == 0); btimer.SetFunction (&RoutingProtocol::BroadcastTimerExpire, this); ntimer.SetFunction (&RoutingProtocol::NeighborTimerExpire, this); @@ -317,26 +330,37 @@ RoutingProtocol::NotifyInterfaceDown (uint32_t i) } void -RoutingProtocol::NotifyAddAddress (uint32_t interface, - Ipv4InterfaceAddress address) +RoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) { } void -RoutingProtocol::NotifyRemoveAddress (uint32_t interface, - Ipv4InterfaceAddress address) +RoutingProtocol::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) { } bool -RoutingProtocol::LooksLikeAodvControl (Ptr p, - Ipv4Header const & header) const +RoutingProtocol::LooksLikeAodvControl (Ptr p, Ipv4Header const & header) const { if (header.GetProtocol () == 17 /*UDP*/) { UdpHeader uh; - return (p->PeekHeader (uh) && uh.GetDestinationPort () == AODV_PORT - && uh.GetSourcePort () == AODV_PORT); + return (p->PeekHeader (uh) && uh.GetDestinationPort () == AODV_PORT && uh.GetSourcePort () == AODV_PORT); + } + return false; +} + +bool +RoutingProtocol::IsMyOwnPacket (Ipv4Address src) +{ + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + { + Ipv4InterfaceAddress iface = j->second; + if (src == iface.GetLocal ()) + { + NS_LOG_LOGIC(iface.GetLocal() << " receive own packet"); + return true; + } } return false; } @@ -366,8 +390,7 @@ RoutingProtocol::SendRequest (Ipv4Address dst, bool G, bool D) else { rreqHeader.SetUnknownSeqno (true); - RoutingTableEntry newEntry (dev, dst, false, 0, Ipv4Address (), 0, - Ipv4Address (), Simulator::Now ()); + RoutingTableEntry newEntry (dev, dst, false, 0, Ipv4Address (), 0, Ipv4Address (), Simulator::Now ()); newEntry.IncrementRreqCnt (); newEntry.SetFlag (RTF_IN_SEARCH); m_routingTable.AddRoute (newEntry); @@ -386,8 +409,7 @@ RoutingProtocol::SendRequest (Ipv4Address dst, bool G, bool D) // Send RREQ as subnet directed broadcast from each (own) interface Ptr packet = Create (); - for (std::map , Ipv4InterfaceAddress>::const_iterator j = - m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) { Ptr socket = j->first; Ipv4InterfaceAddress iface = j->second; @@ -399,7 +421,7 @@ RoutingProtocol::SendRequest (Ipv4Address dst, bool G, bool D) packet->AddHeader (tHeader); socket->Send (packet); } - htimer.Schedule (); + htimer.Schedule (HELLO_INTERVAL); } void @@ -411,8 +433,7 @@ RoutingProtocol::RecvAodv (Ptr socket) Address sourceAddress; packet = socket->RecvFrom (sourceAddress); - InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom ( - sourceAddress); + InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress); NS_ASSERT (inetSourceAddr.GetPort () == AODV_PORT); Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 (); Ipv4Address receiverIfaceAddr = m_socketAddresses[socket].GetLocal (); @@ -479,8 +500,7 @@ RoutingProtocol::UpdateNeighbor (Ipv4Address sender, Ipv4Address receiver) } void -RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, - Ipv4Address src, Ptr socket) +RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, Ipv4Address src, Ptr socket) { NS_LOG_FUNCTION (this << receiver << src); @@ -505,30 +525,27 @@ RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, rreqHeader.SetHopCount (hop); // Reverse route to the Originator IP Address is created, or updating +// UpdateRoute(Ipv4Address dst, ) Ptr dev; RoutingTableEntry toOrigin (dev); if (!m_routingTable.LookupRoute (origin, toOrigin)) { dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)); RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/origin, /*validSeno=*/ - true, /*seqNo=*/rreqHeader.GetOriginSeqno (), - /*iface=*/receiver, /*hops=*/hop, /*nextHop*/src, - /*timeLife=*/Simulator::Now () + Scalar (2) * NET_TRAVERSAL_TIME - - Scalar (2 * hop) * NODE_TRAVERSAL_TIME); + true, /*seqNo=*/rreqHeader.GetOriginSeqno (), + /*iface=*/receiver, /*hops=*/hop, /*nextHop*/src, + /*timeLife=*/Simulator::Now () + Scalar (2) * NET_TRAVERSAL_TIME - Scalar (2 * hop) * NODE_TRAVERSAL_TIME); m_routingTable.AddRoute (newEntry); } else { - if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) - > 0) + if (int32_t (rreqHeader.GetOriginSeqno ()) - int32_t (toOrigin.GetSeqNo ()) > 0) toOrigin.SetSeqNo (rreqHeader.GetOriginSeqno ()); toOrigin.SetValidSeqNo (true); toOrigin.SetNextHop (src); - toOrigin.SetOutputDevice (m_ipv4->GetNetDevice ( - m_ipv4->GetInterfaceForAddress (receiver))); + toOrigin.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver))); toOrigin.SetHop (hop); - Time minimalLifetime = Simulator::Now () + Scalar (2) * NET_TRAVERSAL_TIME - - Scalar (2 * hop) * NODE_TRAVERSAL_TIME; + Time minimalLifetime = Simulator::Now () + Scalar (2) * NET_TRAVERSAL_TIME - Scalar (2 * hop) * NODE_TRAVERSAL_TIME; if (toOrigin.GetLifeTime () < minimalLifetime) toOrigin.SetLifeTime (minimalLifetime); m_routingTable.Update (origin, toOrigin); @@ -566,14 +583,11 @@ RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, // received in the incoming RREQ is larger than the value currently maintained // by the forwarding node. uint32_t dstSeqNo = toDst.GetSeqNo (); - if (rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - - int32_t (rreqHeader.GetDstSeqno ()) > 0)) + if (rreqHeader.GetUnknownSeqno () || (int32_t (toDst.GetSeqNo ()) - int32_t (rreqHeader.GetDstSeqno ()) > 0)) { - if (!rreqHeader.GetDestinationOnly () && toDst.GetValidSeqNo () - && (toDst.GetFlag () == RTF_UP)) + if (!rreqHeader.GetDestinationOnly () && toDst.GetValidSeqNo () && (toDst.GetFlag () == RTF_UP)) { - SendReplyByIntermediateNode (toDst, toOrigin, - rreqHeader.GetGratiousRrep (), socket); + SendReplyByIntermediateNode (toDst, toOrigin, rreqHeader.GetGratiousRrep (), socket); return; } rreqHeader.SetOriginSeqno (dstSeqNo); @@ -589,21 +603,17 @@ RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, TypeHeader tHeader (AODVTYPE_RREQ); packet->AddHeader (tHeader); - for (std::map , Ipv4InterfaceAddress>::const_iterator j = - m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) { Ptr socket = j->first; Ipv4InterfaceAddress iface = j->second; socket->Send (packet); } - - // Shift hello timer - // htimer.Schedule(); + htimer.Schedule (HELLO_INTERVAL); } void -RoutingProtocol::SendReply (RreqHeader const & rreqHeader, - RoutingTableEntry const & toOrigin, Ptr socket) +RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin, Ptr socket) { NS_LOG_FUNCTION (this << toOrigin.GetDestination ()); // Create RREP @@ -614,8 +624,7 @@ RoutingProtocol::SendReply (RreqHeader const & rreqHeader, // if the sequence number in the RREQ packet is equal to that incremented value. // Otherwise, the destination does not change its sequence number before // generating the RREP message. - if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo - + 1)) + if (!rreqHeader.GetUnknownSeqno () && (rreqHeader.GetDstSeqno () == m_seqNo + 1)) m_seqNo++; rrepHeader.SetDstSeqno (m_seqNo); rrepHeader.SetDst (rreqHeader.GetDst ()); @@ -626,13 +635,11 @@ RoutingProtocol::SendReply (RreqHeader const & rreqHeader, TypeHeader tHeader (AODVTYPE_RREP); packet->AddHeader (tHeader); - socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetDestination (), - AODV_PORT)); + socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetDestination (), AODV_PORT)); } void -RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiverIfaceAddr, - Ipv4Address senderIfaceAddr) +RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiverIfaceAddr, Ipv4Address senderIfaceAddr) { NS_LOG_FUNCTION(this << " src " << senderIfaceAddr); RrepHeader rrepHeader; @@ -665,12 +672,10 @@ RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiverIfaceAddr, - and the destination sequence number is the Destination Sequence Number in the RREP message. */ - dev = m_ipv4->GetNetDevice ( - m_ipv4->GetInterfaceForAddress (receiverIfaceAddr)); + dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiverIfaceAddr)); RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/rrepHeader.GetDst (), /*validSeqNo=*/ - true, /*seqno=*/rrepHeader.GetDstSeqno (), /*iface=*/receiverIfaceAddr, - /*hop=*/hop, /*nextHop=*/senderIfaceAddr, /*lifeTime=*/Simulator::Now () - + rrepHeader.GetLifeTime ()); + true, /*seqno=*/rrepHeader.GetDstSeqno (), /*iface=*/receiverIfaceAddr, + /*hop=*/hop, /*nextHop=*/senderIfaceAddr, /*lifeTime=*/Simulator::Now () + rrepHeader.GetLifeTime ()); if (m_routingTable.LookupRoute (rrepHeader.GetDst (), toDst)) { @@ -686,8 +691,7 @@ RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiverIfaceAddr, the node's copy of the destination sequence number and the known value is valid, */ - else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) - > 0) + else if ((int32_t (rrepHeader.GetDstSeqno ()) - int32_t (toDst.GetSeqNo ())) > 0) { toDst.SetSeqNo (rrepHeader.GetDstSeqno ()); m_routingTable.Update (rrepHeader.GetDst (), newEntry); @@ -695,15 +699,13 @@ RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiverIfaceAddr, else { // (iii) the sequence numbers are the same, but the route is marked as inactive. - if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () - != RTF_UP)) + if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (toDst.GetFlag () != RTF_UP)) { m_routingTable.Update (rrepHeader.GetDst (), newEntry); } // (iv) the sequence numbers are the same, and the New Hop Count is // smaller than the hop count in route table entry. - else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop - < toDst.GetHop ())) + else if ((rrepHeader.GetDstSeqno () == toDst.GetSeqNo ()) && (hop < toDst.GetHop ())) { m_routingTable.Update (rrepHeader.GetDst (), newEntry); } @@ -747,22 +749,19 @@ RoutingProtocol::RecvReply (Ptr p, Ipv4Address receiverIfaceAddr, packet->AddHeader (rrepHeader); TypeHeader tHeader (AODVTYPE_RREP); packet->AddHeader (tHeader); - for (std::map , Ipv4InterfaceAddress>::const_iterator j = - m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) { - dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress ( - j->second.GetLocal ())); + dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (j->second.GetLocal ())); if (dev->GetAddress () == toOrigin.GetOutputDevice ()->GetAddress ()) - j->first->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), - AODV_PORT)); + j->first->SendTo (packet, 0, InetSocketAddress (toOrigin.GetNextHop (), AODV_PORT)); } } // TODO may be used for determining connectivity void -RoutingProtocol::ProcessHello (RrepHeader const & rrepHeader, - Ipv4Address receiverIfaceAddr) +RoutingProtocol::ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr) { + NS_LOG_FUNCTION(this << "from " << rrepHeader.GetDst ()); /* * Whenever a node receives a Hello message from a neighbor, the node * SHOULD make sure that it has an active route to the neighbor, and @@ -772,25 +771,21 @@ RoutingProtocol::ProcessHello (RrepHeader const & rrepHeader, RoutingTableEntry toNeighbor (dev); if (!m_routingTable.LookupRoute (rrepHeader.GetDst (), toNeighbor)) { - dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress ( - receiverIfaceAddr)); + dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiverIfaceAddr)); RoutingTableEntry newEntry (/*device=*/dev, /*dst=*/rrepHeader.GetDst (), /*validSeqNo=*/ - true, /*seqno=*/rrepHeader.GetDstSeqno (), /*iface=*/receiverIfaceAddr, - /*hop=*/rrepHeader.GetHopCount (), /*nextHop=*/rrepHeader.GetDst (), /*lifeTime=*/ - Simulator::Now () + rrepHeader.GetLifeTime ()); + true, /*seqno=*/rrepHeader.GetDstSeqno (), /*iface=*/receiverIfaceAddr, + /*hop=*/rrepHeader.GetHopCount (), /*nextHop=*/rrepHeader.GetDst (), /*lifeTime=*/ + Simulator::Now () + rrepHeader.GetLifeTime ()); m_routingTable.AddRoute (newEntry); } else { - if (toNeighbor.GetLifeTime () < Simulator::Now () + Scalar ( - ALLOWED_HELLO_LOSS) * HELLO_INTERVAL) - toNeighbor.SetLifeTime (Simulator::Now () + Scalar (ALLOWED_HELLO_LOSS) - * HELLO_INTERVAL); + if (toNeighbor.GetLifeTime () < Simulator::Now () + Scalar (ALLOWED_HELLO_LOSS) * HELLO_INTERVAL) + toNeighbor.SetLifeTime (Simulator::Now () + Scalar (ALLOWED_HELLO_LOSS) * HELLO_INTERVAL); toNeighbor.SetSeqNo (rrepHeader.GetDstSeqno ()); toNeighbor.SetValidSeqNo (true); toNeighbor.SetFlag (RTF_UP); - dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress ( - receiverIfaceAddr)); + dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiverIfaceAddr)); toNeighbor.SetOutputDevice (dev); m_routingTable.Update (rrepHeader.GetDst (), toNeighbor); } @@ -815,7 +810,7 @@ RoutingProtocol::HelloTimerExpire () { SendHello (); // TODO select random time for the next hello - htimer.Schedule (); + htimer.Schedule (HELLO_INTERVAL); } void @@ -841,21 +836,20 @@ RoutingProtocol::LocalRepairTimerExpire () void RoutingProtocol::SendHello () { + NS_LOG_FUNCTION(this); /* Broadcast a RREP with TTL = 1 with the RREP message fields set as follows: * Destination IP Address The node's IP address. * Destination Sequence Number The node's latest sequence number. * Hop Count 0 * Lifetime ALLOWED_HELLO_LOSS * HELLO_INTERVAL */ - for (std::map , Ipv4InterfaceAddress>::const_iterator j = - m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) + for (std::map , Ipv4InterfaceAddress>::const_iterator j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j) { Ptr socket = j->first; Ipv4InterfaceAddress iface = j->second; RrepHeader helloHeader (/*flags=*/0, /*prefix size=*/0, /*hops=*/0, /*dst=*/ - iface.GetLocal (), /*dst seqno=*/m_seqNo, - /*origin=*/iface.GetLocal (), /*lifetime=*/Scalar (ALLOWED_HELLO_LOSS) - * HELLO_INTERVAL); + iface.GetLocal (), /*dst seqno=*/m_seqNo, + /*origin=*/iface.GetLocal (), /*lifetime=*/Scalar (ALLOWED_HELLO_LOSS) * HELLO_INTERVAL); Ptr packet = Create (); packet->AddHeader (helloHeader); TypeHeader tHeader (AODVTYPE_RREP); @@ -865,15 +859,13 @@ RoutingProtocol::SendHello () } void -RoutingProtocol::SendReplyByIntermediateNode (RoutingTableEntry & toDst, - RoutingTableEntry & toOrigin, bool gratRep, Ptr socket) +RoutingProtocol::SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep, Ptr socket) { RrepHeader rrepHeader (/*flags=*/0, /*prefix size=*/0, /*hops=*/ - toDst.GetHop (), /*dst=*/toDst.GetDestination (), /*dst seqno=*/ - toDst.GetSeqNo (), - /*origin=*/toOrigin.GetDestination (), /*lifetime=*/toDst.GetLifeTime () - - Simulator::Now ()); + toDst.GetHop (), /*dst=*/toDst.GetDestination (), /*dst seqno=*/ + toDst.GetSeqNo (), + /*origin=*/toOrigin.GetDestination (), /*lifetime=*/toDst.GetLifeTime () - Simulator::Now ()); toDst.InsertPrecursor (toOrigin.GetNextHop ()); toOrigin.InsertPrecursor (toDst.GetNextHop ()); @@ -885,21 +877,19 @@ RoutingProtocol::SendReplyByIntermediateNode (RoutingTableEntry & toDst, TypeHeader tHeader (AODVTYPE_RREP); packet->AddHeader (tHeader); - socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetDestination (), - AODV_PORT)); + socket->SendTo (packet, 0, InetSocketAddress (toOrigin.GetDestination (), AODV_PORT)); if (gratRep) { RrepHeader gratRepHeader (/*flags=*/0, /*prefix size=*/0, /*hops=*/ - toOrigin.GetHop (), /*dst=*/toOrigin.GetDestination (), /*dst seqno=*/ - toOrigin.GetSeqNo (), - /*origin=*/toDst.GetDestination (), /*lifetime=*/ - toOrigin.GetLifeTime () - Simulator::Now ()); + toOrigin.GetHop (), /*dst=*/toOrigin.GetDestination (), /*dst seqno=*/ + toOrigin.GetSeqNo (), + /*origin=*/toDst.GetDestination (), /*lifetime=*/ + toOrigin.GetLifeTime () - Simulator::Now ()); Ptr packetToDst = Create (); packetToDst->AddHeader (rrepHeader); packetToDst->AddHeader (tHeader); - socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetDestination (), - AODV_PORT)); + socket->SendTo (packetToDst, 0, InetSocketAddress (toDst.GetDestination (), AODV_PORT)); } } @@ -915,8 +905,7 @@ RoutingProtocol::SendPacketFromQueue (Ipv4Address dst, Ptr route) } void -RoutingProtocol::Send (Ptr route, Ptr packet, - const Ipv4Header & header) +RoutingProtocol::Send (Ptr route, Ptr packet, const Ipv4Header & header) { NS_LOG_FUNCTION(this << packet->GetUid()); Ptr l3 = m_ipv4->GetObject (); @@ -945,8 +934,7 @@ RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop) m_routingTable.Update (nextHop, toNextHop); m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable); - for (std::map::const_iterator i = - unreachable.begin (); i != unreachable.end (); ++i) + for (std::map::const_iterator i = unreachable.begin (); i != unreachable.end (); ++i) { if (!rerrHeader.AddUnDestination (i->first, i->second.GetSeqNo ())) { @@ -954,15 +942,16 @@ RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop) Ptr packet = Create (); packet->AddHeader (rerrHeader); packet->AddHeader (typeHeader); - SendRerrMessage(packet, precursors); + SendRerrMessage (packet, precursors); } } } void -RoutingProtocol::SendRerrMessage(Ptr packet, std::vector precursors) +RoutingProtocol::SendRerrMessage (Ptr packet, std::vector precursors) { - if (precursors.empty ())return; // TODO too many unreachable destinations, but no precursors + if (precursors.empty ()) + 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) { @@ -978,22 +967,23 @@ RoutingProtocol::SendRerrMessage(Ptr packet, std::vector p std::vector ifaces; Ptr dev; RoutingTableEntry toPrecursor (dev); - for(std::vector::const_iterator i = precursors.begin(); i != precursors.end(); ++i) + for (std::vector::const_iterator i = precursors.begin (); i != precursors.end (); ++i) { m_routingTable.LookupRoute (*i, toPrecursor); bool result = true; - for(std::vector::const_iterator i = ifaces.begin(); i != ifaces.end(); ++i) - if(*i == toPrecursor.GetInterface ()) + for (std::vector::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i) + if (*i == toPrecursor.GetInterface ()) { result = false; break; } - if(result) ifaces.push_back(toPrecursor.GetInterface ()); + if (result) + ifaces.push_back (toPrecursor.GetInterface ()); } - for (std::vector::const_iterator i = ifaces.begin(); i != ifaces.end(); ++i) + for (std::vector::const_iterator i = ifaces.begin (); i != ifaces.end (); ++i) { Ptr socket = FindSocketWithInterfaceAddress (*i); - socket->Send(packet); + socket->Send (packet); } } diff --git a/src/routing/aodv/aodv-routing-protocol.h b/src/routing/aodv/aodv-routing-protocol.h index a8f370e54..a73bd0874 100644 --- a/src/routing/aodv/aodv-routing-protocol.h +++ b/src/routing/aodv/aodv-routing-protocol.h @@ -116,6 +116,27 @@ private: std::vector m_broadcastIdCache; //\} + ///\name Handle duplicated packets + //\{ + void InsertPacketUid (Ipv4Address src, uint32_t uid); + bool LookupPacketUid (Ipv4Address src, uint32_t uid); + void PurgePacketUid (); + struct PacketUid + { + Ipv4Address m_src; + uint32_t m_uid; + Time m_expire; + }; + struct IsExpiredForPacket + { + bool operator()(const struct PacketUid & p) const + { + return (p.m_expire < Simulator::Now()); + } + }; + std::vector m_packetUidCache; + //\} + /// IP protocol Ptr m_ipv4; /// Raw socket per each IP interface, map socket -> iface address (IP + mask) @@ -146,6 +167,8 @@ private: void UpdateNeighbor (Ipv4Address sender, Ipv4Address receiver); /// Check that packet is an AODV control message bool LooksLikeAodvControl (Ptr p, Ipv4Header const & header) const; + /// Check that packet is send from own interface + bool IsMyOwnPacket(Ipv4Address src); /// Find socket with local interface address iface Ptr FindSocketWithInterfaceAddress(Ipv4Address iface) const; /// Process hello message