apps: Solving a serious bug #33 in ndn::ConsumerWindow

In certain cases, the number of in-flight packets was maintained in a
wrong way, creating inconsistencies and incorrect decision on when to
send out a new Interests.  That is, the number of in-flight
packets could be non-zero, while there were no outstanding packets at all.

Thanks to Cheng Yi for the bug discovery
diff --git a/apps/ndn-consumer-window.cc b/apps/ndn-consumer-window.cc
index 7e8325d..a2e29b3 100644
--- a/apps/ndn-consumer-window.cc
+++ b/apps/ndn-consumer-window.cc
@@ -151,8 +151,6 @@
           Simulator::Remove (m_sendEvent);
         }
 
-      // NS_LOG_DEBUG ("Window: " << m_window << ", InFlight: " << m_inFlight);
-      m_inFlight++;
       m_sendEvent = Simulator::ScheduleNow (&Consumer::SendPacket, this);
     }
 }
@@ -208,5 +206,13 @@
   Consumer::OnTimeout (sequenceNumber);
 }
 
+void
+ConsumerWindow::WillSendOutInterest (uint32_t sequenceNumber)
+{
+  m_inFlight ++;
+  Consumer::WillSendOutInterest (sequenceNumber);
+}
+
+
 } // namespace ndn
 } // namespace ns3
diff --git a/apps/ndn-consumer-window.h b/apps/ndn-consumer-window.h
index df79fb3..2057123 100644
--- a/apps/ndn-consumer-window.h
+++ b/apps/ndn-consumer-window.h
@@ -59,6 +59,9 @@
   virtual void
   OnTimeout (uint32_t sequenceNumber);
 
+  virtual void
+  WillSendOutInterest (uint32_t sequenceNumber);
+
 protected:
   /**
    * \brief Constructs the Interest packet and sends it using a callback to the underlying NDN protocol
diff --git a/apps/ndn-consumer.cc b/apps/ndn-consumer.cc
index e579312..e5c2a44 100644
--- a/apps/ndn-consumer.cc
+++ b/apps/ndn-consumer.cc
@@ -214,23 +214,12 @@
   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");
-
-  m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
-  m_seqFullDelay.insert (SeqTimeout (seq, Simulator::Now ()));
-
-  m_seqLastDelay.erase (seq);
-  m_seqLastDelay.insert (SeqTimeout (seq, Simulator::Now ()));
-
-  m_seqRetxCounts[seq] ++;
-
-  m_transmittedInterests (&interestHeader, this, m_face);
-
-  m_rtt->SentSeq (SequenceNumber32 (seq), 1);
+  WillSendOutInterest (seq);  
 
   FwHopCountTag hopCountTag;
   packet->AddPacketTag (hopCountTag);
 
+  m_transmittedInterests (&interestHeader, this, m_face);
   m_protocolHandler (packet);
 
   ScheduleNextPacket ();
@@ -324,5 +313,22 @@
   ScheduleNextPacket ();
 }
 
+void
+Consumer::WillSendOutInterest (uint32_t sequenceNumber)
+{
+  NS_LOG_DEBUG ("Trying to add " << sequenceNumber << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");
+
+  m_seqTimeouts.insert (SeqTimeout (sequenceNumber, Simulator::Now ()));
+  m_seqFullDelay.insert (SeqTimeout (sequenceNumber, Simulator::Now ()));
+
+  m_seqLastDelay.erase (sequenceNumber);
+  m_seqLastDelay.insert (SeqTimeout (sequenceNumber, Simulator::Now ()));
+
+  m_seqRetxCounts[sequenceNumber] ++;
+
+  m_rtt->SentSeq (SequenceNumber32 (sequenceNumber), 1);
+}
+
+
 } // namespace ndn
 } // namespace ns3
diff --git a/apps/ndn-consumer.h b/apps/ndn-consumer.h
index b748c2a..7dd4cdc 100644
--- a/apps/ndn-consumer.h
+++ b/apps/ndn-consumer.h
@@ -80,6 +80,16 @@
   void
   SendPacket ();
 
+  /**
+   * @brief An event that is fired just before an Interest packet is actually send out (send is inevitable)
+   *
+   * The reason for "before" even is that in certain cases (when it is possible to satisfy from the local cache),
+   * the send call will immediately return data, and if "after" even was used, this after would be called after
+   * all processing of incoming data, potentially producing unexpected results.
+   */
+  virtual void
+  WillSendOutInterest (uint32_t sequenceNumber);
+  
 protected:
   // from App
   virtual void