30 #include <boost/range/adaptor/reversed.hpp>
51 template<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) {
100 if (!m_forwardingHint.empty()) {
102 m_forwardingHint.begin(), m_forwardingHint.end());
118 totalLength += encoder.prependVarNumber(totalLength);
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));
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) {
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);
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;
476 Interest::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 &&
551 std::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()) {
606 Interest::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());
713 Interest::computeParametersDigest()
const
715 using namespace security::transform;
721 for (
const auto& block : m_parameters) {
730 Interest::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));
750 Interest::findParametersDigestComponent(
const Name& name)
753 for (ssize_t i = 0; i < static_cast<ssize_t>(name.size()); i++) {
754 if (name[i].isParametersSha256Digest()) {
763 std::vector<Block>::const_iterator
764 Interest::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 & getFullName() const
Get the full name (including implicit digest).
const Name & getName() const noexcept
Get the Data name.
Represents an Interest packet.
void wireDecode(const Block &wire)
Decode from wire.
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.
const Name & getName() const noexcept
Get the Interest name.
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.
std::optional< uint8_t > getHopLimit() const noexcept
Get the Interest's hop limit.
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.
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.
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
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.
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.
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)
EncodingImpl< EstimatorTag > EncodingEstimator
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
Block makeStringBlock(uint32_t type, std::string_view value)
Create a TLV block containing a string.
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.
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