diff --git a/src/internet-stack/ipv4-l3-protocol.cc b/src/internet-stack/ipv4-l3-protocol.cc index 1ee4acbb3..85220d211 100644 --- a/src/internet-stack/ipv4-l3-protocol.cc +++ b/src/internet-stack/ipv4-l3-protocol.cc @@ -683,9 +683,9 @@ Ipv4L3Protocol::IpForward (Ptr rtentry, Ptr p, const Ip ipHeader.SetTtl (ipHeader.GetTtl () - 1); if (ipHeader.GetTtl () == 0) { - // Do not reply to ICMP or to multicast/broadcast IP address - if (ipHeader.GetProtocol () != Icmpv4L4Protocol::PROT_NUMBER && - ipHeader.GetDestination ().IsBroadcast () == false && + // Do not reply to ICMP or to multicast/broadcast IP address + if (ipHeader.GetProtocol () != Icmpv4L4Protocol::PROT_NUMBER && + ipHeader.GetDestination ().IsBroadcast () == false && ipHeader.GetDestination ().IsMulticast () == false) { Ptr icmp = GetIcmp (); diff --git a/src/routing/aodv/aodv-routing-protocol.cc b/src/routing/aodv/aodv-routing-protocol.cc index 8f1fec639..125309d6a 100644 --- a/src/routing/aodv/aodv-routing-protocol.cc +++ b/src/routing/aodv/aodv-routing-protocol.cc @@ -45,6 +45,8 @@ #include "ns3/adhoc-wifi-mac.h" #include +#include "ns3/icmpv4.h" + NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol"); namespace ns3 @@ -58,6 +60,7 @@ const uint32_t RoutingProtocol::AODV_PORT = 654; RoutingProtocol::RoutingProtocol () : RreqRetries (2), + RreqRateLimit (10), ActiveRouteTimeout (Seconds (3)), NetDiameter (35), NodeTraversalTime (MilliSeconds (40)), @@ -65,7 +68,7 @@ RoutingProtocol::RoutingProtocol () : PathDiscoveryTime ( Scalar (2) * NetTraversalTime), MyRouteTimeout (Scalar (2) * std::max (PathDiscoveryTime, ActiveRouteTimeout)), HelloInterval(Seconds (1)), - AllowedHelloLoss (3), + AllowedHelloLoss (2), DeletePeriod (Scalar(5) * std::max(ActiveRouteTimeout, HelloInterval)), NextHopWait (NodeTraversalTime + MilliSeconds (10)), TimeoutBuffer (2), @@ -80,7 +83,9 @@ RoutingProtocol::RoutingProtocol () : m_requestId (0), m_seqNo (0), m_nb(HelloInterval), - htimer (Timer::CANCEL_ON_DESTROY) + m_rreqCount (0), + htimer (Timer::CANCEL_ON_DESTROY), + m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY) { if (EnableHello) { @@ -102,6 +107,10 @@ RoutingProtocol::GetTypeId (void) UintegerValue (2), MakeUintegerAccessor (&RoutingProtocol::RreqRetries), MakeUintegerChecker ()) + .AddAttribute ("RreqRateLimit", "Maximum number of RREQ per second.", + UintegerValue (10), + MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit), + 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)), @@ -124,7 +133,7 @@ RoutingProtocol::GetTypeId (void) MakeTimeAccessor (&RoutingProtocol::MaxQueueTime), MakeTimeChecker ()) .AddAttribute ("AllowedHelloLoss", "Number of hello messages which may be loss for valid link.", - UintegerValue (3), + UintegerValue (2), MakeUintegerAccessor (&RoutingProtocol::AllowedHelloLoss), MakeUintegerChecker ()) .AddAttribute ("GratuitousReply", "Indicates whether a gratuitous RREP should be unicast to the node originated route discovery.", @@ -172,6 +181,8 @@ RoutingProtocol::Start () { m_nb.ScheduleTimer (); } + m_rreqRateLimitTimer.SetFunction (&RoutingProtocol::RreqRateLimitTimerExpire, this); + m_rreqRateLimitTimer.Schedule (Seconds (1)); } Ptr @@ -212,9 +223,8 @@ RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header, uint32_t NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue"); } - if (rt.GetFlag () == INVALID && result) + if ((rt.GetFlag () == INVALID) && result) { - m_routingTable.SetEntryState (dst, IN_SEARCH); SendRequest (dst); } } @@ -228,7 +238,7 @@ RoutingProtocol::RouteOutput (Ptr p, const Ipv4Header &header, uint32_t // Some protocols may ask route several times for a single packet. result = m_queue.Enqueue (newEntry); if (result) - NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue"); + NS_LOG_LOGIC ("Add packet " << p->GetUid() << " to queue. Protocol " << (uint16_t) header.GetProtocol ()); } if (result) SendRequest (dst); @@ -271,13 +281,12 @@ RoutingProtocol::RouteInput (Ptr p, const Ipv4Header &header, Ptr< } m_idCache.InsertId (origin, p->GetUid (), PathDiscoveryTime); UpdateRouteLifeTime (origin, ActiveRouteTimeout); - NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ()); Ptr packet = p->Copy(); lcb (p, header, iif); Ptr route; - if (header.GetTtl() > 1) + if (header.GetTtl () > 1) { NS_LOG_LOGIC ("Forward broadcast"); ucb (route, packet, header); @@ -547,6 +556,14 @@ void RoutingProtocol::SendRequest (Ipv4Address dst) { NS_LOG_FUNCTION ( this << dst); + // A node SHOULD NOT originate more than RREQ_RATELIMIT RREQ messages per second. + if (m_rreqCount == RreqRateLimit) + { + Simulator::Schedule(m_rreqRateLimitTimer.GetDelayLeft() + MilliSeconds(0.1), &RoutingProtocol::SendRequest, this, dst); + return; + } + else + m_rreqCount++; // Create RREQ header RreqHeader rreqHeader; rreqHeader.SetDst (dst); @@ -559,6 +576,8 @@ RoutingProtocol::SendRequest (Ipv4Address dst) rreqHeader.SetDstSeqno (rt.GetSeqNo ()); else rreqHeader.SetUnknownSeqno (true); + rt.SetFlag (IN_SEARCH); + m_routingTable.AddRoute (rt); } else { @@ -771,6 +790,7 @@ RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, Ipv4Address s toOrigin.SetLifeTime (std::max (Scalar (2) * NetTraversalTime - Scalar (2 * hop) * NodeTraversalTime, toOrigin.GetLifeTime ())); m_routingTable.Update (toOrigin); } + NS_LOG_LOGIC (receiver << " recieve RREQ to destination " << rreqHeader.GetDst ()); // A node generates a RREP if either: // (i) it is itself the destination, @@ -786,7 +806,6 @@ RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, Ipv4Address s */ RoutingTableEntry toDst; Ipv4Address dst = rreqHeader.GetDst (); - NS_LOG_LOGIC (receiver << " recieve RREQ to destination " << dst); if (m_routingTable.LookupRoute (dst, toDst)) { /* @@ -1185,6 +1204,13 @@ RoutingProtocol::HelloTimerExpire () htimer.Schedule (HelloInterval - t); } +void +RoutingProtocol::RreqRateLimitTimerExpire () +{ + m_rreqCount = 0; + m_rreqRateLimitTimer.Schedule(Seconds(1)); +} + void RoutingProtocol::AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout ) { diff --git a/src/routing/aodv/aodv-routing-protocol.h b/src/routing/aodv/aodv-routing-protocol.h index 92a8e33e9..b5ba6e412 100644 --- a/src/routing/aodv/aodv-routing-protocol.h +++ b/src/routing/aodv/aodv-routing-protocol.h @@ -90,6 +90,7 @@ private: ///\name Protocol parameters. TODO document //\{ uint32_t RreqRetries; ///< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route + uint16_t RreqRateLimit; ///< Maximum number of RREQ per second. Time ActiveRouteTimeout; ///< Minimal lifetime for active route. uint32_t NetDiameter; ///< Net diameter measures the maximum possible number of hops between two nodes in the network /** @@ -142,6 +143,7 @@ private: IdCache m_idCache; /// Handle neighbors Neighbors m_nb; + uint16_t m_rreqCount; /// Unicast callback for own packets UnicastForwardCallback m_scb; @@ -227,6 +229,8 @@ private: //\{ Timer htimer; // TODO independent hello timers for all interfaces void HelloTimerExpire (); + Timer m_rreqRateLimitTimer; + void RreqRateLimitTimerExpire (); std::map m_addressReqTimer; void RouteRequestTimerExpire (Ipv4Address dst); void AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout);