Add ability to configure maximum packet size for sync data
Change-Id: Iab7913d094a1b5d64ef5cc8e00b2624993b59ab5
Refs: #4140
diff --git a/src/logic.cpp b/src/logic.cpp
index 84cf5be..5e87153 100644
--- a/src/logic.cpp
+++ b/src/logic.cpp
@@ -26,6 +26,7 @@
#include "logic.hpp"
#include "logger.hpp"
+#include <ndn-cxx/util/backports.hpp>
#include <ndn-cxx/util/string-helper.hpp>
INIT_LOGGER(Logic);
@@ -59,6 +60,44 @@
const ndn::name::Component Logic::RESET_COMPONENT("reset");
const ndn::name::Component Logic::RECOVERY_COMPONENT("recovery");
+const size_t NDNLP_EXPECTED_OVERHEAD = 20;
+
+/**
+ * Get maximum packet limit
+ *
+ * By default, it returns `ndn::MAX_NDN_PACKET_SIZE`.
+ * The returned value can be customized using the environment variable `CHRONOSYNC_MAX_PACKET_SIZE`,
+ * but the returned value will be at least 500 and no more than `ndn::MAX_NDN_PACKET_SIZE`.
+ */
+#ifndef CHRONOSYNC_HAVE_TESTS
+static
+#endif // CHRONOSYNC_HAVE_TESTS
+size_t
+getMaxPacketLimit()
+{
+ static size_t limit = 0;
+#ifndef CHRONOSYNC_HAVE_TESTS
+ if (limit != 0) {
+ return limit;
+ }
+#endif // CHRONOSYNC_HAVE_TESTS
+
+ if (getenv("CHRONOSYNC_MAX_PACKET_SIZE") != nullptr) {
+ try {
+ limit = ndn::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
+ 500, ndn::MAX_NDN_PACKET_SIZE);
+ }
+ catch (const boost::bad_lexical_cast&) {
+ limit = ndn::MAX_NDN_PACKET_SIZE;
+ }
+ }
+ else {
+ limit = ndn::MAX_NDN_PACKET_SIZE;
+ }
+
+ return limit;
+}
+
Logic::Logic(ndn::Face& face,
const Name& syncPrefix,
const Name& defaultUserPrefix,
@@ -666,9 +705,11 @@
else
m_keyChain.sign(syncReply, security::signingByIdentity(m_nodeList[nodePrefix].signingId));
- if (syncReply.wireEncode().size() > ndn::MAX_NDN_PACKET_SIZE) {
- _LOG_DEBUG("Sync reply size exceeded MAX_NDN_PACKET_SIZE");
- auto maxContentSize = ndn::MAX_NDN_PACKET_SIZE - (syncReply.wireEncode().size() - state.wireEncode().size());
+ if (syncReply.wireEncode().size() > getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) {
+ _LOG_DEBUG("Sync reply size exceeded maximum packet limit (" << getMaxPacketLimit() << ")");
+ auto maxContentSize = getMaxPacketLimit() - (syncReply.wireEncode().size() - syncReply.getContent().size());
+ maxContentSize -= NDNLP_EXPECTED_OVERHEAD;
+
State partialState;
trimState(partialState, state, maxContentSize);
syncReply.setContent(partialState.wireEncode());
diff --git a/src/logic.hpp b/src/logic.hpp
index f1f6a0e..d33ed39 100644
--- a/src/logic.hpp
+++ b/src/logic.hpp
@@ -525,6 +525,10 @@
static int s_instanceCounter;
};
+#ifdef CHRONOSYNC_HAVE_TESTS
+size_t
+getMaxPacketLimit();
+#endif // CHRONOSYNC_HAVE_TESTS
} // namespace chronosync
diff --git a/tests/unit-tests/test-logic.cpp b/tests/unit-tests/test-logic.cpp
index dc7e2ef..fb0422a 100644
--- a/tests/unit-tests/test-logic.cpp
+++ b/tests/unit-tests/test-logic.cpp
@@ -348,6 +348,41 @@
BOOST_REQUIRE(syncReply.wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE);
}
+class MaxPacketCustomizationFixture
+{
+public:
+ MaxPacketCustomizationFixture()
+ {
+ if (getenv("CHRONOSYNC_MAX_PACKET_SIZE") != nullptr) {
+ oldSize = std::string(getenv("CHRONOSYNC_MAX_PACKET_SIZE"));
+ unsetenv("CHRONOSYNC_MAX_PACKET_SIZE");
+ }
+ }
+
+ ~MaxPacketCustomizationFixture()
+ {
+ if (oldSize) {
+ setenv("CHRONOSYNC_MAX_PACKET_SIZE", oldSize->c_str(), 1);
+ }
+ }
+private:
+ ndn::optional<std::string> oldSize;
+};
+
+BOOST_FIXTURE_TEST_CASE(MaxPacketCustomization, MaxPacketCustomizationFixture)
+{
+ BOOST_CHECK_EQUAL(getMaxPacketLimit(), ndn::MAX_NDN_PACKET_SIZE);
+
+ setenv("CHRONOSYNC_MAX_PACKET_SIZE", "1500", 1);
+ BOOST_CHECK_EQUAL(getMaxPacketLimit(), 1500);
+
+ setenv("CHRONOSYNC_MAX_PACKET_SIZE", ndn::to_string(ndn::MAX_NDN_PACKET_SIZE * 100).c_str(), 1);
+ BOOST_CHECK_EQUAL(getMaxPacketLimit(), ndn::MAX_NDN_PACKET_SIZE);
+
+ setenv("CHRONOSYNC_MAX_PACKET_SIZE", "1", 1);
+ BOOST_CHECK_EQUAL(getMaxPacketLimit(), 500);
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace test