30 #include <boost/range/adaptor/reversed.hpp>
37 BOOST_CONCEPT_ASSERT((WireEncodable<Interest>));
38 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
39 BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
40 static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
41 "Interest::Error must inherit from tlv::Error");
43 boost::logic::tribool Interest::s_defaultCanBePrefix = boost::logic::indeterminate;
44 bool Interest::s_autoCheckParametersDigest =
true;
51 if (!boost::logic::indeterminate(s_defaultCanBePrefix)) {
63 template<encoding::Tag TAG>
79 ssize_t digestIndex = findParametersDigestComponent(
getName());
80 BOOST_ASSERT(digestIndex != -2);
81 if (digestIndex == -1) {
83 NDN_THROW(
Error(
"Interest with parameters must have a ParametersSha256DigestComponent"));
86 NDN_THROW(
Error(
"Interest without parameters must not have a ParametersSha256DigestComponent"));
89 size_t totalLength = 0;
92 for (
const auto& block : m_parameters | boost::adaptors::reversed) {
113 if (!m_forwardingHint.empty()) {
115 m_forwardingHint.begin(), m_forwardingHint.end());
131 totalLength += encoder.prependVarNumber(totalLength);
179 Name tempName(*element);
180 if (tempName.
empty()) {
183 ssize_t digestIndex = findParametersDigestComponent(tempName);
184 if (digestIndex == -2) {
185 NDN_THROW(
Error(
"Name has more than one ParametersSha256DigestComponent"));
187 m_name = std::move(tempName);
189 m_canBePrefix = m_mustBeFresh =
false;
190 m_forwardingHint.clear();
194 m_parameters.clear();
197 for (++element; element != m_wire.
elements_end(); ++element) {
198 switch (element->type()) {
200 if (lastElement >= 2) {
203 if (element->value_size() != 0) {
206 m_canBePrefix =
true;
211 if (lastElement >= 3) {
214 if (element->value_size() != 0) {
217 m_mustBeFresh =
true;
222 if (lastElement >= 4) {
230 for (
const auto& del : element->elements()) {
231 switch (del.type()) {
234 m_forwardingHint.emplace_back(del);
243 m_forwardingHint.emplace_back(del.get(
tlv::Name));
260 if (lastElement >= 5) {
263 if (element->value_size() !=
Nonce().size()) {
267 std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
272 if (lastElement >= 6) {
280 if (lastElement >= 7) {
283 if (element->value_size() != 1) {
286 m_hopLimit = *element->value();
291 if (lastElement >= 8) {
295 m_parameters.push_back(*element);
306 m_parameters.push_back(*element);
315 NDN_THROW(
Error(
"ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
322 std::ostringstream os;
332 size_t interestNameLength = m_name.
size();
334 size_t fullNameLength = dataName.
size() + 1;
337 if (interestNameLength == fullNameLength) {
374 ssize_t digestIndex = findParametersDigestComponent(name);
375 if (digestIndex == -2) {
376 NDN_THROW(std::invalid_argument(
"Name cannot have more than one ParametersSha256DigestComponent"));
379 if (name != m_name) {
382 addOrReplaceParametersDigestComponent();
392 m_forwardingHint = std::move(value);
402 std::memcpy(n.data(), &r,
sizeof(r));
410 m_nonce = generateNonce();
419 if (nonce != m_nonce) {
432 auto oldNonce = *m_nonce;
433 while (m_nonce == oldNonce)
434 m_nonce = generateNonce();
442 if (lifetime < 0_ms) {
443 NDN_THROW(std::invalid_argument(
"InterestLifetime must be >= 0"));
446 if (lifetime != m_interestLifetime) {
447 m_interestLifetime = lifetime;
456 if (hopLimit != m_hopLimit) {
457 m_hopLimit = hopLimit;
464 Interest::setApplicationParametersInternal(
Block parameters)
467 if (m_parameters.empty()) {
468 m_parameters.push_back(std::move(parameters));
472 m_parameters[0] = std::move(parameters);
480 NDN_THROW(std::invalid_argument(
"ApplicationParameters block must be valid"));
484 setApplicationParametersInternal(parameters);
489 addOrReplaceParametersDigestComponent();
498 addOrReplaceParametersDigestComponent();
506 if (value ==
nullptr && length != 0) {
507 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
516 if (value ==
nullptr) {
517 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
521 addOrReplaceParametersDigestComponent();
529 m_parameters.clear();
530 ssize_t digestIndex = findParametersDigestComponent(
getName());
531 if (digestIndex >= 0) {
532 m_name.
erase(digestIndex);
541 return m_parameters.size() >= 3 &&
548 optional<SignatureInfo>
552 if (blockIt != m_parameters.end()) {
562 if (m_parameters.empty()) {
567 auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
568 return block.type() == tlv::InterestSignatureInfo;
572 if (infoIt != m_parameters.end()) {
573 if (*infoIt == encodedInfo) {
579 *infoIt = std::move(encodedInfo);
584 m_parameters.insert(valueIt, std::move(encodedInfo));
587 addOrReplaceParametersDigestComponent();
596 if (blockIt != m_parameters.end()) {
605 if (value ==
nullptr) {
606 NDN_THROW(std::invalid_argument(
"InterestSignatureValue buffer cannot be nullptr"));
611 if (infoIt == m_parameters.end()) {
612 NDN_THROW(
Error(
"InterestSignatureInfo must be present to set InterestSignatureValue"));
615 auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
616 return block.type() == tlv::InterestSignatureValue;
620 if (valueIt != m_parameters.end()) {
621 if (*valueIt == valueBlock) {
627 *valueIt = std::move(valueBlock);
631 valueIt = m_parameters.insert(std::next(infoIt), std::move(valueBlock));
637 addOrReplaceParametersDigestComponent();
652 BOOST_ASSERT(!m_name.
empty());
654 NDN_THROW(
Error(
"Interest Name must end with a ParametersSha256DigestComponent"));
657 bufs.emplace_back(m_name[0].wire(), m_name[-1].wire());
661 if (sigInfoIt == m_parameters.end()) {
670 bufs.emplace_back(m_parameters.front().begin(), lastSignedIt->end());
680 ssize_t digestIndex = findParametersDigestComponent(
getName());
681 if (digestIndex == -1) {
685 BOOST_ASSERT(digestIndex >= 0);
691 const auto& digestComponent =
getName()[digestIndex];
692 auto digest = computeParametersDigest();
694 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
695 digest->begin(), digest->end());
699 Interest::computeParametersDigest()
const
701 using namespace security::transform;
707 for (
const auto& block : m_parameters) {
708 in.write({block.wire(), block.size()});
716 Interest::addOrReplaceParametersDigestComponent()
720 ssize_t digestIndex = findParametersDigestComponent(
getName());
723 if (digestIndex == -1) {
725 m_name.
append(std::move(digestComponent));
729 BOOST_ASSERT(digestIndex >= 0);
731 m_name.
set(digestIndex, std::move(digestComponent));
736 Interest::findParametersDigestComponent(
const Name& name)
739 for (ssize_t i = 0; i < static_cast<ssize_t>(name.size()); i++) {
740 if (name[i].isParametersSha256Digest()) {
749 std::vector<Block>::const_iterator
750 Interest::findFirstParameter(uint32_t type)
const
752 return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (
const Block& block) {
753 return block.type() == type;
765 auto printOne = [&] (
const auto&... args) {
768 using expand =
int[];
769 (void)expand{(os << args, 0)...};
773 printOne(
"CanBePrefix");
776 printOne(
"MustBeFresh");
779 printOne(
"Nonce=", interest.
getNonce());
785 printOne(
"HopLimit=",
static_cast<unsigned>(*interest.
getHopLimit()));
Represents a TLV element of the NDN packet format.
uint32_t type() const
Return the TLV-TYPE of the Block.
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
bool isValid() const noexcept
Check if the Block is valid.
void encode()
Encode sub-elements into TLV-VALUE.
element_const_iterator elements_end() const
Equivalent to elements().end()
element_const_iterator elements_begin() const
Equivalent to elements().begin()
void reset() noexcept
Reset the Block to a default-constructed state.
void parse() const
Parse TLV-VALUE into sub-elements.
Represents a Data packet.
const Name & getFullName() const
Get full name including implicit digest.
const Name & getName() const noexcept
Get name.
time::milliseconds getFreshnessPeriod() const
Represents an Interest packet.
void wireDecode(const Block &wire)
Decode from wire.
Interest(const Name &name=Name(), time::milliseconds lifetime=DEFAULT_INTEREST_LIFETIME)
Construct an Interest with given name and lifetime.
const Name & getName() const noexcept
Interest & setHopLimit(optional< uint8_t > hopLimit)
Set the Interest's hop limit.
Nonce getNonce() const
Get nonce value.
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
Interest & setSignatureValue(ConstBufferPtr value)
Set the InterestSignatureValue.
bool hasApplicationParameters() const noexcept
Return whether this Interest has any ApplicationParameters.
time::milliseconds getInterestLifetime() const noexcept
bool matchesData(const Data &data) const
Check if Interest can be satisfied by data.
bool getMustBeFresh() const noexcept
Check whether the MustBeFresh element is present.
Block getSignatureValue() const
Get the InterestSignatureValue.
InputBuffers extractSignedRanges() const
Extract ranges of Interest covered by the signature in Packet Specification v0.3.
bool hasNonce() const noexcept
Check if the Nonce element is present.
bool getCanBePrefix() const noexcept
Check whether the CanBePrefix element is present.
void refreshNonce()
Change nonce value.
optional< uint8_t > getHopLimit() const noexcept
Interest & setCanBePrefix(bool canBePrefix)
Add or remove CanBePrefix element.
bool isSigned() const noexcept
Return whether the Interest is signed.
optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo.
Interest & unsetApplicationParameters()
Remove the ApplicationParameters element from this Interest.
bool isParametersDigestValid() const
Check if the ParametersSha256DigestComponent in the name is valid.
Interest & setName(const Name &name)
Set the Interest's name.
Interest & setSignatureInfo(const SignatureInfo &info)
Set the InterestSignatureInfo.
Interest & setApplicationParameters(const Block &block)
Set ApplicationParameters from a Block.
Interest & setForwardingHint(std::vector< Name > value)
std::string toUri() const
Return a URI-like string that represents the Interest.
Interest & setNonce(optional< Nonce > nonce)
Set the Interest's nonce.
const Block & wireEncode() const
Encode into a Block.
Interest & setInterestLifetime(time::milliseconds lifetime)
Set the Interest's lifetime.
Represents an absolute name.
bool empty() const
Checks if the name is empty, i.e.
Name & set(ssize_t i, const Component &component)
Replace the component at the specified index.
Name & append(const Component &component)
Append a component.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
bool isPrefixOf(const Name &other) const
Check if this name is a prefix of another name.
void erase(ssize_t i)
Erase the component at the specified index.
size_t size() const
Returns the number of components.
const Component & get(ssize_t i) const
Returns an immutable reference to the component at the specified index.
implements an output stream that constructs ndn::Buffer
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer.
Represents a SignatureInfo or InterestSignatureInfo TLV element.
static Component fromParametersSha256Digest(ConstBufferPtr digest)
Create ParametersSha256DigestComponent component.
bool isImplicitSha256Digest() const
Check if the component is ImplicitSha256DigestComponent.
represents an error in TLV encoding or decoding
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW_NESTED(e)
EncodingImpl< EstimatorTag > EncodingEstimator
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
Block makeEmptyBlock(uint32_t type)
Create an empty TLV block.
size_t prependEmptyBlock(EncodingImpl< TAG > &encoder, uint32_t type)
Prepend an empty TLV element.
Block makeBinaryBlock(uint32_t type, span< const uint8_t > value)
Create a TLV block copying the TLV-VALUE from a byte range.
size_t prependBinaryBlock(EncodingImpl< TAG > &encoder, uint32_t type, span< const uint8_t > value)
Prepend a TLV element containing a sequence of raw bytes.
EncodingImpl< EncoderTag > EncodingBuffer
size_t prependBlock(EncodingImpl< TAG > &encoder, const Block &block)
Prepend a TLV element.
std::string to_string(const errinfo_stacktrace &x)
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32)
boost::chrono::milliseconds milliseconds
@ ParametersSha256DigestComponent
constexpr bool isCriticalType(uint32_t type)
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
shared_ptr< const Buffer > ConstBufferPtr
const time::milliseconds DEFAULT_INTEREST_LIFETIME
default value for InterestLifetime
std::ostream & operator<<(std::ostream &os, const Data &data)