Fixing bugs related to NACKs implementation
diff --git a/apps/ndn-consumer-window.cc b/apps/ndn-consumer-window.cc
index 4ae30dd..165326b 100644
--- a/apps/ndn-consumer-window.cc
+++ b/apps/ndn-consumer-window.cc
@@ -32,9 +32,9 @@
namespace ns3 {
namespace ndn {
-
+
NS_OBJECT_ENSURE_REGISTERED (ConsumerWindow);
-
+
TypeId
ConsumerWindow::GetTypeId (void)
{
@@ -126,14 +126,19 @@
void
ConsumerWindow::ScheduleNextPacket ()
{
- if (m_window == static_cast<uint32_t> (0) || m_inFlight >= m_window)
+ if (m_window == static_cast<uint32_t> (0))
{
if (!m_sendEvent.IsRunning ())
{
- m_sendEvent = Simulator::Schedule (Seconds (m_rtt->RetransmitTimeout ().ToDouble (Time::S) * 0.1),
+ m_sendEvent = Simulator::Schedule (Seconds (m_rtt->RetransmitTimeout ().ToDouble (Time::S)),
&Consumer::SendPacket, this);
+ m_rtt->IncreaseMultiplier ();
}
}
+ else if (m_inFlight >= m_window)
+ {
+ // simply do nothing
+ }
else
{
if (m_sendEvent.IsRunning ())
@@ -141,7 +146,7 @@
Simulator::Remove (m_sendEvent);
}
- NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
+ // NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
m_inFlight++;
m_sendEvent = Simulator::ScheduleNow (&Consumer::SendPacket, this);
}
@@ -169,22 +174,25 @@
ConsumerWindow::OnNack (const Ptr<const InterestHeader> &interest, Ptr<Packet> payload)
{
Consumer::OnNack (interest, payload);
-
+
if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
if (m_window > static_cast<uint32_t> (0))
{
// m_window = 0.5 * m_window;//m_window - 1;
- m_window = m_window - 1;
+ m_window = std::max<uint32_t> (0, m_window - 1);
}
-
+
// NS_LOG_DEBUG ("Window: " << m_window);
}
void
ConsumerWindow::OnTimeout (uint32_t sequenceNumber)
{
+ // NS_FATAL_ERROR ("No timeouts should happen: " << sequenceNumber);
if (m_inFlight > static_cast<uint32_t> (0)) m_inFlight--;
+ // m_window = std::max<uint32_t> (0, m_window - 1);
+ m_window = 0;
Consumer::OnTimeout (sequenceNumber);
}
diff --git a/apps/ndn-consumer.cc b/apps/ndn-consumer.cc
index 60ef55b..8c2619e 100644
--- a/apps/ndn-consumer.cc
+++ b/apps/ndn-consumer.cc
@@ -47,9 +47,9 @@
namespace ns3 {
namespace ndn {
-
+
NS_OBJECT_ENSURE_REGISTERED (Consumer);
-
+
TypeId
Consumer::GetTypeId (void)
{
@@ -85,7 +85,7 @@
return tid;
}
-
+
Consumer::Consumer ()
: m_rand (0, std::numeric_limits<uint32_t>::max ())
, m_seq (0)
@@ -108,7 +108,7 @@
// schedule even with new timeout
m_retxEvent = Simulator::Schedule (m_retxTimer,
- &Consumer::CheckRetxTimeout, this);
+ &Consumer::CheckRetxTimeout, this);
}
Time
@@ -123,6 +123,7 @@
Time now = Simulator::Now ();
Time rto = m_rtt->RetransmitTimeout ();
+ NS_LOG_DEBUG ("Current RTO: " << rto.ToDouble (Time::S) << "s");
while (!m_seqTimeouts.empty ())
{
@@ -139,11 +140,11 @@
}
m_retxEvent = Simulator::Schedule (m_retxTimer,
- &Consumer::CheckRetxTimeout, this);
+ &Consumer::CheckRetxTimeout, this);
}
// Application Methods
-void
+void
Consumer::StartApplication () // Called at time specified by Start
{
NS_LOG_FUNCTION_NOARGS ();
@@ -153,8 +154,8 @@
ScheduleNextPacket ();
}
-
-void
+
+void
Consumer::StopApplication () // Called at time specified by Stop
{
NS_LOG_FUNCTION_NOARGS ();
@@ -165,7 +166,7 @@
// cleanup base stuff
App::StopApplication ();
}
-
+
void
Consumer::SendPacket ()
{
@@ -191,10 +192,10 @@
return; // we are totally done
}
}
-
+
seq = m_seq++;
}
-
+
//
Ptr<NameComponents> nameWithSequence = Create<NameComponents> (m_interestName);
(*nameWithSequence) (seq);
@@ -203,7 +204,7 @@
InterestHeader interestHeader;
interestHeader.SetNonce (m_rand.GetValue ());
interestHeader.SetName (nameWithSequence);
-
+
// NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
NS_LOG_INFO ("> Interest for " << seq);
@@ -211,8 +212,8 @@
packet->AddHeader (interestHeader);
NS_LOG_DEBUG ("Interest packet size: " << packet->GetSize ());
- NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
-
+ NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
+
m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
m_seqFullDelay.insert (SeqTimeout (seq, Simulator::Now ()));
@@ -220,14 +221,14 @@
m_seqLastDelay.insert (SeqTimeout (seq, Simulator::Now ()));
m_seqRetxCounts[seq] ++;
-
+
m_transmittedInterests (&interestHeader, this, m_face);
m_rtt->SentSeq (SequenceNumber32 (seq), 1);
FwHopCountTag hopCountTag;
packet->AddPacketTag (hopCountTag);
-
+
m_protocolHandler (packet);
ScheduleNextPacket ();
@@ -245,11 +246,11 @@
if (!m_active) return;
App::OnContentObject (contentObject, payload); // tracing inside
-
+
NS_LOG_FUNCTION (this << contentObject << payload);
// NS_LOG_INFO ("Received content object: " << boost::cref(*contentObject));
-
+
uint32_t seq = boost::lexical_cast<uint32_t> (contentObject->GetName ().GetComponents ().back ());
NS_LOG_INFO ("< DATA for " << seq);
@@ -259,7 +260,7 @@
{
hopCount = hopCountTag.Get ();
}
-
+
SeqTimeoutsContainer::iterator entry = m_seqLastDelay.find (seq);
if (entry != m_seqLastDelay.end ())
{
@@ -272,10 +273,10 @@
m_firstInterestDataDelay (this, seq, Simulator::Now () - entry->time, m_seqRetxCounts[seq], hopCount);
}
- m_seqRetxCounts.erase (seq);
+ m_seqRetxCounts.erase (seq);
m_seqFullDelay.erase (seq);
m_seqLastDelay.erase (seq);
-
+
m_seqTimeouts.erase (seq);
m_retxSeqs.erase (seq);
@@ -286,9 +287,9 @@
Consumer::OnNack (const Ptr<const InterestHeader> &interest, Ptr<Packet> origPacket)
{
if (!m_active) return;
-
+
App::OnNack (interest, origPacket); // tracing inside
-
+
// NS_LOG_DEBUG ("Nack type: " << interest->GetNack ());
// NS_LOG_FUNCTION (interest->GetName ());
@@ -296,13 +297,15 @@
// NS_LOG_INFO ("Received NACK: " << boost::cref(*interest));
uint32_t seq = boost::lexical_cast<uint32_t> (interest->GetName ().GetComponents ().back ());
NS_LOG_INFO ("< NACK for " << seq);
- // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << "NACK for " << seq << "\n";
+ // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << "NACK for " << seq << "\n";
// put in the queue of interests to be retransmitted
// NS_LOG_INFO ("Before: " << m_retxSeqs.size ());
m_retxSeqs.insert (seq);
// NS_LOG_INFO ("After: " << m_retxSeqs.size ());
+ m_seqTimeouts.erase (seq);
+
m_rtt->IncreaseMultiplier (); // Double the next RTO ??
ScheduleNextPacket ();
}
@@ -316,7 +319,7 @@
m_rtt->IncreaseMultiplier (); // Double the next RTO
m_rtt->SentSeq (SequenceNumber32 (sequenceNumber), 1); // make sure to disable RTT calculation for this sample
m_retxSeqs.insert (sequenceNumber);
- ScheduleNextPacket ();
+ ScheduleNextPacket ();
}
} // namespace ndn
diff --git a/apps/ndn-consumer.h b/apps/ndn-consumer.h
index 5d09672..970da4c 100644
--- a/apps/ndn-consumer.h
+++ b/apps/ndn-consumer.h
@@ -27,8 +27,8 @@
#include "ns3/ndn-name-components.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
-#include "../../internet/model/rtt-estimator.h"
//#include "ns3/internet-module.h"
+#include "ns3/rtt-estimator.h"
#include <set>
#include <map>
@@ -47,11 +47,11 @@
*/
class Consumer: public App
{
-public:
+public:
static TypeId GetTypeId ();
-
+
/**
- * \brief Default constructor
+ * \brief Default constructor
* Sets up randomizer function and packet sequence number
*/
Consumer ();
@@ -80,7 +80,7 @@
*/
void
SendPacket ();
-
+
protected:
// from App
virtual void
@@ -88,19 +88,19 @@
virtual void
StopApplication ();
-
+
/**
* \brief Constructs the Interest packet and sends it using a callback to the underlying NDN protocol
*/
virtual void
ScheduleNextPacket () = 0;
-
+
/**
* \brief Checks if the packet need to be retransmitted becuase of retransmission timer expiration
*/
void
CheckRetxTimeout ();
-
+
/**
* \brief Modifies the frequency of checking the retransmission timeouts
* \param retxTimer Timeout defining how frequent retransmission timeouts should be checked
@@ -114,7 +114,7 @@
*/
Time
GetRetxTimer () const;
-
+
protected:
UniformVariable m_rand; ///< @brief nonce generator
@@ -125,37 +125,37 @@
EventId m_retxEvent; ///< @brief Event to check whether or not retransmission should be performed
Ptr<RttEstimator> m_rtt; ///< @brief RTT estimator
-
+
Time m_offTime; ///< \brief Time interval between packets
NameComponents m_interestName; ///< \brief NDN Name of the Interest (use NameComponents)
Time m_interestLifeTime; ///< \brief LifeTime for interest packet
-/// @cond include_hidden
+/// @cond include_hidden
/**
* \struct This struct contains sequence numbers of packets to be retransmitted
*/
struct RetxSeqsContainer :
public std::set<uint32_t> { };
-
+
RetxSeqsContainer m_retxSeqs; ///< \brief ordered set of sequence numbers to be retransmitted
/**
* \struct This struct contains a pair of packet sequence number and its timeout
- */
+ */
struct SeqTimeout
{
SeqTimeout (uint32_t _seq, Time _time) : seq (_seq), time (_time) { }
-
+
uint32_t seq;
Time time;
};
/// @endcond
-
+
/// @cond include_hidden
class i_seq { };
- class i_timestamp { };
+ class i_timestamp { };
/// @endcond
-
+
/// @cond include_hidden
/**
* \struct This struct contains a multi-index for the set of SeqTimeout structs
@@ -180,13 +180,13 @@
SeqTimeoutsContainer m_seqLastDelay;
SeqTimeoutsContainer m_seqFullDelay;
std::map<uint32_t, uint32_t> m_seqRetxCounts;
-
+
TracedCallback<Ptr<App> /* app */, uint32_t /* seqno */,
Time /* delay */, int32_t /*hop count*/> m_lastRetransmittedInterestDataDelay;
TracedCallback<Ptr<App> /* app */, uint32_t /* seqno */,
Time /* delay */, uint32_t /*retx count*/,
int32_t /*hop count*/> m_firstInterestDataDelay;
-
+
/// @endcond
};