30 #include <boost/range/adaptor/reversed.hpp> 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"));
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) {
225 for (
const auto& del : element->elements()) {
226 switch (del.type()) {
229 m_forwardingHint.emplace_back(del);
238 m_forwardingHint.emplace_back(del.get(
tlv::Name));
255 if (lastElement >= 5) {
258 if (element->value_size() !=
Nonce().size()) {
262 std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
267 if (lastElement >= 6) {
275 if (lastElement >= 7) {
278 if (element->value_size() != 1) {
281 m_hopLimit = *element->value();
286 if (lastElement >= 8) {
290 m_parameters.push_back(*element);
301 m_parameters.push_back(*element);
310 NDN_THROW(
Error(
"ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
317 std::ostringstream os;
327 size_t interestNameLength = m_name.
size();
329 size_t fullNameLength = dataName.
size() + 1;
332 if (interestNameLength == fullNameLength) {
369 ssize_t digestIndex = findParametersDigestComponent(name);
370 if (digestIndex == -2) {
371 NDN_THROW(std::invalid_argument(
"Name cannot have more than one ParametersSha256DigestComponent"));
374 if (name != m_name) {
377 addOrReplaceParametersDigestComponent();
397 std::memcpy(n.data(), &r,
sizeof(r));
414 if (nonce != m_nonce) {
427 auto oldNonce = *m_nonce;
428 while (m_nonce == oldNonce)
437 if (lifetime < 0_ms) {
438 NDN_THROW(std::invalid_argument(
"InterestLifetime must be >= 0"));
441 if (lifetime != m_interestLifetime) {
442 m_interestLifetime = lifetime;
451 if (hopLimit != m_hopLimit) {
452 m_hopLimit = hopLimit;
459 Interest::setApplicationParametersInternal(
Block parameters)
462 if (m_parameters.empty()) {
463 m_parameters.push_back(
std::move(parameters));
475 NDN_THROW(std::invalid_argument(
"ApplicationParameters block must be valid"));
479 setApplicationParametersInternal(parameters);
484 addOrReplaceParametersDigestComponent();
493 addOrReplaceParametersDigestComponent();
501 if (value ==
nullptr && length != 0) {
502 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
511 if (value ==
nullptr) {
512 NDN_THROW(std::invalid_argument(
"ApplicationParameters buffer cannot be nullptr"));
516 addOrReplaceParametersDigestComponent();
524 m_parameters.clear();
525 ssize_t digestIndex = findParametersDigestComponent(
getName());
526 if (digestIndex >= 0) {
527 m_name.
erase(digestIndex);
536 return m_parameters.size() >= 3 &&
543 optional<SignatureInfo>
547 if (blockIt != m_parameters.end()) {
557 if (m_parameters.empty()) {
562 auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
567 if (infoIt != m_parameters.end()) {
568 if (*infoIt == encodedInfo) {
579 m_parameters.insert(valueIt,
std::move(encodedInfo));
582 addOrReplaceParametersDigestComponent();
591 if (blockIt != m_parameters.end()) {
600 if (value ==
nullptr) {
601 NDN_THROW(std::invalid_argument(
"InterestSignatureValue buffer cannot be nullptr"));
606 if (infoIt == m_parameters.end()) {
607 NDN_THROW(
Error(
"InterestSignatureInfo must be present to set InterestSignatureValue"));
610 auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (
const Block& block) {
615 if (valueIt != m_parameters.end()) {
616 if (*valueIt == valueBlock) {
626 valueIt = m_parameters.insert(std::next(infoIt),
std::move(valueBlock));
632 addOrReplaceParametersDigestComponent();
647 BOOST_ASSERT(!m_name.
empty());
649 NDN_THROW(
Error(
"Interest Name must end with a ParametersSha256DigestComponent"));
652 bufs.emplace_back(m_name[0].data(), m_name[-1].data());
656 if (sigInfoIt == m_parameters.end()) {
665 bufs.emplace_back(m_parameters.front().begin(), lastSignedIt->end());
675 ssize_t digestIndex = findParametersDigestComponent(
getName());
676 if (digestIndex == -1) {
680 BOOST_ASSERT(digestIndex >= 0);
686 const auto& digestComponent =
getName()[digestIndex];
687 auto digest = computeParametersDigest();
689 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
690 digest->begin(), digest->end());
694 Interest::computeParametersDigest()
const 696 using namespace security::transform;
702 for (
const auto& block : m_parameters) {
711 Interest::addOrReplaceParametersDigestComponent()
715 ssize_t digestIndex = findParametersDigestComponent(
getName());
718 if (digestIndex == -1) {
720 m_name.append(
std::move(digestComponent));
724 BOOST_ASSERT(digestIndex >= 0);
726 m_name.set(digestIndex,
std::move(digestComponent));
731 Interest::findParametersDigestComponent(
const Name&
name)
734 for (ssize_t i = 0; i < static_cast<ssize_t>(name.
size()); i++) {
735 if (name[i].isParametersSha256Digest()) {
744 std::vector<Block>::const_iterator
745 Interest::findFirstParameter(uint32_t type)
const 747 return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (
const Block& block) {
748 return block.type() == type;
760 auto printOne = [&] (
const auto&... args) {
763 using expand =
int[];
764 (void)expand{(os << args, 0)...};
768 printOne(
"CanBePrefix");
771 printOne(
"MustBeFresh");
774 printOne(
"Nonce=", interest.
getNonce());
780 printOne(
"HopLimit=", static_cast<unsigned>(*interest.
getHopLimit()));
#define NDN_THROW_NESTED(e)
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.
Copyright (c) 2011-2015 Regents of the University of California.
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.
bool hasApplicationParameters() const noexcept
Return whether this Interest has any ApplicationParameters.
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
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)
a concept check for TLV abstraction with .wireEncode method
element_const_iterator elements_end() const
Equivalent to elements().end()
NDN_CXX_NODISCARD bool empty() const
Checks if the name is empty, i.e.
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.
Interest & setForwardingHint(std::vector< Name > value)
Nonce getNonce() const
Get nonce value.
bool matchesData(const Data &data) const
Check if Interest can be satisfied by data.
const Name & getName() const noexcept
Get name.
bool hasNonce() const noexcept
Check if the Nonce element is present.
bool isImplicitSha256Digest() const
Check if the component is an ImplicitSha256DigestComponent.
optional< uint8_t > getHopLimit() const noexcept
Use the SHA-256 hash of the public key as key id.
Represents an absolute name.
NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Interest)
size_t prependBinaryBlock(EncodingImpl< TAG > &encoder, uint32_t type, span< const uint8_t > value)
Prepend a TLV element containing a sequence of raw bytes.
const Name & getFullName() const
Get full name including implicit digest.
Block makeBinaryBlock(uint32_t type, span< const uint8_t > value)
Create a TLV block copying the TLV-VALUE from a byte range.
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.
Represents a name component.
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
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.
void erase(ssize_t i)
Erase the component at the specified index.
const Name & getName() const noexcept
size_t prependBlock(EncodingImpl< TAG > &encoder, const Block &block)
Prepend a TLV element.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
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(const Name &name={}, time::milliseconds lifetime=DEFAULT_INTEREST_LIFETIME)
Construct an Interest with given name and lifetime.
Interest & unsetApplicationParameters()
Remove the ApplicationParameters element from this Interest.
a concept check for TLV abstraction with .wireEncode method
time::milliseconds getFreshnessPeriod() const
Represents a Data packet.
a concept check for TLV abstraction with .wireDecode method and constructible from Block ...
Interest & setApplicationParameters(const Block &block)
Set ApplicationParameters from a Block.
EncodingImpl< EncoderTag > EncodingBuffer
const nullopt_t nullopt((nullopt_t::init()))
represents an error in TLV encoding or decoding
EncodingImpl< EstimatorTag > EncodingEstimator
bool isSigned() const noexcept
Return whether the Interest is signed.
static auto generateNonce()
shared_ptr< const Buffer > ConstBufferPtr
boost::chrono::milliseconds milliseconds
Interest & setName(const Name &name)
Set the Interest's name.