30 #ifdef NDN_CXX_HAVE_STACKTRACE 31 #include <boost/stacktrace/stacktrace.hpp> 34 #include <boost/range/adaptor/reversed.hpp> 42 BOOST_CONCEPT_ASSERT((WireEncodable<Interest>));
43 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
44 BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
45 static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
46 "Interest::Error must inherit from tlv::Error");
48 #ifdef NDN_CXX_HAVE_TESTS 49 bool Interest::s_errorIfCanBePrefixUnset =
true;
50 #endif // NDN_CXX_HAVE_TESTS 51 boost::logic::tribool Interest::s_defaultCanBePrefix = boost::logic::indeterminate;
52 bool Interest::s_autoCheckParametersDigest =
true;
59 if (!boost::logic::indeterminate(s_defaultCanBePrefix)) {
74 static bool didWarn =
false;
77 std::cerr <<
"WARNING: Interest.CanBePrefix will be set to false in the near future. " 78 <<
"Please declare a preferred setting via Interest::setDefaultCanBePrefix.\n";
79 #ifdef NDN_CXX_HAVE_STACKTRACE 80 if (std::getenv(
"NDN_CXX_VERBOSE_CANBEPREFIX_UNSET_WARNING") !=
nullptr) {
81 std::cerr << boost::stacktrace::stacktrace(2, 64);
87 template<encoding::Tag TAG>
91 if (!m_isCanBePrefixSet) {
93 #ifdef NDN_CXX_HAVE_TESTS 94 if (s_errorIfCanBePrefixUnset) {
95 NDN_THROW(std::logic_error(
"Interest.CanBePrefix is unset"));
97 #endif // NDN_CXX_HAVE_TESTS 112 ssize_t digestIndex = findParametersDigestComponent(
getName());
113 BOOST_ASSERT(digestIndex != -2);
114 if (digestIndex == -1) {
116 NDN_THROW(
Error(
"Interest with parameters must have a ParametersSha256DigestComponent"));
119 NDN_THROW(
Error(
"Interest without parameters must not have a ParametersSha256DigestComponent"));
122 size_t totalLength = 0;
125 for (
const auto& block : m_parameters | boost::adaptors::reversed) {
126 totalLength += encoder.prependBlock(block);
131 totalLength += encoder.prependByteArrayBlock(
tlv::HopLimit, &*m_hopLimit, 1);
143 totalLength += encoder.prependByteArrayBlock(
tlv::Nonce, m_nonce->data(), m_nonce->size());
163 totalLength += encoder.prependVarNumber(totalLength);
211 Name tempName(*element);
212 if (tempName.
empty()) {
215 ssize_t digestIndex = findParametersDigestComponent(tempName);
216 if (digestIndex == -2) {
217 NDN_THROW(
Error(
"Name has more than one ParametersSha256DigestComponent"));
219 m_name = std::move(tempName);
221 m_isCanBePrefixSet =
true;
222 m_canBePrefix = m_mustBeFresh =
false;
223 m_forwardingHint = {};
227 m_parameters.clear();
230 for (++element; element != m_wire.
elements_end(); ++element) {
231 switch (element->type()) {
233 if (lastElement >= 2) {
236 if (element->value_size() != 0) {
239 m_canBePrefix =
true;
244 if (lastElement >= 3) {
247 if (element->value_size() != 0) {
250 m_mustBeFresh =
true;
255 if (lastElement >= 4) {
263 if (lastElement >= 5) {
266 if (element->value_size() !=
Nonce().size()) {
270 std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
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"));
382 if (name != m_name) {
385 addOrReplaceParametersDigestComponent();
395 m_forwardingHint = value;
405 std::memcpy(n.data(), &r,
sizeof(r));
422 if (nonce != m_nonce) {
435 auto oldNonce = *m_nonce;
436 while (m_nonce == oldNonce)
445 if (lifetime < 0_ms) {
446 NDN_THROW(std::invalid_argument(
"InterestLifetime must be >= 0"));
449 if (lifetime != m_interestLifetime) {
450 m_interestLifetime = lifetime;
459 if (hopLimit != m_hopLimit) {
460 m_hopLimit = hopLimit;
467 Interest::setApplicationParametersInternal(
Block parameters)
470 if (m_parameters.empty()) {
471 m_parameters.push_back(std::move(parameters));
475 m_parameters[0] = std::move(parameters);
483 NDN_THROW(std::invalid_argument(
"ApplicationParameters block must be valid"));
487 setApplicationParametersInternal(parameters);
492 addOrReplaceParametersDigestComponent();
500 if (value ==
nullptr && length != 0) {
501 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
505 addOrReplaceParametersDigestComponent();
513 if (value ==
nullptr) {
514 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
518 addOrReplaceParametersDigestComponent();
526 m_parameters.clear();
527 ssize_t digestIndex = findParametersDigestComponent(
getName());
528 if (digestIndex >= 0) {
529 m_name.
erase(digestIndex);
538 return m_parameters.size() >= 3 &&
545 optional<SignatureInfo>
549 if (blockIt != m_parameters.end()) {
559 if (m_parameters.empty()) {
564 auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
569 if (infoIt != m_parameters.end()) {
570 if (*infoIt == encodedInfo) {
576 *infoIt = std::move(encodedInfo);
581 m_parameters.insert(valueIt, std::move(encodedInfo));
584 addOrReplaceParametersDigestComponent();
593 if (blockIt != m_parameters.end()) {
602 if (value ==
nullptr) {
603 NDN_THROW(std::invalid_argument(
"InterestSignatureValue buffer cannot be nullptr"));
608 if (infoIt == m_parameters.end()) {
609 NDN_THROW(
Error(
"InterestSignatureInfo must be present to set InterestSignatureValue"));
612 auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
617 if (valueIt != m_parameters.end()) {
618 if (*valueIt == valueBlock) {
624 *valueIt = std::move(valueBlock);
628 valueIt = m_parameters.insert(std::next(infoIt), std::move(valueBlock));
634 addOrReplaceParametersDigestComponent();
649 BOOST_ASSERT(!m_name.
empty());
651 NDN_THROW(
Error(
"Interest Name must end with a ParametersSha256DigestComponent"));
654 bufs.emplace_back(m_name[0].wire(), std::distance(m_name[0].wire(), m_name[-1].wire()));
658 if (sigInfoIt == m_parameters.end()) {
666 bufs.emplace_back(m_parameters.begin()->wire(),
667 std::distance(m_parameters.begin()->begin(), std::prev(sigValueIt)->end()));
676 ssize_t digestIndex = findParametersDigestComponent(
getName());
677 if (digestIndex == -1) {
681 BOOST_ASSERT(digestIndex >= 0);
687 const auto& digestComponent =
getName()[digestIndex];
688 auto digest = computeParametersDigest();
690 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
691 digest->begin(), digest->end());
695 Interest::computeParametersDigest()
const 697 using namespace security::transform;
703 for (
const auto& block : m_parameters) {
704 in.write(block.wire(), block.size());
712 Interest::addOrReplaceParametersDigestComponent()
716 ssize_t digestIndex = findParametersDigestComponent(
getName());
719 if (digestIndex == -1) {
721 m_name.append(std::move(digestComponent));
725 BOOST_ASSERT(digestIndex >= 0);
727 m_name.set(digestIndex, std::move(digestComponent));
732 Interest::findParametersDigestComponent(
const Name& name)
735 for (ssize_t i = 0; i < static_cast<ssize_t>(name.
size()); i++) {
736 if (name[i].isParametersSha256Digest()) {
745 std::vector<Block>::const_iterator
746 Interest::findFirstParameter(uint32_t type)
const 748 return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (
const Block& block) {
749 return block.type() == type;
761 auto printOne = [&] (
const auto&... args) {
764 using expand =
int[];
765 (void)expand{(os << args, 0)...};
769 printOne(
"CanBePrefix");
772 printOne(
"MustBeFresh");
775 printOne(
"Nonce=", interest.
getNonce());
781 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.
Represents a SignatureInfo or InterestSignatureInfo TLV element.
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)
Block makeEmptyBlock(uint32_t type)
Create an empty TLV block.
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
Return whether this Interest has any ApplicationParameters.
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
InputBuffers extractSignedRanges() const
Extract ranges of Interest covered by the signature in Packet Specification v0.3. ...
void parse() const
Parse TLV-VALUE into sub-elements.
Represents a TLV element of the 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.
Interest & setNonce(optional< Nonce > nonce)
Set the Interest's nonce.
optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo.
Interest & setSignatureValue(ConstBufferPtr value)
Set the InterestSignatureValue.
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
static void warnOnceCanBePrefixUnset()
Nonce getNonce() const
Get nonce value.
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
bool matchesData(const Data &data) const
Check if Interest can be satisfied by data.
const Name & getName() const noexcept
Get name.
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 SHA-256 hash of the public key as key id.
Represents an absolute name.
const Name & getFullName() const
Get full name including implicit digest.
size_t wireEncode(EncodingImpl< TAG > &encoder, Type type=Type::Data) const
Fast encoding or block size estimation.
size_t size() const
Returns the number of components.
void wireDecode(const Block &wire)
Decode from wire.
Interest & setHopLimit(optional< uint8_t > hopLimit)
Set the Interest's hop limit.
Block getSignatureValue() const
Get the InterestSignatureValue.
Interest & setSignatureInfo(const SignatureInfo &info)
Set the InterestSignatureInfo.
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.
bool empty() const noexcept
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.
Interest & setApplicationParameters(const Block &block)
Set ApplicationParameters from a Block.
EncodingImpl< EncoderTag > EncodingBuffer
uint32_t type() const
Return the TLV-TYPE of the Block.
EncodingImpl< EstimatorTag > EncodingEstimator
bool isSigned() const noexcept
Return whether the Interest is signed.
Interest & setCanBePrefix(bool canBePrefix)
Add or remove CanBePrefix element.
static auto generateNonce()
shared_ptr< const Buffer > ConstBufferPtr
Interest & setName(const Name &name)
Set the Interest's name.