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