catchunks: increase retx limit and improve statistics

Increased the retx limit from 3 to 15 (default in Linux TCP).
Added statistics about skipped retransmission.
Cleaned up statistic output.

Change-Id: I66ce9ac9fa08f7492f84bec48b7464ddb1228ab1
refs: #4861 #4603
diff --git a/tools/chunks/catchunks/options.hpp b/tools/chunks/catchunks/options.hpp
index b078277..d3a564e 100644
--- a/tools/chunks/catchunks/options.hpp
+++ b/tools/chunks/catchunks/options.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2018, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -36,7 +36,7 @@
 struct Options
 {
   time::milliseconds interestLifetime = ndn::DEFAULT_INTEREST_LIFETIME;
-  int maxRetriesOnTimeoutOrNack = 3;
+  int maxRetriesOnTimeoutOrNack = 15;
   bool mustBeFresh = false;
   bool isQuiet = false;
   bool isVerbose = false;
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.cpp b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
index eea122e..b802e34 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
@@ -47,7 +47,10 @@
   , m_highInterest(0)
   , m_recPoint(0)
   , m_nInFlight(0)
-  , m_nLossEvents(0)
+  , m_nLossDecr(0)
+  , m_nMarkDecr(0)
+  , m_nTimeouts(0)
+  , m_nSkippedRetx(0)
   , m_nRetransmitted(0)
   , m_nCongMarks(0)
   , m_nSent(0)
@@ -103,6 +106,7 @@
     if (segInfo.state != SegmentState::InRetxQueue) { // skip segments already in the retx queue
       Milliseconds timeElapsed = time::steady_clock::now() - segInfo.timeSent;
       if (timeElapsed.count() > segInfo.rto.count()) { // timer expired?
+        m_nTimeouts++;
         hasTimeout = true;
         enqueueForRetransmission(entry.first);
       }
@@ -191,6 +195,7 @@
       uint64_t retxSegNo = m_retxQueue.front();
       m_retxQueue.pop();
       if (m_segmentInfo.count(retxSegNo) == 0) {
+        m_nSkippedRetx++;
         continue;
       }
       // the segment is still in the map, that means it needs to be retransmitted
@@ -257,6 +262,7 @@
       if (m_options.disableCwa || m_highData > m_recPoint) {
         m_recPoint = m_highInterest;  // react to only one congestion event (timeout or congestion mark)
                                       // per RTT (conservative window adaptation)
+        m_nMarkDecr++;
         decreaseWindow();
 
         if (m_options.isVerbose) {
@@ -333,6 +339,7 @@
   if (isStopping())
     return;
 
+  m_nTimeouts++;
   enqueueForRetransmission(getSegmentFromPacket(interest));
   recordTimeout();
   schedulePackets();
@@ -347,7 +354,7 @@
 
     decreaseWindow();
     m_rttEstimator.backoffRto();
-    m_nLossEvents++;
+    m_nLossDecr++;
 
     if (m_options.isVerbose) {
       std::cerr << "Packet loss event, new cwnd = " << m_cwnd
@@ -433,11 +440,11 @@
 PipelineInterestsAimd::printSummary() const
 {
   PipelineInterests::printSummary();
-  std::cerr << "Total # of lost/retransmitted segments: " << m_nRetransmitted
-            << " (caused " << m_nLossEvents << " window decreases)\n"
-            << "Packet loss rate: "
-            << (m_nSent == 0 ? 0 : (static_cast<double>(m_nRetransmitted) / static_cast<double>(m_nSent) * 100))  << "%\n"
-            << "Total # of received congestion marks: " << m_nCongMarks << "\n"
+  std::cerr << "Congestion marks: " << m_nCongMarks << " (caused " << m_nMarkDecr << " window decreases)\n"
+            << "Timeouts: " << m_nTimeouts << " (caused " << m_nLossDecr << " window decreases)\n"
+            << "Retransmitted segments: " << m_nRetransmitted
+            << " (" << (m_nSent == 0 ? 0 : (static_cast<double>(m_nRetransmitted) / m_nSent * 100.0))  << "%)"
+            << ", skipped: " << m_nSkippedRetx << "\n"
             << "RTT ";
 
   if (m_rttEstimator.getMinRtt() == std::numeric_limits<double>::max() ||
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.hpp b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
index 12edb95..4ef21ac 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
@@ -200,8 +200,12 @@
                        ///< it remains fixed until the next packet loss event happens
 
   int64_t m_nInFlight; ///< # of segments in flight
-  int64_t m_nLossEvents; ///< # of loss events occurred
-  int64_t m_nRetransmitted; ///< # of segments retransmitted
+  int64_t m_nLossDecr; ///< # of window decreases caused by packet loss
+  int64_t m_nMarkDecr; ///< # of window decreases caused by congestion marks
+  int64_t m_nTimeouts; ///< # of timed out segments
+  int64_t m_nSkippedRetx; ///< # of segments queued for retransmission but received before the
+                          ///< retransmission occurred
+  int64_t m_nRetransmitted; ///< # of retransmitted segments
   int64_t m_nCongMarks; ///< # of data packets with congestion mark
   int64_t m_nSent; ///< # of interest packets sent out (including retransmissions)
 
diff --git a/tools/chunks/catchunks/pipeline-interests.cpp b/tools/chunks/catchunks/pipeline-interests.cpp
index a6c7c21..3b0bff9 100644
--- a/tools/chunks/catchunks/pipeline-interests.cpp
+++ b/tools/chunks/catchunks/pipeline-interests.cpp
@@ -136,9 +136,9 @@
   duration<double, milliseconds::period> timeElapsed = steady_clock::now() - getStartTime();
   double throughput = (8 * m_receivedSize * 1000) / timeElapsed.count();
 
-  std::cerr << "\nAll segments have been received.\n"
+  std::cerr << "\n\nAll segments have been received.\n"
             << "Time elapsed: " << timeElapsed << "\n"
-            << "Total # of segments received: " << m_nReceived << "\n"
+            << "Segments received: " << m_nReceived << "\n"
             << "Total size: " << static_cast<double>(m_receivedSize) / 1000 << "kB" << "\n"
             << "Goodput: " << formatThroughput(throughput) << "\n";
 }