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 bool Interest::s_autoCheckParametersDigest =
true;
58 template<encoding::Tag TAG>
74 ssize_t digestIndex = findParametersDigestComponent(
getName());
75 BOOST_ASSERT(digestIndex != -2);
76 if (digestIndex == -1) {
78 NDN_THROW(
Error(
"Interest with parameters must have a ParametersSha256DigestComponent"));
81 NDN_THROW(
Error(
"Interest without parameters must not have a ParametersSha256DigestComponent"));
84 size_t totalLength = 0;
87 for (
const auto& block : m_parameters | boost::adaptors::reversed) {
108 if (!m_forwardingHint.empty()) {
110 m_forwardingHint.begin(), m_forwardingHint.end());
126 totalLength += encoder.prependVarNumber(totalLength);
174 Name tempName(*element);
175 if (tempName.
empty()) {
178 ssize_t digestIndex = findParametersDigestComponent(tempName);
179 if (digestIndex == -2) {
180 NDN_THROW(
Error(
"Name has more than one ParametersSha256DigestComponent"));
182 m_name = std::move(tempName);
184 m_canBePrefix = m_mustBeFresh =
false;
185 m_forwardingHint.clear();
189 m_parameters.clear();
192 for (++element; element != m_wire.
elements_end(); ++element) {
193 switch (element->type()) {
195 if (lastElement >= 2) {
198 if (element->value_size() != 0) {
201 m_canBePrefix =
true;
206 if (lastElement >= 3) {
209 if (element->value_size() != 0) {
212 m_mustBeFresh =
true;
217 if (lastElement >= 4) {
226 for (
const auto& del : element->elements()) {
227 switch (del.type()) {
230 m_forwardingHint.emplace_back(del);
240 m_forwardingHint.emplace_back(del.get(
tlv::Name));
257 if (lastElement >= 5) {
260 if (element->value_size() !=
Nonce().size()) {
264 std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
269 if (lastElement >= 6) {
277 if (lastElement >= 7) {
280 if (element->value_size() != 1) {
283 m_hopLimit = *element->value();
288 if (lastElement >= 8) {
292 m_parameters.push_back(*element);
303 m_parameters.push_back(*element);
312 NDN_THROW(
Error(
"ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
319 std::ostringstream os;
329 size_t interestNameLength = m_name.
size();
331 size_t fullNameLength = dataName.
size() + 1;
334 if (interestNameLength == fullNameLength) {
371 ssize_t digestIndex = findParametersDigestComponent(name);
372 if (digestIndex == -2) {
373 NDN_THROW(std::invalid_argument(
"Name cannot have more than one ParametersSha256DigestComponent"));
376 if (name != m_name) {
379 addOrReplaceParametersDigestComponent();
389 m_forwardingHint = std::move(value);
399 std::memcpy(n.data(), &r,
sizeof(r));
407 m_nonce = generateNonce();
416 if (nonce != m_nonce) {
429 auto oldNonce = *m_nonce;
430 while (m_nonce == oldNonce)
431 m_nonce = generateNonce();
439 if (lifetime < 0_ms) {
440 NDN_THROW(std::invalid_argument(
"InterestLifetime must be >= 0"));
443 if (lifetime != m_interestLifetime) {
444 m_interestLifetime = lifetime;
453 if (hopLimit != m_hopLimit) {
454 m_hopLimit = hopLimit;
461 Interest::setApplicationParametersInternal(
Block parameters)
464 if (m_parameters.empty()) {
465 m_parameters.push_back(std::move(parameters));
469 m_parameters[0] = std::move(parameters);
472 addOrReplaceParametersDigestComponent();
481 NDN_THROW(std::invalid_argument(
"ApplicationParameters block must be valid"));
485 return setApplicationParametersInternal(parameters);
501 if (value ==
nullptr) {
502 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
511 m_parameters.clear();
512 ssize_t digestIndex = findParametersDigestComponent(
getName());
513 if (digestIndex >= 0) {
514 m_name.
erase(digestIndex);
523 return m_parameters.size() >= 3 &&
530 optional<SignatureInfo>
534 if (blockIt != m_parameters.end()) {
544 if (m_parameters.empty()) {
549 auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
550 return block.type() == tlv::InterestSignatureInfo;
554 if (infoIt != m_parameters.end()) {
555 if (*infoIt == encodedInfo) {
561 *infoIt = std::move(encodedInfo);
566 m_parameters.insert(valueIt, std::move(encodedInfo));
569 addOrReplaceParametersDigestComponent();
578 if (blockIt != m_parameters.end()) {
585 Interest::setSignatureValueInternal(
Block sigValue)
589 if (infoIt == m_parameters.end()) {
590 NDN_THROW(Error(
"InterestSignatureInfo must be present to set InterestSignatureValue"));
593 auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
594 return block.type() == tlv::InterestSignatureValue;
597 if (valueIt != m_parameters.end()) {
598 if (*valueIt == sigValue) {
604 *valueIt = std::move(sigValue);
608 valueIt = m_parameters.insert(std::next(infoIt), std::move(sigValue));
614 addOrReplaceParametersDigestComponent();
628 if (value ==
nullptr) {
629 NDN_THROW(std::invalid_argument(
"InterestSignatureValue buffer cannot be nullptr"));
645 BOOST_ASSERT(!m_name.
empty());
647 NDN_THROW(
Error(
"Interest Name must end with a ParametersSha256DigestComponent"));
650 bufs.emplace_back(m_name[0].data(), m_name[-1].data());
654 if (sigInfoIt == m_parameters.end()) {
663 bufs.emplace_back(m_parameters.front().begin(), lastSignedIt->end());
673 ssize_t digestIndex = findParametersDigestComponent(
getName());
674 if (digestIndex == -1) {
678 BOOST_ASSERT(digestIndex >= 0);
684 const auto& digestComponent =
getName()[digestIndex];
685 auto digest = computeParametersDigest();
687 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
688 digest->begin(), digest->end());
692 Interest::computeParametersDigest()
const
694 using namespace security::transform;
700 for (
const auto& block : m_parameters) {
709 Interest::addOrReplaceParametersDigestComponent()
713 ssize_t digestIndex = findParametersDigestComponent(
getName());
716 if (digestIndex == -1) {
718 m_name.
append(std::move(digestComponent));
722 BOOST_ASSERT(digestIndex >= 0);
724 m_name.
set(digestIndex, std::move(digestComponent));
729 Interest::findParametersDigestComponent(
const Name& name)
732 for (ssize_t i = 0; i < static_cast<ssize_t>(name.size()); i++) {
733 if (name[i].isParametersSha256Digest()) {
742 std::vector<Block>::const_iterator
743 Interest::findFirstParameter(uint32_t type)
const
745 return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (
const Block& block) {
746 return block.type() == type;
758 auto printOne = [&] (
const auto&... args) {
761 using expand =
int[];
762 (void)expand{(os << args, 0)...};
766 printOne(
"CanBePrefix");
769 printOne(
"MustBeFresh");
772 printOne(
"Nonce=", interest.
getNonce());
778 printOne(
"HopLimit=",
static_cast<unsigned>(*interest.
getHopLimit()));
Represents a TLV element of the NDN packet format.
element_const_iterator elements_begin() const noexcept
Equivalent to elements().begin().
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
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.
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
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 the data name.
time::milliseconds getFreshnessPeriod() const
Represents an Interest packet.
void wireDecode(const Block &wire)
Decode from wire.
const Name & getName() const noexcept
Interest & setHopLimit(optional< uint8_t > hopLimit)
Set the Interest's hop limit.
Nonce getNonce() const
Get nonce value.
Interest & setSignatureValue(span< const uint8_t > value)
Set InterestSignatureValue by copying from a contiguous sequence of bytes.
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
bool hasApplicationParameters() const noexcept
Return whether this Interest has any ApplicationParameters element.
time::milliseconds getInterestLifetime() const noexcept
Get the Interest's lifetime.
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 element.
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
Get the Interest's hop limit.
bool isSigned() const noexcept
Return whether the Interest is signed.
optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo element.
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 element.
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(const Name &name={}, time::milliseconds lifetime=DEFAULT_INTEREST_LIFETIME)
Construct an Interest with given name and lifetime.
Interest & setInterestLifetime(time::milliseconds lifetime)
Set the Interest's lifetime.
Represents an absolute name.
Name & set(ssize_t i, const Component &component)
Replace the component at the specified index.
size_t size() const noexcept
Returns the number of components.
bool empty() const noexcept
Checks if the name is empty, i.e., has no components.
Name & append(const Component &component)
Append a name component.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
void erase(ssize_t i)
Erase the component at the specified index.
bool isPrefixOf(const Name &other) const noexcept
Check if this name is a prefix of another name.
const Component & get(ssize_t i) const noexcept
Returns an immutable reference to the component at the specified index.
An output stream that writes to a Buffer.
shared_ptr< Buffer > buf()
Return a shared pointer to the underlying buffer.
Represents a SignatureInfo or InterestSignatureInfo TLV element.
bool isImplicitSha256Digest() const noexcept
Check if the component is an 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) noexcept
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
shared_ptr< const Buffer > ConstBufferPtr
std::ostream & operator<<(std::ostream &os, const Data &data)
const time::milliseconds DEFAULT_INTEREST_LIFETIME
Default value of InterestLifetime.