ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
interest.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2024 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "ndn-cxx/interest.hpp"
23#include "ndn-cxx/data.hpp"
29
30#include <boost/range/adaptor/reversed.hpp>
31
32#include <algorithm>
33#include <cstring>
34#include <sstream>
35
36namespace ndn {
37
39{
40 setName(name);
41 setInterestLifetime(lifetime);
42}
43
45{
46 wireDecode(wire);
47}
48
49// ---- encode and decode ----
50
51template<encoding::Tag TAG>
52size_t
54{
55 // Interest = INTEREST-TYPE TLV-LENGTH
56 // Name
57 // [CanBePrefix]
58 // [MustBeFresh]
59 // [ForwardingHint]
60 // [Nonce]
61 // [InterestLifetime]
62 // [HopLimit]
63 // [ApplicationParameters [InterestSignature]]
64 // (elements are encoded in reverse order)
65
66 // sanity check of ApplicationParameters and ParametersSha256DigestComponent
67 ssize_t digestIndex = findParametersDigestComponent(getName());
68 BOOST_ASSERT(digestIndex != -2); // guaranteed by the checks in setName() and wireDecode()
69 if (digestIndex == -1) {
71 NDN_THROW(Error("Interest with parameters must have a ParametersSha256DigestComponent"));
72 }
73 else if (!hasApplicationParameters()) {
74 NDN_THROW(Error("Interest without parameters must not have a ParametersSha256DigestComponent"));
75 }
76
77 size_t totalLength = 0;
78
79 // ApplicationParameters and following elements (in reverse order)
80 for (const auto& block : m_parameters | boost::adaptors::reversed) {
81 totalLength += prependBlock(encoder, block);
82 }
83
84 // HopLimit
85 if (m_hopLimit) {
86 totalLength += prependBinaryBlock(encoder, tlv::HopLimit, {*m_hopLimit});
87 }
88
89 // InterestLifetime
90 if (m_interestLifetime != DEFAULT_INTEREST_LIFETIME.count()) {
91 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::InterestLifetime, m_interestLifetime);
92 }
93
94 // Nonce
95 getNonce(); // if nonce was unset, this generates a fresh nonce
96 BOOST_ASSERT(hasNonce());
97 totalLength += prependBinaryBlock(encoder, tlv::Nonce, *m_nonce);
98
99 // ForwardingHint
100 if (!m_forwardingHint.empty()) {
101 totalLength += prependNestedBlock(encoder, tlv::ForwardingHint,
102 m_forwardingHint.begin(), m_forwardingHint.end());
103 }
104
105 // MustBeFresh
106 if (getMustBeFresh()) {
107 totalLength += prependEmptyBlock(encoder, tlv::MustBeFresh);
108 }
109
110 // CanBePrefix
111 if (getCanBePrefix()) {
112 totalLength += prependEmptyBlock(encoder, tlv::CanBePrefix);
113 }
114
115 // Name
116 totalLength += getName().wireEncode(encoder);
117
118 totalLength += encoder.prependVarNumber(totalLength);
119 totalLength += encoder.prependVarNumber(tlv::Interest);
120 return totalLength;
121}
122
124
125const Block&
127{
128 if (m_wire.hasWire())
129 return m_wire;
130
131 EncodingEstimator estimator;
132 size_t estimatedSize = wireEncode(estimator);
133
134 EncodingBuffer encoder(estimatedSize, 0);
135 wireEncode(encoder);
136
137 const_cast<Interest*>(this)->wireDecode(encoder.block());
138 return m_wire;
139}
140
141void
143{
144 if (wire.type() != tlv::Interest) {
145 NDN_THROW(Error("Interest", wire.type()));
146 }
147 m_wire = wire;
148 m_wire.parse();
149
150 // Interest = INTEREST-TYPE TLV-LENGTH
151 // Name
152 // [CanBePrefix]
153 // [MustBeFresh]
154 // [ForwardingHint]
155 // [Nonce]
156 // [InterestLifetime]
157 // [HopLimit]
158 // [ApplicationParameters [InterestSignature]]
159
160 auto element = m_wire.elements_begin();
161 if (element == m_wire.elements_end() || element->type() != tlv::Name) {
162 NDN_THROW(Error("Name element is missing or out of order"));
163 }
164 // decode into a temporary object until we determine that the name is valid, in order
165 // to maintain class invariants and thus provide a basic form of exception safety
166 Name tempName(*element);
167 if (tempName.empty()) {
168 NDN_THROW(Error("Name has zero name components"));
169 }
170 ssize_t digestIndex = findParametersDigestComponent(tempName);
171 if (digestIndex == -2) {
172 NDN_THROW(Error("Name has more than one ParametersSha256DigestComponent"));
173 }
174 m_name = std::move(tempName);
175
176 m_canBePrefix = m_mustBeFresh = false;
177 m_forwardingHint.clear();
178 m_nonce.reset();
179 m_interestLifetime = DEFAULT_INTEREST_LIFETIME.count();
180 m_hopLimit.reset();
181 m_parameters.clear();
182
183 int lastElement = 1; // last recognized element index, in spec order
184 for (++element; element != m_wire.elements_end(); ++element) {
185 switch (element->type()) {
186 case tlv::CanBePrefix: {
187 if (lastElement >= 2) {
188 NDN_THROW(Error("CanBePrefix element is out of order"));
189 }
190 if (element->value_size() != 0) {
191 NDN_THROW(Error("CanBePrefix element has non-zero TLV-LENGTH"));
192 }
193 m_canBePrefix = true;
194 lastElement = 2;
195 break;
196 }
197 case tlv::MustBeFresh: {
198 if (lastElement >= 3) {
199 NDN_THROW(Error("MustBeFresh element is out of order"));
200 }
201 if (element->value_size() != 0) {
202 NDN_THROW(Error("MustBeFresh element has non-zero TLV-LENGTH"));
203 }
204 m_mustBeFresh = true;
205 lastElement = 3;
206 break;
207 }
208 case tlv::ForwardingHint: {
209 if (lastElement >= 4) {
210 NDN_THROW(Error("ForwardingHint element is out of order"));
211 }
212 // Current format:
213 // ForwardingHint = FORWARDING-HINT-TYPE TLV-LENGTH 1*Name
214 // Previous format, partially supported for backward compatibility:
215 // ForwardingHint = FORWARDING-HINT-TYPE TLV-LENGTH 1*Delegation
216 // Delegation = DELEGATION-TYPE TLV-LENGTH Preference Name
217 element->parse();
218 for (const auto& del : element->elements()) {
219 switch (del.type()) {
220 case tlv::Name:
221 try {
222 m_forwardingHint.emplace_back(del);
223 }
224 catch (const tlv::Error&) {
225 NDN_THROW_NESTED(Error("Invalid Name in ForwardingHint"));
226 }
227 break;
228 case 31: // Delegation
229 // old ForwardingHint format, try to parse the nested Name for compatibility
230 try {
231 del.parse();
232 m_forwardingHint.emplace_back(del.get(tlv::Name));
233 }
234 catch (const tlv::Error&) {
235 NDN_THROW_NESTED(Error("Invalid Name in ForwardingHint.Delegation"));
236 }
237 break;
238 default:
239 if (tlv::isCriticalType(del.type())) {
240 NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(del.type()) + " while decoding ForwardingHint"));
241 }
242 break;
243 }
244 }
245 lastElement = 4;
246 break;
247 }
248 case tlv::Nonce: {
249 if (lastElement >= 5) {
250 NDN_THROW(Error("Nonce element is out of order"));
251 }
252 if (element->value_size() != Nonce().size()) {
253 NDN_THROW(Error("Nonce element is malformed"));
254 }
255 m_nonce.emplace();
256 std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
257 lastElement = 5;
258 break;
259 }
261 if (lastElement >= 6) {
262 NDN_THROW(Error("InterestLifetime element is out of order"));
263 }
264 m_interestLifetime = readNonNegativeInteger(*element);
265 lastElement = 6;
266 break;
267 }
268 case tlv::HopLimit: {
269 if (lastElement >= 7) {
270 break; // HopLimit is non-critical, ignore out-of-order appearance
271 }
272 if (element->value_size() != 1) {
273 NDN_THROW(Error("HopLimit element is malformed"));
274 }
275 m_hopLimit = *element->value();
276 lastElement = 7;
277 break;
278 }
280 if (lastElement >= 8) {
281 break; // ApplicationParameters is non-critical, ignore out-of-order appearance
282 }
283 BOOST_ASSERT(!hasApplicationParameters());
284 m_parameters.push_back(*element);
285 lastElement = 8;
286 break;
287 }
288 default: { // unrecognized element
289 // if the TLV-TYPE is critical, abort decoding
290 if (tlv::isCriticalType(element->type())) {
291 NDN_THROW(Error("Unrecognized element of critical type " + to_string(element->type())));
292 }
293 // if we already encountered ApplicationParameters, store this element as parameter
295 m_parameters.push_back(*element);
296 }
297 // otherwise, ignore it
298 break;
299 }
300 }
301 }
302
303 if (s_autoCheckParametersDigest && !isParametersDigestValid()) {
304 NDN_THROW(Error("ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
305 }
306}
307
308std::string
310{
311 std::ostringstream os;
312 os << *this;
313 return os.str();
314}
315
316// ---- matching ----
317
318bool
319Interest::matchesData(const Data& data) const
320{
321 const Name& dataName = data.getName();
322 size_t fullNameLength = dataName.size() + 1;
323
324 // check Name and CanBePrefix
325 if (m_name.size() == fullNameLength) {
326 if (m_name.get(-1).isImplicitSha256Digest()) {
327 return m_name == data.getFullName();
328 }
329 else {
330 // the Interest name has the same length as the Data full name, but the last
331 // component is not a digest, so there is no possibility of matching
332 return false;
333 }
334 }
335 else if (m_canBePrefix) {
336 return m_name.isPrefixOf(dataName);
337 }
338 else {
339 return m_name == dataName;
340 }
341}
342
343bool
345{
346 return getName() == other.getName() &&
347 getCanBePrefix() == other.getCanBePrefix() &&
348 getMustBeFresh() == other.getMustBeFresh();
349}
350
351// ---- field accessors and modifiers ----
352
355{
356 ssize_t digestIndex = findParametersDigestComponent(name);
357 if (digestIndex == -2) {
358 NDN_THROW(std::invalid_argument("Name cannot have more than one ParametersSha256DigestComponent"));
359 }
360
361 if (name != m_name) {
362 m_name = name;
364 addOrReplaceParametersDigestComponent();
365 }
366 m_wire.reset();
367 }
368 return *this;
369}
370
373{
374 if (canBePrefix != m_canBePrefix) {
375 m_canBePrefix = canBePrefix;
376 m_wire.reset();
377 }
378 return *this;
379}
380
383{
384 if (mustBeFresh != m_mustBeFresh) {
385 m_mustBeFresh = mustBeFresh;
386 m_wire.reset();
387 }
388 return *this;
389}
390
392Interest::setForwardingHint(std::vector<Name> value)
393{
394 m_forwardingHint = std::move(value);
395 m_wire.reset();
396 return *this;
397}
398
399[[nodiscard]] static auto
400generateNonce()
401{
402 uint32_t r = random::generateWord32();
404 std::memcpy(n.data(), &r, sizeof(r));
405 return n;
406}
407
408Interest::Nonce
410{
411 if (!hasNonce()) {
412 m_nonce = generateNonce();
413 m_wire.reset();
414 }
415 return *m_nonce;
416}
417
419Interest::setNonce(std::optional<Interest::Nonce> nonce)
420{
421 if (nonce != m_nonce) {
422 m_nonce = nonce;
423 m_wire.reset();
424 }
425 return *this;
426}
427
428void
430{
431 if (!hasNonce())
432 return;
433
434 auto oldNonce = *m_nonce;
435 while (m_nonce == oldNonce)
436 m_nonce = generateNonce();
437
438 m_wire.reset();
439}
440
443{
444 if (m_interestLifetime > static_cast<uint64_t>(time::milliseconds::max().count())) {
445 return time::milliseconds::max();
446 }
447 return time::milliseconds(m_interestLifetime);
448}
449
452{
453 if (lifetime < 0_ms) {
454 NDN_THROW(std::invalid_argument("InterestLifetime must be >= 0"));
455 }
456
457 uint64_t lifetimeMillis = static_cast<uint64_t>(lifetime.count());
458 if (lifetimeMillis != m_interestLifetime) {
459 m_interestLifetime = lifetimeMillis;
460 m_wire.reset();
461 }
462 return *this;
463}
464
466Interest::setHopLimit(std::optional<uint8_t> hopLimit)
467{
468 if (hopLimit != m_hopLimit) {
469 m_hopLimit = hopLimit;
470 m_wire.reset();
471 }
472 return *this;
473}
474
476Interest::setApplicationParametersInternal(Block parameters)
477{
478 parameters.encode(); // ensure we have wire encoding needed by computeParametersDigest()
479 if (m_parameters.empty()) {
480 m_parameters.push_back(std::move(parameters));
481 }
482 else {
483 BOOST_ASSERT(m_parameters[0].type() == tlv::ApplicationParameters);
484 m_parameters[0] = std::move(parameters);
485 }
486
487 addOrReplaceParametersDigestComponent();
488 m_wire.reset();
489 return *this;
490}
491
494{
495 if (!parameters.isValid()) {
496 NDN_THROW(std::invalid_argument("ApplicationParameters block must be valid"));
497 }
498
499 if (parameters.type() == tlv::ApplicationParameters) {
500 return setApplicationParametersInternal(parameters);
501 }
502 else {
503 return setApplicationParametersInternal({tlv::ApplicationParameters, parameters});
504 }
505}
506
508Interest::setApplicationParameters(span<const uint8_t> value)
509{
510 return setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value));
511}
512
515{
516 return setApplicationParametersInternal(makeStringBlock(tlv::ApplicationParameters, value));
517}
518
521{
522 if (!value) {
523 NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be null"));
524 }
525
526 return setApplicationParametersInternal({tlv::ApplicationParameters, std::move(value)});
527}
528
531{
532 m_parameters.clear();
533 ssize_t digestIndex = findParametersDigestComponent(getName());
534 if (digestIndex >= 0) {
535 m_name.erase(digestIndex);
536 }
537 m_wire.reset();
538 return *this;
539}
540
541bool
542Interest::isSigned() const noexcept
543{
544 return m_parameters.size() >= 3 &&
545 getSignatureInfo().has_value() &&
547 !m_name.empty() &&
548 m_name[-1].type() == tlv::ParametersSha256DigestComponent;
549}
550
551std::optional<SignatureInfo>
553{
554 auto blockIt = findFirstParameter(tlv::InterestSignatureInfo);
555 if (blockIt != m_parameters.end()) {
556 return std::make_optional<SignatureInfo>(*blockIt, SignatureInfo::Type::Interest);
557 }
558 return std::nullopt;
559}
560
563{
564 // Prepend empty ApplicationParameters element if none present
565 if (m_parameters.empty()) {
566 m_parameters.push_back(makeEmptyBlock(tlv::ApplicationParameters));
567 }
568
569 // Find first existing InterestSignatureInfo (if any)
570 auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (const Block& block) {
571 return block.type() == tlv::InterestSignatureInfo;
572 });
573
574 Block encodedInfo = info.wireEncode(SignatureInfo::Type::Interest);
575 if (infoIt != m_parameters.end()) {
576 if (*infoIt == encodedInfo) {
577 // New InterestSignatureInfo is the same as the old InterestSignatureInfo
578 return *this;
579 }
580
581 // Replace existing InterestSignatureInfo
582 *infoIt = std::move(encodedInfo);
583 }
584 else {
585 // Place before first InterestSignatureValue element (if any), else at end
586 auto valueIt = findFirstParameter(tlv::InterestSignatureValue);
587 m_parameters.insert(valueIt, std::move(encodedInfo));
588 }
589
590 addOrReplaceParametersDigestComponent();
591 m_wire.reset();
592 return *this;
593}
594
595Block
597{
598 auto blockIt = findFirstParameter(tlv::InterestSignatureValue);
599 if (blockIt != m_parameters.end()) {
600 return *blockIt;
601 }
602 return {};
603}
604
606Interest::setSignatureValueInternal(Block sigValue)
607{
608 // Ensure presence of InterestSignatureInfo
609 auto infoIt = findFirstParameter(tlv::InterestSignatureInfo);
610 if (infoIt == m_parameters.end()) {
611 NDN_THROW(Error("InterestSignatureInfo must be present to set InterestSignatureValue"));
612 }
613
614 auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (const Block& block) {
615 return block.type() == tlv::InterestSignatureValue;
616 });
617
618 if (valueIt != m_parameters.end()) {
619 if (*valueIt == sigValue) {
620 // New InterestSignatureValue is the same as the old InterestSignatureValue
621 return *this;
622 }
623
624 // Replace existing InterestSignatureValue
625 *valueIt = std::move(sigValue);
626 }
627 else {
628 // Place after first InterestSignatureInfo element
629 valueIt = m_parameters.insert(std::next(infoIt), std::move(sigValue));
630 }
631
632 // computeParametersDigest needs encoded InterestSignatureValue
633 valueIt->encode();
634
635 addOrReplaceParametersDigestComponent();
636 m_wire.reset();
637 return *this;
638}
639
641Interest::setSignatureValue(span<const uint8_t> value)
642{
643 return setSignatureValueInternal(makeBinaryBlock(tlv::InterestSignatureValue, value));
644}
645
648{
649 if (!value) {
650 NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be null"));
651 }
652
653 return setSignatureValueInternal({tlv::InterestSignatureValue, std::move(value)});
654}
655
656InputBuffers
658{
659 InputBuffers bufs;
660 bufs.reserve(2); // For Name range and parameters range
661
662 wireEncode();
663
664 // Get Interest name minus any ParametersSha256DigestComponent
665 // Name is guaranteed to be non-empty if wireEncode() does not throw
666 BOOST_ASSERT(!m_name.empty());
667 if (m_name[-1].type() != tlv::ParametersSha256DigestComponent) {
668 NDN_THROW(Error("Interest Name must end with a ParametersSha256DigestComponent"));
669 }
670
671 bufs.emplace_back(m_name[0].data(), m_name[-1].data());
672
673 // Ensure InterestSignatureInfo element is present
674 auto sigInfoIt = findFirstParameter(tlv::InterestSignatureInfo);
675 if (sigInfoIt == m_parameters.end()) {
676 NDN_THROW(Error("Interest missing InterestSignatureInfo"));
677 }
678
679 // Get range from ApplicationParameters to InterestSignatureValue
680 // or end of parameters (whichever is first)
681 BOOST_ASSERT(!m_parameters.empty() && m_parameters.begin()->type() == tlv::ApplicationParameters);
682 auto lastSignedIt = std::prev(findFirstParameter(tlv::InterestSignatureValue));
683 // Note: we assume that both iterators point to the same underlying buffer
684 bufs.emplace_back(m_parameters.front().begin(), lastSignedIt->end());
685
686 return bufs;
687}
688
689// ---- ParametersSha256DigestComponent support ----
690
691bool
693{
694 ssize_t digestIndex = findParametersDigestComponent(getName());
695 if (digestIndex == -1) {
696 return !hasApplicationParameters();
697 }
698 // cannot be -2 because of the checks in setName() and wireDecode()
699 BOOST_ASSERT(digestIndex >= 0);
700
702 return false;
703 }
704
705 const auto& digestComponent = getName()[digestIndex];
706 auto digest = computeParametersDigest();
707
708 return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
709 digest->begin(), digest->end());
710}
711
712shared_ptr<Buffer>
713Interest::computeParametersDigest() const
714{
715 using namespace security::transform;
716
717 StepSource in;
718 OBufferStream out;
719 in >> digestFilter(DigestAlgorithm::SHA256) >> streamSink(out);
720
721 for (const auto& block : m_parameters) {
722 in.write(block);
723 }
724 in.end();
725
726 return out.buf();
727}
728
729void
730Interest::addOrReplaceParametersDigestComponent()
731{
732 BOOST_ASSERT(hasApplicationParameters());
733
734 ssize_t digestIndex = findParametersDigestComponent(getName());
735 name::Component digestComponent(tlv::ParametersSha256DigestComponent, computeParametersDigest());
736
737 if (digestIndex == -1) {
738 // no existing digest components, append one
739 m_name.append(std::move(digestComponent));
740 }
741 else {
742 // cannot be -2 because of the checks in setName() and wireDecode()
743 BOOST_ASSERT(digestIndex >= 0);
744 // replace the existing digest component
745 m_name.set(digestIndex, std::move(digestComponent));
746 }
747}
748
749ssize_t
750Interest::findParametersDigestComponent(const Name& name)
751{
752 ssize_t pos = -1;
753 for (ssize_t i = 0; i < static_cast<ssize_t>(name.size()); i++) {
754 if (name[i].isParametersSha256Digest()) {
755 if (pos != -1)
756 return -2;
757 pos = i;
758 }
759 }
760 return pos;
761}
762
763std::vector<Block>::const_iterator
764Interest::findFirstParameter(uint32_t type) const
765{
766 return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (const Block& block) {
767 return block.type() == type;
768 });
769}
770
771// ---- operators ----
772
773std::ostream&
774operator<<(std::ostream& os, const Interest& interest)
775{
776 os << interest.getName();
777
778 char delim = '?';
779 auto printOne = [&] (const auto&... args) {
780 os << delim;
781 delim = '&';
782 (os << ... << args);
783 };
784
785 if (interest.getCanBePrefix()) {
786 printOne("CanBePrefix");
787 }
788 if (interest.getMustBeFresh()) {
789 printOne("MustBeFresh");
790 }
791 if (interest.hasNonce()) {
792 printOne("Nonce=", interest.getNonce());
793 }
795 printOne("Lifetime=", interest.getInterestLifetime().count());
796 }
797 if (interest.getHopLimit()) {
798 printOne("HopLimit=", static_cast<unsigned>(*interest.getHopLimit()));
799 }
800
801 return os;
802}
803
804} // namespace ndn
Represents a TLV element of the NDN packet format.
Definition block.hpp:45
element_const_iterator elements_begin() const noexcept
Equivalent to elements().begin().
Definition block.hpp:433
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
Definition block.hpp:442
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition block.hpp:205
bool isValid() const noexcept
Check if the Block is valid.
Definition block.hpp:193
void encode()
Encode sub-elements into TLV-VALUE.
Definition block.cpp:353
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition block.hpp:275
void reset() noexcept
Reset the Block to a default-constructed state.
Definition block.cpp:293
void parse() const
Parse TLV-VALUE into sub-elements.
Definition block.cpp:326
Represents a Data packet.
Definition data.hpp:39
const Name & getName() const noexcept
Get the Data name.
Definition data.hpp:137
const Name & getFullName() const
Get the full name (including implicit digest).
Definition data.cpp:200
Represents an Interest packet.
Definition interest.hpp:50
void wireDecode(const Block &wire)
Decode from wire.
Definition interest.cpp:142
std::optional< uint8_t > getHopLimit() const noexcept
Get the Interest's hop limit.
Definition interest.hpp:295
Interest & setHopLimit(std::optional< uint8_t > hopLimit)
Set the Interest's hop limit.
Definition interest.cpp:466
std::optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo element.
Definition interest.cpp:552
Interest & setCanBePrefix(bool canBePrefix)
Add or remove CanBePrefix element.
Definition interest.cpp:372
Interest & setNonce(std::optional< Nonce > nonce)
Set the Interest's nonce.
Definition interest.cpp:419
Nonce getNonce() const
Get nonce value.
Definition interest.cpp:409
Interest & setSignatureValue(span< const uint8_t > value)
Set InterestSignatureValue by copying from a contiguous sequence of bytes.
Definition interest.cpp:641
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
Definition interest.cpp:344
bool hasApplicationParameters() const noexcept
Return whether this Interest has any ApplicationParameters element.
Definition interest.hpp:312
time::milliseconds getInterestLifetime() const noexcept
Get the Interest's lifetime.
Definition interest.cpp:442
bool matchesData(const Data &data) const
Check if this Interest can be satisfied by data.
Definition interest.cpp:319
Interest & setMustBeFresh(bool mustBeFresh)
Add or remove MustBeFresh element.
Definition interest.cpp:382
bool getMustBeFresh() const noexcept
Check whether the MustBeFresh element is present.
Definition interest.hpp:211
Block getSignatureValue() const
Get the InterestSignatureValue element.
Definition interest.cpp:596
InputBuffers extractSignedRanges() const
Extract ranges of Interest covered by the signature.
Definition interest.cpp:657
bool hasNonce() const noexcept
Check if the Nonce element is present.
Definition interest.hpp:244
bool getCanBePrefix() const noexcept
Check whether the CanBePrefix element is present.
Definition interest.hpp:195
void refreshNonce()
Change nonce value.
Definition interest.cpp:429
bool isSigned() const noexcept
Return whether the Interest is signed.
Definition interest.cpp:542
Interest & unsetApplicationParameters()
Remove the ApplicationParameters element from this Interest.
Definition interest.cpp:530
const Name & getName() const noexcept
Get the Interest name.
Definition interest.hpp:179
bool isParametersDigestValid() const
Check if the ParametersSha256DigestComponent in the name is valid.
Definition interest.cpp:692
Interest & setName(const Name &name)
Set the Interest name.
Definition interest.cpp:354
Interest & setSignatureInfo(const SignatureInfo &info)
Set the InterestSignatureInfo element.
Definition interest.cpp:562
Interest & setApplicationParameters(const Block &block)
Set ApplicationParameters from a Block.
Definition interest.cpp:493
Interest & setForwardingHint(std::vector< Name > value)
Set the ForwardingHint delegations (names).
Definition interest.cpp:392
std::string toUri() const
Return a URI-like string that represents the Interest.
Definition interest.cpp:309
const Block & wireEncode() const
Encode into a Block.
Definition interest.cpp:126
Interest(const Name &name={}, time::milliseconds lifetime=DEFAULT_INTEREST_LIFETIME)
Construct an Interest with given name and lifetime.
Definition interest.cpp:38
Interest & setInterestLifetime(time::milliseconds lifetime)
Set the Interest's lifetime.
Definition interest.cpp:451
Represents an absolute name.
Definition name.hpp:45
const Component & get(ssize_t i) const noexcept
Returns an immutable reference to the component at the specified index.
Definition name.hpp:192
Name & set(ssize_t i, const Component &component)
Replace the component at the specified index.
Definition name.cpp:181
Name & append(const Component &component)
Append a name component.
Definition name.hpp:308
size_t size() const noexcept
Returns the number of components.
Definition name.hpp:180
bool empty() const noexcept
Checks if the name is empty, i.e., has no components.
Definition name.hpp:171
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Prepend wire encoding to encoder.
Definition name.cpp:92
void erase(ssize_t i)
Erase the component at the specified index.
Definition name.cpp:245
bool isPrefixOf(const Name &other) const noexcept
Check if this name is a prefix of another name.
Definition name.cpp:275
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.
Definition tlv.hpp:54
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW_NESTED(e)
Definition exception.hpp:65
#define NDN_THROW(e)
Definition exception.hpp:56
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32).
Definition random.cpp:68
::boost::chrono::milliseconds milliseconds
Definition time.hpp:52
@ Name
Definition tlv.hpp:71
@ InterestLifetime
Definition tlv.hpp:86
@ HopLimit
Definition tlv.hpp:87
@ InterestSignatureInfo
Definition tlv.hpp:89
@ ApplicationParameters
Definition tlv.hpp:88
@ ForwardingHint
Definition tlv.hpp:84
@ InterestSignatureValue
Definition tlv.hpp:90
@ CanBePrefix
Definition tlv.hpp:82
@ ParametersSha256DigestComponent
Definition tlv.hpp:74
@ Interest
Definition tlv.hpp:68
@ MustBeFresh
Definition tlv.hpp:83
@ Nonce
Definition tlv.hpp:85
constexpr bool isCriticalType(uint32_t type) noexcept
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
Definition tlv.hpp:162
Definition data.cpp:25
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition data.cpp:377
constexpr time::milliseconds DEFAULT_INTEREST_LIFETIME
Default value of InterestLifetime.
Definition interest.hpp:43
std::shared_ptr< const Buffer > ConstBufferPtr
Definition buffer.hpp:140
InputBuffers bufs
SignatureInfo info