face: use ndn-cxx's RttEstimator in LpReliability
Refs: #4887
Change-Id: Iaf8b04e33de363bae2c99f10f3866773c900f30d
diff --git a/daemon/face/lp-reliability.cpp b/daemon/face/lp-reliability.cpp
index f19f713..4489f6c 100644
--- a/daemon/face/lp-reliability.cpp
+++ b/daemon/face/lp-reliability.cpp
@@ -36,7 +36,6 @@
, m_linkService(linkService)
, m_firstUnackedFrag(m_unackedFrags.begin())
, m_lastTxSeqNo(-1) // set to "-1" to start TxSequence numbers at 0
- , m_isIdleAckTimerRunning(false)
{
BOOST_ASSERT(m_linkService != nullptr);
BOOST_ASSERT(m_options.idleAckTimerPeriod > 0_ns);
@@ -48,7 +47,7 @@
BOOST_ASSERT(options.idleAckTimerPeriod > 0_ns);
if (m_options.isEnabled && !options.isEnabled) {
- this->stopIdleAckTimer();
+ m_idleAckTimer.cancel();
}
m_options = options;
@@ -81,7 +80,7 @@
std::forward_as_tuple(txSeq),
std::forward_as_tuple(frag));
unackedFragsIt->second.sendTime = sendTime;
- unackedFragsIt->second.rtoTimer = getScheduler().schedule(m_rto.computeRto(),
+ unackedFragsIt->second.rtoTimer = getScheduler().schedule(m_rttEst.getEstimatedRto(),
[=] { onLpPacketLost(txSeq); });
unackedFragsIt->second.netPkt = netPkt;
@@ -114,8 +113,8 @@
frag.rtoTimer.cancel();
if (frag.retxCount == 0) {
- // This sequence had no retransmissions, so use it to calculate the RTO
- m_rto.addMeasurement(time::duration_cast<RttEstimator::Duration>(now - frag.sendTime));
+ // This sequence had no retransmissions, so use it to estimate the RTO
+ m_rttEst.addMeasurement(now - frag.sendTime, 1);
}
// Look for frags with TxSequence numbers < ackSeq (allowing for wraparound) and consider them
@@ -136,7 +135,7 @@
// Resend or fail fragments considered lost. Potentially increment the start of the window.
for (lp::Sequence txSeq : lostLpPackets) {
if (removedLpPackets.find(txSeq) == removedLpPackets.end()) {
- auto removedThisTxSeq = this->onLpPacketLost(txSeq);
+ auto removedThisTxSeq = onLpPacketLost(txSeq);
for (auto removedTxSeq : removedThisTxSeq) {
removedLpPackets.insert(removedTxSeq);
}
@@ -147,9 +146,7 @@
// If packet has Fragment and TxSequence fields, extract TxSequence and add to AckQueue
if (pkt.has<lp::FragmentField>() && pkt.has<lp::TxSequenceField>()) {
m_ackQueue.push(pkt.get<lp::TxSequenceField>());
- if (!m_isIdleAckTimerRunning) {
- this->startIdleAckTimer();
- }
+ startIdleAckTimer();
}
}
@@ -168,7 +165,7 @@
while (!m_ackQueue.empty()) {
lp::Sequence ackSeq = m_ackQueue.front();
- // Ack size = Ack TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + uint64_t (8 octets)
+ // Ack size = Ack TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + lp::Sequence (8 octets)
const ssize_t ackSize = tlv::sizeOfVarNumber(lp::tlv::Ack) +
tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
sizeof(lp::Sequence);
@@ -197,25 +194,18 @@
void
LpReliability::startIdleAckTimer()
{
- BOOST_ASSERT(!m_isIdleAckTimerRunning);
- m_isIdleAckTimerRunning = true;
+ if (m_idleAckTimer) {
+ // timer is already running, do nothing
+ return;
+ }
m_idleAckTimer = getScheduler().schedule(m_options.idleAckTimerPeriod, [this] {
while (!m_ackQueue.empty()) {
m_linkService->requestIdlePacket(0);
}
-
- m_isIdleAckTimerRunning = false;
});
}
-void
-LpReliability::stopIdleAckTimer()
-{
- m_idleAckTimer.cancel();
- m_isIdleAckTimerRunning = false;
-}
-
std::vector<lp::Sequence>
LpReliability::findLostLpPackets(LpReliability::UnackedFrags::iterator ackIt)
{
@@ -305,7 +295,8 @@
m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt), 0);
// Start RTO timer for this sequence
- newTxFrag.rtoTimer = getScheduler().schedule(m_rto.computeRto(), [=] { onLpPacketLost(newTxSeq); });
+ newTxFrag.rtoTimer = getScheduler().schedule(m_rttEst.getEstimatedRto(),
+ [=] { onLpPacketLost(newTxSeq); });
}
return removedThisTxSeq;
diff --git a/daemon/face/lp-reliability.hpp b/daemon/face/lp-reliability.hpp
index 5018730..ca8f360 100644
--- a/daemon/face/lp-reliability.hpp
+++ b/daemon/face/lp-reliability.hpp
@@ -26,10 +26,11 @@
#ifndef NFD_DAEMON_FACE_LP_RELIABILITY_HPP
#define NFD_DAEMON_FACE_LP_RELIABILITY_HPP
-#include "core/rtt-estimator.hpp"
+#include "core/common.hpp"
#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/lp/sequence.hpp>
+#include <ndn-cxx/util/rtt-estimator.hpp>
#include <queue>
@@ -126,11 +127,6 @@
void
startIdleAckTimer();
- /** \brief cancel the idle Ack timer
- */
- void
- stopIdleAckTimer();
-
/** \brief find and mark as lost fragments where a configurable number of Acks
* (\p m_options.seqNumLossThreshold) have been received for greater TxSequence numbers
* \param ackIt iterator pointing to acknowledged fragment
@@ -198,8 +194,10 @@
};
public:
- /// TxSequence TLV-TYPE (3 octets) + TxSequence TLV-LENGTH (1 octet) + sizeof(lp::Sequence)
- static constexpr size_t RESERVED_HEADER_SPACE = 3 + 1 + sizeof(lp::Sequence);
+ /// TxSequence TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + lp::Sequence (8 octets)
+ static constexpr size_t RESERVED_HEADER_SPACE = tlv::sizeOfVarNumber(lp::tlv::TxSequence) +
+ tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
+ sizeof(lp::Sequence);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
Options m_options;
@@ -214,8 +212,7 @@
std::queue<lp::Sequence> m_ackQueue;
lp::Sequence m_lastTxSeqNo;
scheduler::ScopedEventId m_idleAckTimer;
- bool m_isIdleAckTimerRunning;
- RttEstimator m_rto;
+ ndn::util::RttEstimator m_rttEst;
};
} // namespace face
diff --git a/tests/daemon/face/lp-reliability.t.cpp b/tests/daemon/face/lp-reliability.t.cpp
index 5e73c03..e814042 100644
--- a/tests/daemon/face/lp-reliability.t.cpp
+++ b/tests/daemon/face/lp-reliability.t.cpp
@@ -40,8 +40,6 @@
using namespace nfd::tests;
-BOOST_AUTO_TEST_SUITE(Face)
-
class DummyLpReliabilityLinkService : public GenericLinkService
{
public:
@@ -58,11 +56,11 @@
Interest interest("/test/prefix");
interest.setCanBePrefix(false);
lp::Packet pkt;
- pkt.add<lp::FragmentField>(make_pair(interest.wireEncode().begin(), interest.wireEncode().end()));
+ pkt.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
m_reliability.handleOutgoing(frags, std::move(pkt), true);
}
- for (lp::Packet frag : frags) {
+ for (auto frag : frags) {
this->sendLpPacket(std::move(frag), 0);
}
}
@@ -116,9 +114,7 @@
netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
{
return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
- [txSeq] (const LpReliability::UnackedFrags::iterator& frag) {
- return frag->first == txSeq;
- });
+ [txSeq] (auto fragIt) { return fragIt->first == txSeq; });
}
/** \brief make an LpPacket with fragment of specified size
@@ -134,7 +130,7 @@
lp::Packet pkt;
ndn::Buffer buf(payloadSize);
std::memcpy(buf.data(), &pktNo, sizeof(pktNo));
- pkt.set<lp::FragmentField>(make_pair(buf.cbegin(), buf.cend()));
+ pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
return pkt;
}
@@ -164,6 +160,7 @@
LpReliability* reliability;
};
+BOOST_AUTO_TEST_SUITE(Face)
BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
BOOST_AUTO_TEST_CASE(SendNoFragmentField)
@@ -715,7 +712,7 @@
BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
{
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
lp::Packet pkt1 = makeFrag(100, 40);
@@ -723,7 +720,7 @@
reliability->processIncomingPacket(pkt1);
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
@@ -732,14 +729,14 @@
reliability->processIncomingPacket(pkt2);
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
// T+5ms
advanceClocks(1_ms, 5);
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
}
BOOST_AUTO_TEST_CASE(PiggybackAcks)
@@ -820,38 +817,38 @@
BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
{
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
lp::Packet pkt1 = makeFrag(1, 100);
pkt1.add<lp::TxSequenceField>(12);
reliability->processIncomingPacket({pkt1});
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
// T+1ms
advanceClocks(1_ms, 1);
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
lp::Packet pkt2 = makeFrag(2, 100);
pkt2.add<lp::TxSequenceField>(13);
reliability->processIncomingPacket({pkt2});
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
// T+5ms
advanceClocks(1_ms, 4);
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
lp::Packet pkt3 = makeFrag(3, 100);
pkt3.add<lp::TxSequenceField>(15);
reliability->processIncomingPacket({pkt3});
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
// T+9ms
advanceClocks(1_ms, 4);
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
// T+10ms
advanceClocks(1_ms, 1);
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
}
BOOST_AUTO_TEST_CASE(IdleAckTimer)
@@ -862,13 +859,13 @@
reliability->m_ackQueue.push(i);
expectedAcks.insert(i);
}
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
reliability->startIdleAckTimer();
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
// T+4ms: idle ack timer has not yet expired, no IDLE packet generated
advanceClocks(1_ms, 4);
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
@@ -876,7 +873,7 @@
// T+5ms: idle ack timer expires, IDLE packet generated
advanceClocks(1_ms, 1);
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
@@ -898,13 +895,13 @@
reliability->m_ackQueue.push(i);
expectedAcks.insert(i);
}
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
reliability->startIdleAckTimer();
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
// T+4ms: idle ack timer has not yet expired, no IDLE packet generated
advanceClocks(1_ms, 4);
- BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(reliability->m_idleAckTimer);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
@@ -912,7 +909,7 @@
// T+5ms: idle ack timer expires, IDLE packets generated
advanceClocks(1_ms, 1);
- BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+ BOOST_CHECK(!reliability->m_idleAckTimer);
BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
// MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for