30 #ifdef NDN_CXX_HAVE_STACKTRACE 31 #include <boost/stacktrace/stacktrace.hpp> 40 BOOST_CONCEPT_ASSERT((WireEncodable<Interest>));
41 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
42 BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
43 static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
44 "Interest::Error must inherit from tlv::Error");
46 #ifdef NDN_CXX_HAVE_TESTS 47 bool Interest::s_errorIfCanBePrefixUnset =
true;
48 #endif // NDN_CXX_HAVE_TESTS 49 boost::logic::tribool Interest::s_defaultCanBePrefix = boost::logic::indeterminate;
50 bool Interest::s_autoCheckParametersDigest =
true;
57 if (!boost::logic::indeterminate(s_defaultCanBePrefix)) {
72 static bool didWarn =
false;
75 std::cerr <<
"WARNING: Interest.CanBePrefix will be set to false in the near future. " 76 <<
"Please declare a preferred setting via Interest::setDefaultCanBePrefix.\n";
77 #ifdef NDN_CXX_HAVE_STACKTRACE 78 if (std::getenv(
"NDN_CXX_VERBOSE_CANBEPREFIX_UNSET_WARNING") !=
nullptr) {
79 std::cerr << boost::stacktrace::stacktrace(2, 64);
85 template<encoding::Tag TAG>
89 if (!m_isCanBePrefixSet) {
91 #ifdef NDN_CXX_HAVE_TESTS 92 if (s_errorIfCanBePrefixUnset) {
93 NDN_THROW(std::logic_error(
"Interest.CanBePrefix is unset"));
95 #endif // NDN_CXX_HAVE_TESTS 111 ssize_t digestIndex = findParametersDigestComponent(
getName());
112 BOOST_ASSERT(digestIndex != -2);
113 if (digestIndex == -1) {
115 NDN_THROW(
Error(
"Interest with parameters must have a ParametersSha256DigestComponent"));
118 NDN_THROW(
Error(
"Interest without parameters must not have a ParametersSha256DigestComponent"));
121 size_t totalLength = 0;
124 std::for_each(m_parameters.rbegin(), m_parameters.rend(), [&] (
const Block& b) {
125 totalLength += encoder.prependBlock(b);
131 totalLength += encoder.prependByteArrayBlock(
tlv::HopLimit, &hopLimit,
sizeof(hopLimit));
142 totalLength += encoder.prependByteArrayBlock(
tlv::Nonce, reinterpret_cast<uint8_t*>(&nonce),
sizeof(nonce));
162 totalLength += encoder.prependVarNumber(totalLength);
210 Name tempName(*element);
211 if (tempName.
empty()) {
214 ssize_t digestIndex = findParametersDigestComponent(tempName);
215 if (digestIndex == -2) {
216 NDN_THROW(
Error(
"Name has more than one ParametersSha256DigestComponent"));
220 m_isCanBePrefixSet =
true;
221 m_canBePrefix = m_mustBeFresh =
false;
222 m_forwardingHint = {};
226 m_parameters.clear();
229 for (++element; element != m_wire.
elements_end(); ++element) {
230 switch (element->type()) {
232 if (lastElement >= 2) {
235 if (element->value_size() != 0) {
238 m_canBePrefix =
true;
243 if (lastElement >= 3) {
246 if (element->value_size() != 0) {
249 m_mustBeFresh =
true;
254 if (lastElement >= 4) {
262 if (lastElement >= 5) {
266 if (element->value_size() !=
sizeof(nonce)) {
269 std::memcpy(&nonce, element->value(),
sizeof(nonce));
275 if (lastElement >= 6) {
283 if (lastElement >= 7) {
286 if (element->value_size() != 1) {
289 m_hopLimit = *element->value();
294 if (lastElement >= 8) {
298 m_parameters.push_back(*element);
309 m_parameters.push_back(*element);
318 NDN_THROW(
Error(
"ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
325 std::ostringstream os;
335 size_t interestNameLength = m_name.
size();
337 size_t fullNameLength = dataName.
size() + 1;
340 if (interestNameLength == fullNameLength) {
377 ssize_t digestIndex = findParametersDigestComponent(name);
378 if (digestIndex == -2) {
379 NDN_THROW(std::invalid_argument(
"Name cannot have more than one ParametersSha256DigestComponent"));
381 if (name != m_name) {
384 addOrReplaceParametersDigestComponent();
394 m_forwardingHint = value;
412 if (nonce != m_nonce) {
425 uint32_t oldNonce = *m_nonce;
426 while (m_nonce == oldNonce)
435 if (lifetime < 0_ms) {
436 NDN_THROW(std::invalid_argument(
"InterestLifetime must be >= 0"));
438 if (lifetime != m_interestLifetime) {
439 m_interestLifetime = lifetime;
448 if (hopLimit != m_hopLimit) {
449 m_hopLimit = hopLimit;
456 Interest::setApplicationParametersInternal(
Block parameters)
459 if (m_parameters.empty()) {
460 m_parameters.push_back(
std::move(parameters));
475 setApplicationParametersInternal(parameters);
480 addOrReplaceParametersDigestComponent();
488 if (value ==
nullptr && length != 0) {
489 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
492 addOrReplaceParametersDigestComponent();
500 if (value ==
nullptr) {
501 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
504 addOrReplaceParametersDigestComponent();
512 m_parameters.clear();
513 ssize_t digestIndex = findParametersDigestComponent(
getName());
514 if (digestIndex >= 0) {
515 m_name.
erase(digestIndex);
526 ssize_t digestIndex = findParametersDigestComponent(
getName());
527 if (digestIndex == -1) {
531 BOOST_ASSERT(digestIndex >= 0);
537 const auto& digestComponent =
getName()[digestIndex];
538 auto digest = computeParametersDigest();
540 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
541 digest->begin(), digest->end());
545 Interest::computeParametersDigest()
const 547 using namespace security::transform;
553 std::for_each(m_parameters.begin(), m_parameters.end(), [&] (
const Block& b) {
554 in.write(b.wire(), b.size());
562 Interest::addOrReplaceParametersDigestComponent()
566 ssize_t digestIndex = findParametersDigestComponent(
getName());
569 if (digestIndex == -1) {
571 m_name.append(
std::move(digestComponent));
575 BOOST_ASSERT(digestIndex >= 0);
577 m_name.set(digestIndex,
std::move(digestComponent));
582 Interest::findParametersDigestComponent(
const Name& name)
585 for (ssize_t i = 0; i < static_cast<ssize_t>(name.
size()); i++) {
586 if (name[i].isParametersSha256Digest()) {
603 auto printOne = [&] (
const auto&... args) {
606 using expand =
int[];
607 (void)expand{(os << args, 0)...};
611 printOne(
"CanBePrefix");
614 printOne(
"MustBeFresh");
617 printOne(
"Nonce=", interest.
getNonce());
623 printOne(
"HopLimit=", static_cast<unsigned>(*interest.
getHopLimit()));
static Component fromParametersSha256Digest(ConstBufferPtr digest)
Create ParametersSha256DigestComponent component.
bool isParametersDigestValid() const
Check if the ParametersSha256DigestComponent in the name is valid.
bool getMustBeFresh() const noexcept
Check whether the MustBeFresh element is present.
const Block & wireEncode() const
Encode into a Block according to NDN Packet Format v0.3.
const Name & getName() const
Get name.
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
std::string to_string(const T &val)
std::string toUri() const
Return a URI-like string that represents the Interest.
const Component & get(ssize_t i) const
Returns an immutable reference to the component at the specified index.
constexpr bool isCriticalType(uint32_t type)
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
void refreshNonce()
Change nonce value.
bool getCanBePrefix() const noexcept
Check whether the CanBePrefix element is present.
std::ostream & operator<<(std::ostream &os, const Data &data)
bool isPrefixOf(const Name &other) const
Check if this name is a prefix of another name.
Interest(const Name &name=Name(), time::milliseconds lifetime=DEFAULT_INTEREST_LIFETIME)
Construct an Interest with given name and lifetime.
bool hasApplicationParameters() const noexcept
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
void parse() const
Parse TLV-VALUE into sub-elements.
Interest & setApplicationParameters(const Block ¶meters)
Set ApplicationParameters from a Block.
Represents a TLV element of NDN packet format.
Represents an Interest packet.
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
element_const_iterator elements_begin() const
Equivalent to elements().begin()
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32)
void wireDecode(const Block &block, bool wantSort=true)
decode a DelegationList
element_const_iterator elements_end() const
Equivalent to elements().end()
void reset() noexcept
Reset the Block to a default-constructed state.
size_t prependEmptyBlock(EncodingImpl< TAG > &encoder, uint32_t type)
Prepend an empty TLV element.
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
const DelegationList & getForwardingHint() const noexcept
uint32_t getNonce() const
Get nonce value.
static void warnOnceCanBePrefixUnset()
Interest & setNonce(uint32_t nonce)
Set nonce value.
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
bool matchesData(const Data &data) const
Check if Interest can be satisfied by data.
size_t wireEncode(EncodingImpl< TAG > &encoder, uint32_t type=tlv::ForwardingHint) const
encode into wire format
bool hasNonce() const noexcept
Check if the Nonce element is present.
bool isImplicitSha256Digest() const
Check if the component is ImplicitSha256DigestComponent.
optional< uint8_t > getHopLimit() const noexcept
Use the SHA256 hash of the public key as key id.
Represents an absolute name.
const Name & getFullName() const
Get full name including implicit digest.
size_t size() const
Returns the number of components.
void wireDecode(const Block &wire)
Decode from wire according to NDN Packet Format v0.3.
Interest & setHopLimit(optional< uint8_t > hopLimit)
Set the Interest's hop limit.
bool isValid() const noexcept
Check if the Block is valid.
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer.
void encode()
Encode sub-elements into TLV-VALUE.
void erase(ssize_t i)
Erase the component at the specified index.
const Name & getName() const noexcept
represents a list of Delegations
bool empty() const
Checks if the name is empty, i.e.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Interest & setForwardingHint(const DelegationList &value)
Interest & setInterestLifetime(time::milliseconds lifetime)
Set the Interest's lifetime.
const time::milliseconds DEFAULT_INTEREST_LIFETIME
default value for InterestLifetime
time::milliseconds getInterestLifetime() const noexcept
implements an output stream that constructs ndn::Buffer
Interest & unsetApplicationParameters()
Remove the ApplicationParameters element from this Interest.
time::milliseconds getFreshnessPeriod() const
Represents a Data packet.
EncodingImpl< EncoderTag > EncodingBuffer
uint32_t type() const
Return the TLV-TYPE of the Block.
EncodingImpl< EstimatorTag > EncodingEstimator
Interest & setCanBePrefix(bool canBePrefix)
Add or remove CanBePrefix element.
shared_ptr< const Buffer > ConstBufferPtr
Interest & setName(const Name &name)
Set the Interest's name.