30#include <boost/range/adaptor/reversed.hpp>
51template<encoding::Tag TAG>
67 ssize_t digestIndex = findParametersDigestComponent(
getName());
68 BOOST_ASSERT(digestIndex != -2);
69 if (digestIndex == -1) {
71 NDN_THROW(
Error(
"Interest with parameters must have a ParametersSha256DigestComponent"));
74 NDN_THROW(
Error(
"Interest without parameters must not have a ParametersSha256DigestComponent"));
77 size_t totalLength = 0;
80 for (
const auto& block : m_parameters | boost::adaptors::reversed) {
81 totalLength += prependBlock(encoder, block);
86 totalLength += prependBinaryBlock(encoder,
tlv::HopLimit, {*m_hopLimit});
97 totalLength += prependBinaryBlock(encoder,
tlv::Nonce, *m_nonce);
100 if (!m_forwardingHint.empty()) {
102 m_forwardingHint.begin(), m_forwardingHint.end());
118 totalLength += encoder.prependVarNumber(totalLength);
131 EncodingEstimator estimator;
134 EncodingBuffer encoder(estimatedSize, 0);
166 Name tempName(*element);
167 if (tempName.
empty()) {
170 ssize_t digestIndex = findParametersDigestComponent(tempName);
171 if (digestIndex == -2) {
172 NDN_THROW(
Error(
"Name has more than one ParametersSha256DigestComponent"));
174 m_name = std::move(tempName);
176 m_canBePrefix = m_mustBeFresh =
false;
177 m_forwardingHint.clear();
181 m_parameters.clear();
184 for (++element; element != m_wire.
elements_end(); ++element) {
185 switch (element->type()) {
187 if (lastElement >= 2) {
190 if (element->value_size() != 0) {
193 m_canBePrefix =
true;
198 if (lastElement >= 3) {
201 if (element->value_size() != 0) {
204 m_mustBeFresh =
true;
209 if (lastElement >= 4) {
218 for (
const auto& del : element->elements()) {
219 switch (del.type()) {
222 m_forwardingHint.emplace_back(del);
232 m_forwardingHint.emplace_back(del.get(
tlv::Name));
240 NDN_THROW(
Error(
"Unexpected TLV-TYPE " + to_string(del.type()) +
" while decoding ForwardingHint"));
249 if (lastElement >= 5) {
252 if (element->value_size() !=
Nonce().size()) {
256 std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
261 if (lastElement >= 6) {
264 m_interestLifetime = readNonNegativeInteger(*element);
269 if (lastElement >= 7) {
272 if (element->value_size() != 1) {
275 m_hopLimit = *element->value();
280 if (lastElement >= 8) {
284 m_parameters.push_back(*element);
291 NDN_THROW(
Error(
"Unrecognized element of critical type " + to_string(element->type())));
295 m_parameters.push_back(*element);
304 NDN_THROW(
Error(
"ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
311 std::ostringstream os;
322 size_t fullNameLength = dataName.
size() + 1;
325 if (m_name.
size() == fullNameLength) {
335 else if (m_canBePrefix) {
339 return m_name == dataName;
356 ssize_t digestIndex = findParametersDigestComponent(name);
357 if (digestIndex == -2) {
358 NDN_THROW(std::invalid_argument(
"Name cannot have more than one ParametersSha256DigestComponent"));
361 if (name != m_name) {
364 addOrReplaceParametersDigestComponent();
374 if (canBePrefix != m_canBePrefix) {
375 m_canBePrefix = canBePrefix;
384 if (mustBeFresh != m_mustBeFresh) {
385 m_mustBeFresh = mustBeFresh;
394 m_forwardingHint = std::move(value);
399[[nodiscard]]
static auto
404 std::memcpy(n.data(), &r,
sizeof(r));
412 m_nonce = generateNonce();
421 if (nonce != m_nonce) {
434 auto oldNonce = *m_nonce;
435 while (m_nonce == oldNonce)
436 m_nonce = generateNonce();
444 if (m_interestLifetime >
static_cast<uint64_t
>(time::milliseconds::max().count())) {
445 return time::milliseconds::max();
453 if (lifetime < 0_ms) {
454 NDN_THROW(std::invalid_argument(
"InterestLifetime must be >= 0"));
457 uint64_t lifetimeMillis =
static_cast<uint64_t
>(lifetime.count());
458 if (lifetimeMillis != m_interestLifetime) {
459 m_interestLifetime = lifetimeMillis;
468 if (hopLimit != m_hopLimit) {
469 m_hopLimit = hopLimit;
476Interest::setApplicationParametersInternal(
Block parameters)
479 if (m_parameters.empty()) {
480 m_parameters.push_back(std::move(parameters));
484 m_parameters[0] = std::move(parameters);
487 addOrReplaceParametersDigestComponent();
496 NDN_THROW(std::invalid_argument(
"ApplicationParameters block must be valid"));
500 return setApplicationParametersInternal(parameters);
523 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be null"));
532 m_parameters.clear();
533 ssize_t digestIndex = findParametersDigestComponent(
getName());
534 if (digestIndex >= 0) {
535 m_name.
erase(digestIndex);
544 return m_parameters.size() >= 3 &&
551std::optional<SignatureInfo>
555 if (blockIt != m_parameters.end()) {
565 if (m_parameters.empty()) {
570 auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
571 return block.type() == tlv::InterestSignatureInfo;
575 if (infoIt != m_parameters.end()) {
576 if (*infoIt == encodedInfo) {
582 *infoIt = std::move(encodedInfo);
587 m_parameters.insert(valueIt, std::move(encodedInfo));
590 addOrReplaceParametersDigestComponent();
599 if (blockIt != m_parameters.end()) {
606Interest::setSignatureValueInternal(
Block sigValue)
610 if (infoIt == m_parameters.end()) {
611 NDN_THROW(Error(
"InterestSignatureInfo must be present to set InterestSignatureValue"));
614 auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
615 return block.type() == tlv::InterestSignatureValue;
618 if (valueIt != m_parameters.end()) {
619 if (*valueIt == sigValue) {
625 *valueIt = std::move(sigValue);
629 valueIt = m_parameters.insert(std::next(infoIt), std::move(sigValue));
635 addOrReplaceParametersDigestComponent();
650 NDN_THROW(std::invalid_argument(
"InterestSignatureValue buffer cannot be null"));
666 BOOST_ASSERT(!m_name.
empty());
668 NDN_THROW(
Error(
"Interest Name must end with a ParametersSha256DigestComponent"));
671 bufs.emplace_back(m_name[0].data(), m_name[-1].data());
675 if (sigInfoIt == m_parameters.end()) {
684 bufs.emplace_back(m_parameters.front().begin(), lastSignedIt->end());
694 ssize_t digestIndex = findParametersDigestComponent(
getName());
695 if (digestIndex == -1) {
699 BOOST_ASSERT(digestIndex >= 0);
705 const auto& digestComponent =
getName()[digestIndex];
706 auto digest = computeParametersDigest();
708 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
709 digest->begin(), digest->end());
713Interest::computeParametersDigest()
const
715 using namespace security::transform;
721 for (
const auto& block : m_parameters) {
730Interest::addOrReplaceParametersDigestComponent()
734 ssize_t digestIndex = findParametersDigestComponent(
getName());
737 if (digestIndex == -1) {
739 m_name.
append(std::move(digestComponent));
743 BOOST_ASSERT(digestIndex >= 0);
745 m_name.
set(digestIndex, std::move(digestComponent));
750Interest::findParametersDigestComponent(
const Name& name)
753 for (ssize_t i = 0; i < static_cast<ssize_t>(name.size()); i++) {
754 if (name[i].isParametersSha256Digest()) {
763std::vector<Block>::const_iterator
764Interest::findFirstParameter(uint32_t type)
const
766 return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (
const Block& block) {
767 return block.type() == type;
779 auto printOne = [&] (
const auto&... args) {
786 printOne(
"CanBePrefix");
789 printOne(
"MustBeFresh");
792 printOne(
"Nonce=", interest.
getNonce());
798 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 & getName() const noexcept
Get the Data name.
const Name & getFullName() const
Get the full name (including implicit digest).
Represents an Interest packet.
void wireDecode(const Block &wire)
Decode from wire.
std::optional< uint8_t > getHopLimit() const noexcept
Get the Interest's hop limit.
Interest & setHopLimit(std::optional< uint8_t > hopLimit)
Set the Interest's hop limit.
std::optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo element.
Interest & setCanBePrefix(bool canBePrefix)
Add or remove CanBePrefix element.
Interest & setNonce(std::optional< Nonce > nonce)
Set the Interest's nonce.
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 this Interest can be satisfied by data.
Interest & setMustBeFresh(bool mustBeFresh)
Add or remove MustBeFresh element.
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.
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.
bool isSigned() const noexcept
Return whether the Interest is signed.
Interest & unsetApplicationParameters()
Remove the ApplicationParameters element from this Interest.
const Name & getName() const noexcept
Get the Interest name.
bool isParametersDigestValid() const
Check if the ParametersSha256DigestComponent in the name is valid.
Interest & setName(const Name &name)
Set the Interest 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)
Set the ForwardingHint delegations (names).
std::string toUri() const
Return a URI-like string that represents the Interest.
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.
const Component & get(ssize_t i) const noexcept
Returns an immutable reference to the component at the specified index.
Name & set(ssize_t i, const Component &component)
Replace the component at the specified index.
Name & append(const Component &component)
Append a name component.
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.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Prepend wire encoding to encoder.
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.
An output stream that writes to a Buffer.
std::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)
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.
std::ostream & operator<<(std::ostream &os, const Data &data)
constexpr time::milliseconds DEFAULT_INTEREST_LIFETIME
Default value of InterestLifetime.
std::shared_ptr< const Buffer > ConstBufferPtr