interest: declare default CanBePrefix setting
refs #4581
Change-Id: I82de3b13c3010242fa7999a2564d4a5442dfd14b
diff --git a/src/interest.cpp b/src/interest.cpp
index f08eeb2..8fc04a3 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -23,7 +23,10 @@
#include "util/random.hpp"
#include "data.hpp"
+#include <boost/scope_exit.hpp>
+
#include <cstring>
+#include <iostream>
#include <sstream>
namespace ndn {
@@ -35,16 +38,27 @@
static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
"Interest::Error must inherit from tlv::Error");
+#ifdef NDN_CXX_HAVE_TESTS
+bool Interest::s_errorIfCanBePrefixUnset = true;
+#endif // NDN_CXX_HAVE_TESTS
+boost::logic::tribool Interest::s_defaultCanBePrefix = boost::logic::indeterminate;
+
Interest::Interest(const Name& name, time::milliseconds lifetime)
: m_name(name)
+ , m_isCanBePrefixSet(false)
, m_interestLifetime(lifetime)
{
if (lifetime < time::milliseconds::zero()) {
BOOST_THROW_EXCEPTION(std::invalid_argument("InterestLifetime must be >= 0"));
}
+
+ if (!boost::logic::indeterminate(s_defaultCanBePrefix)) {
+ setCanBePrefix(static_cast<bool>(s_defaultCanBePrefix));
+ }
}
Interest::Interest(const Block& wire)
+ : m_isCanBePrefixSet(true)
{
wireDecode(wire);
}
@@ -55,6 +69,20 @@
size_t
Interest::wireEncode(EncodingImpl<TAG>& encoder) const
{
+ static bool hasDefaultCanBePrefixWarning = false;
+ if (!m_isCanBePrefixSet) {
+ if (!hasDefaultCanBePrefixWarning) {
+ std::cerr << "WARNING: Interest.CanBePrefix will be set to 0 in the near future. "
+ << "Please declare a preferred setting via Interest::setDefaultCanBePrefix.";
+ hasDefaultCanBePrefixWarning = true;
+ }
+#ifdef NDN_CXX_HAVE_TESTS
+ if (s_errorIfCanBePrefixUnset) {
+ BOOST_THROW_EXCEPTION(std::logic_error("Interest.CanBePrefix is unset"));
+ }
+#endif // NDN_CXX_HAVE_TESTS
+ }
+
size_t totalLength = 0;
// Interest ::= INTEREST-TYPE TLV-LENGTH
@@ -131,6 +159,8 @@
setNonce(getNonce());
}
}
+
+ m_isCanBePrefixSet = true; // don't trigger warning from decoded packet
}
bool
@@ -493,6 +523,21 @@
// ---- operators ----
+bool
+operator==(const Interest& lhs, const Interest& rhs)
+{
+ bool wasCanBePrefixSetOnLhs = lhs.m_isCanBePrefixSet;
+ bool wasCanBePrefixSetOnRhs = rhs.m_isCanBePrefixSet;
+ lhs.m_isCanBePrefixSet = true;
+ rhs.m_isCanBePrefixSet = true;
+ BOOST_SCOPE_EXIT_ALL(&) {
+ lhs.m_isCanBePrefixSet = wasCanBePrefixSetOnLhs;
+ rhs.m_isCanBePrefixSet = wasCanBePrefixSetOnRhs;
+ };
+
+ return lhs.wireEncode() == rhs.wireEncode();
+}
+
std::ostream&
operator<<(std::ostream& os, const Interest& interest)
{
diff --git a/src/interest.hpp b/src/interest.hpp
index 7d0705e..1357352 100644
--- a/src/interest.hpp
+++ b/src/interest.hpp
@@ -27,6 +27,7 @@
#include "packet-base.hpp"
#include "selectors.hpp"
#include "util/time.hpp"
+#include <boost/logic/tribool.hpp>
namespace ndn {
@@ -147,6 +148,26 @@
return *this;
}
+ /** @brief Declare the default CanBePrefix setting of the application.
+ *
+ * As part of transitioning to NDN Packet Format v0.3, the default setting for CanBePrefix
+ * will be changed from "true" to "false". Application developers are advised to review all
+ * Interests expressed by their application and decide what CanBePrefix setting is appropriate
+ * for each Interest, to avoid breaking changes when the transition occurs. Application may
+ * either set CanBePrefix on a per-Interest basis, or declare a default CanBePrefix setting for
+ * all Interests expressed by the application using this function. If an application neither
+ * declares a default nor sets CanBePrefix on every Interest, Interest::wireEncode will print a
+ * one-time warning message.
+ *
+ * @note This function should not be used in libraries or in ndn-cxx unit tests.
+ * @sa https://redmine.named-data.net/projects/nfd/wiki/Packet03Transition
+ */
+ static void
+ setDefaultCanBePrefix(bool canBePrefix)
+ {
+ s_defaultCanBePrefix = canBePrefix;
+ }
+
/** @brief Check whether the CanBePrefix element is present.
*
* This is a getter for the CanBePrefix element as defined in NDN Packet Format v0.3.
@@ -171,6 +192,7 @@
{
m_selectors.setMaxSuffixComponents(canBePrefix ? -1 : 1);
m_wire.reset();
+ m_isCanBePrefixSet = true;
return *this;
}
@@ -390,14 +412,26 @@
void
decode03();
+#ifdef NDN_CXX_HAVE_TESTS
+public:
+ /** @brief If true, not setting CanBePrefix results in an error in wireEncode().
+ */
+ static bool s_errorIfCanBePrefixUnset;
+#endif // NDN_CXX_HAVE_TESTS
+
private:
+ static boost::logic::tribool s_defaultCanBePrefix;
+
Name m_name;
Selectors m_selectors;
+ mutable bool m_isCanBePrefixSet;
mutable optional<uint32_t> m_nonce;
time::milliseconds m_interestLifetime;
DelegationList m_forwardingHint;
mutable Block m_wire;
+
+ friend bool operator==(const Interest& lhs, const Interest& rhs);
};
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Interest);
@@ -405,11 +439,8 @@
std::ostream&
operator<<(std::ostream& os, const Interest& interest);
-inline bool
-operator==(const Interest& lhs, const Interest& rhs)
-{
- return lhs.wireEncode() == rhs.wireEncode();
-}
+bool
+operator==(const Interest& lhs, const Interest& rhs);
inline bool
operator!=(const Interest& lhs, const Interest& rhs)
diff --git a/src/security/command-interest-signer.cpp b/src/security/command-interest-signer.cpp
index 70e80a1..d4cb33a 100644
--- a/src/security/command-interest-signer.cpp
+++ b/src/security/command-interest-signer.cpp
@@ -56,6 +56,7 @@
CommandInterestSigner::makeCommandInterest(const Name& name, const SigningInfo& params)
{
Interest commandInterest(prepareCommandInterestName(name));
+ commandInterest.setCanBePrefix(false);
m_keyChain.sign(commandInterest, params);
return commandInterest;
}
diff --git a/src/security/v2/certificate-bundle-fetcher.cpp b/src/security/v2/certificate-bundle-fetcher.cpp
index 45a0c38..227a434 100644
--- a/src/security/v2/certificate-bundle-fetcher.cpp
+++ b/src/security/v2/certificate-bundle-fetcher.cpp
@@ -95,9 +95,10 @@
const ValidationContinuation& continueValidation)
{
Interest bundleInterest = Interest(bundleNamePrefix);
- bundleInterest.setInterestLifetime(m_bundleInterestLifetime);
+ bundleInterest.setCanBePrefix(true);
bundleInterest.setMustBeFresh(true);
bundleInterest.setChildSelector(1);
+ bundleInterest.setInterestLifetime(m_bundleInterestLifetime);
m_face.expressInterest(bundleInterest,
[=] (const Interest& interest, const Data& data) {
@@ -123,8 +124,9 @@
}
Interest bundleInterest(fullBundleName.getPrefix(-1).append(segmentNo));
- bundleInterest.setInterestLifetime(m_bundleInterestLifetime);
+ bundleInterest.setCanBePrefix(false);
bundleInterest.setMustBeFresh(false);
+ bundleInterest.setInterestLifetime(m_bundleInterestLifetime);
m_face.expressInterest(bundleInterest,
[=] (const Interest& interest, const Data& data) {
diff --git a/src/security/v2/certificate-request.hpp b/src/security/v2/certificate-request.hpp
index c1d88dc..9bcb93b 100644
--- a/src/security/v2/certificate-request.hpp
+++ b/src/security/v2/certificate-request.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -46,6 +46,12 @@
{
}
+ explicit
+ CertificateRequest(const Name& name)
+ : CertificateRequest(Interest(name).setCanBePrefix(true))
+ {
+ }
+
public:
/// @brief the name for the requested data/certificate.
Interest m_interest;
diff --git a/src/security/v2/validation-policy-config.cpp b/src/security/v2/validation-policy-config.cpp
index 2d82079..ff3f7bf 100644
--- a/src/security/v2/validation-policy-config.cpp
+++ b/src/security/v2/validation-policy-config.cpp
@@ -255,7 +255,7 @@
for (const auto& rule : m_dataRules) {
if (rule->match(tlv::Data, data.getName())) {
if (rule->check(tlv::Data, data.getName(), klName, state)) {
- return continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+ return continueValidation(make_shared<CertificateRequest>(klName), state);
}
// rule->check calls state->fail(...) if the check fails
return;
@@ -284,7 +284,7 @@
for (const auto& rule : m_interestRules) {
if (rule->match(tlv::Interest, interest.getName())) {
if (rule->check(tlv::Interest, interest.getName(), klName, state)) {
- return continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+ return continueValidation(make_shared<CertificateRequest>(klName), state);
}
// rule->check calls state->fail(...) if the check fails
return;
diff --git a/src/security/v2/validation-policy-simple-hierarchy.cpp b/src/security/v2/validation-policy-simple-hierarchy.cpp
index 0ad6128..e83c9bc 100644
--- a/src/security/v2/validation-policy-simple-hierarchy.cpp
+++ b/src/security/v2/validation-policy-simple-hierarchy.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -35,7 +35,7 @@
}
if (klName.getPrefix(-2).isPrefixOf(data.getName())) {
- continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+ continueValidation(make_shared<CertificateRequest>(klName), state);
}
else {
state->fail({ValidationError::Code::INVALID_KEY_LOCATOR, "Data signing policy violation for " +
@@ -53,7 +53,7 @@
}
if (klName.getPrefix(-2).isPrefixOf(interest.getName())) {
- continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+ continueValidation(make_shared<CertificateRequest>(klName), state);
}
else {
state->fail({ValidationError::Code::INVALID_KEY_LOCATOR, "Interest signing policy violation for " +
diff --git a/src/util/notification-subscriber.cpp b/src/util/notification-subscriber.cpp
index e69800a..f72aa58 100644
--- a/src/util/notification-subscriber.cpp
+++ b/src/util/notification-subscriber.cpp
@@ -79,6 +79,7 @@
return;
auto interest = make_shared<Interest>(m_prefix);
+ interest->setCanBePrefix(true);
interest->setMustBeFresh(true);
interest->setChildSelector(1);
interest->setInterestLifetime(getInterestLifetime());
@@ -101,6 +102,7 @@
nextName.appendSequenceNumber(m_lastSequenceNo + 1);
auto interest = make_shared<Interest>(nextName);
+ interest->setCanBePrefix(false);
interest->setInterestLifetime(getInterestLifetime());
m_lastInterestId = m_face.expressInterest(*interest,