bug 1042: AODV RERR implosion (missing RERR_RATELIMIT)

This commit is contained in:
Elena Buchatskaya
2011-05-12 23:10:46 -07:00
parent e9e1e82c4a
commit 3cbd6f9aa0
3 changed files with 53 additions and 1 deletions

View File

@@ -75,6 +75,7 @@ since ns-3.10, in many cases referencing the Bugzilla bug number.
- bug 1056 - CSMA: padding not handled correctly for LLC encapsulation
- bug 1058 - documentation help to avoid InternetStackHelper pitfall
- bug 1054 - ipv6 InternetStackHelper EnablePcapIpv6All() broken
- bug 1042 - AODV RERR implosion (missing RERR_RATELIMIT)
Known issues
------------

View File

@@ -96,6 +96,7 @@ struct DeferredRouteOutputTag : public Tag
RoutingProtocol::RoutingProtocol () :
RreqRetries (2),
RreqRateLimit (10),
RerrRateLimit (10),
ActiveRouteTimeout (Seconds (3)),
NetDiameter (35),
NodeTraversalTime (MilliSeconds (40)),
@@ -121,8 +122,10 @@ RoutingProtocol::RoutingProtocol () :
m_dpd (PathDiscoveryTime),
m_nb(HelloInterval),
m_rreqCount (0),
m_rerrCount (0),
m_htimer (Timer::CANCEL_ON_DESTROY),
m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY)
m_rreqRateLimitTimer (Timer::CANCEL_ON_DESTROY),
m_rerrRateLimitTimer (Timer::CANCEL_ON_DESTROY)
{
if (EnableHello)
{
@@ -148,6 +151,10 @@ RoutingProtocol::GetTypeId (void)
UintegerValue (10),
MakeUintegerAccessor (&RoutingProtocol::RreqRateLimit),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("RerrRateLimit", "Maximum number of RERR per second.",
UintegerValue (10),
MakeUintegerAccessor (&RoutingProtocol::RerrRateLimit),
MakeUintegerChecker<uint32_t> ())
.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)),
@@ -278,6 +285,11 @@ RoutingProtocol::Start ()
m_rreqRateLimitTimer.SetFunction (&RoutingProtocol::RreqRateLimitTimerExpire,
this);
m_rreqRateLimitTimer.Schedule (Seconds (1));
m_rerrRateLimitTimer.SetFunction (&RoutingProtocol::RerrRateLimitTimerExpire,
this);
m_rerrRateLimitTimer.Schedule (Seconds (1));
}
Ptr<Ipv4Route>
@@ -1493,6 +1505,14 @@ RoutingProtocol::RreqRateLimitTimerExpire ()
m_rreqRateLimitTimer.Schedule (Seconds (1));
}
void
RoutingProtocol::RerrRateLimitTimerExpire ()
{
NS_LOG_FUNCTION (this);
m_rerrCount = 0;
m_rerrRateLimitTimer.Schedule (Seconds (1));
}
void
RoutingProtocol::AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout)
{
@@ -1610,6 +1630,17 @@ RoutingProtocol::SendRerrWhenNoRouteToForward (Ipv4Address dst,
uint32_t dstSeqNo, Ipv4Address origin)
{
NS_LOG_FUNCTION (this);
// A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
if (m_rerrCount == RerrRateLimit)
{
// Just make sure that the RerrRateLimit timer is running and will expire
NS_ASSERT (m_rerrRateLimitTimer.IsRunning ());
// discard the packet and return
NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
<< m_rerrRateLimitTimer.GetDelayLeft ().GetSeconds ()
<< "; suppressing RERR");
return;
}
RerrHeader rerrHeader;
rerrHeader.AddUnDestination (dst, dstSeqNo);
RoutingTableEntry toOrigin;
@@ -1658,6 +1689,17 @@ RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> p
NS_LOG_LOGIC ("No precursors");
return;
}
// A node SHOULD NOT originate more than RERR_RATELIMIT RERR messages per second.
if (m_rerrCount == RerrRateLimit)
{
// Just make sure that the RerrRateLimit timer is running and will expire
NS_ASSERT (m_rerrRateLimitTimer.IsRunning ());
// discard the packet and return
NS_LOG_LOGIC ("RerrRateLimit reached at " << Simulator::Now ().GetSeconds () << " with timer delay left "
<< m_rerrRateLimitTimer.GetDelayLeft ().GetSeconds ()
<< "; suppressing RERR");
return;
}
// If there is only one precursor, RERR SHOULD be unicast toward that precursor
if (precursors.size () == 1)
{
@@ -1668,6 +1710,7 @@ RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> p
NS_ASSERT (socket);
NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination() << " from " << toPrecursor.GetInterface ().GetLocal ());
socket->SendTo (packet, 0, InetSocketAddress (precursors.front (), AODV_PORT));
m_rerrCount++;
}
return;
}
@@ -1700,6 +1743,7 @@ RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> p
destination = i->GetBroadcast ();
}
socket->SendTo (packet, 0, InetSocketAddress (destination, AODV_PORT));
m_rerrCount++;
}
}

View File

@@ -94,6 +94,7 @@ private:
//\{
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.
uint16_t RerrRateLimit; ///< Maximum number of REER per second.
Time ActiveRouteTimeout; ///< Period of time during which the route is considered to be valid.
uint32_t NetDiameter; ///< Net diameter measures the maximum possible number of hops between two nodes in the network
/**
@@ -153,6 +154,8 @@ private:
Neighbors m_nb;
/// Number of RREQs used for RREQ rate control
uint16_t m_rreqCount;
/// Number of RERRs used for RERR rate control
uint16_t m_rerrCount;
private:
/// Start protocol operation
@@ -241,6 +244,10 @@ private:
Timer m_rreqRateLimitTimer;
/// Reset RREQ count and schedule RREQ rate limit timer with delay 1 sec.
void RreqRateLimitTimerExpire ();
/// RERR rate limit timer
Timer m_rerrRateLimitTimer;
/// Reset RERR count and schedule RERR rate limit timer with delay 1 sec.
void RerrRateLimitTimerExpire ();
/// Map IP address + RREQ timer.
std::map<Ipv4Address, Timer> m_addressReqTimer;
/// Handle route discovery process