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>));
38 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
39 BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
40 static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
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  // Current format:
221  // ForwardingHint = FORWARDING-HINT-TYPE TLV-LENGTH 1*Name
222  // Previous format, partially supported for backward compatibility:
223  // ForwardingHint = FORWARDING-HINT-TYPE TLV-LENGTH 1*Delegation
224  // Delegation = DELEGATION-TYPE TLV-LENGTH Preference Name
225  element->parse();
226  for (const auto& del : element->elements()) {
227  switch (del.type()) {
228  case tlv::Name:
229  try {
230  m_forwardingHint.emplace_back(del);
231  }
232  catch (const tlv::Error&) {
233  NDN_THROW_NESTED(Error("Invalid Name in ForwardingHint"));
234  }
235  break;
236  case 31: // Delegation
237  // old ForwardingHint format, try to parse the nested Name for compatibility
238  try {
239  del.parse();
240  m_forwardingHint.emplace_back(del.get(tlv::Name));
241  }
242  catch (const tlv::Error&) {
243  NDN_THROW_NESTED(Error("Invalid Name in ForwardingHint.Delegation"));
244  }
245  break;
246  default:
247  if (tlv::isCriticalType(del.type())) {
248  NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(del.type()) + " while decoding ForwardingHint"));
249  }
250  break;
251  }
252  }
253  lastElement = 4;
254  break;
255  }
256  case tlv::Nonce: {
257  if (lastElement >= 5) {
258  NDN_THROW(Error("Nonce element is out of order"));
259  }
260  if (element->value_size() != Nonce().size()) {
261  NDN_THROW(Error("Nonce element is malformed"));
262  }
263  m_nonce.emplace();
264  std::memcpy(m_nonce->data(), element->value(), m_nonce->size());
265  lastElement = 5;
266  break;
267  }
268  case tlv::InterestLifetime: {
269  if (lastElement >= 6) {
270  NDN_THROW(Error("InterestLifetime element is out of order"));
271  }
272  m_interestLifetime = time::milliseconds(readNonNegativeInteger(*element));
273  lastElement = 6;
274  break;
275  }
276  case tlv::HopLimit: {
277  if (lastElement >= 7) {
278  break; // HopLimit is non-critical, ignore out-of-order appearance
279  }
280  if (element->value_size() != 1) {
281  NDN_THROW(Error("HopLimit element is malformed"));
282  }
283  m_hopLimit = *element->value();
284  lastElement = 7;
285  break;
286  }
288  if (lastElement >= 8) {
289  break; // ApplicationParameters is non-critical, ignore out-of-order appearance
290  }
291  BOOST_ASSERT(!hasApplicationParameters());
292  m_parameters.push_back(*element);
293  lastElement = 8;
294  break;
295  }
296  default: { // unrecognized element
297  // if the TLV-TYPE is critical, abort decoding
298  if (tlv::isCriticalType(element->type())) {
299  NDN_THROW(Error("Unrecognized element of critical type " + to_string(element->type())));
300  }
301  // if we already encountered ApplicationParameters, store this element as parameter
302  if (hasApplicationParameters()) {
303  m_parameters.push_back(*element);
304  }
305  // otherwise, ignore it
306  break;
307  }
308  }
309  }
310 
311  if (s_autoCheckParametersDigest && !isParametersDigestValid()) {
312  NDN_THROW(Error("ParametersSha256DigestComponent does not match the SHA-256 of Interest parameters"));
313  }
314 }
315 
316 std::string
318 {
319  std::ostringstream os;
320  os << *this;
321  return os.str();
322 }
323 
324 // ---- matching ----
325 
326 bool
327 Interest::matchesData(const Data& data) const
328 {
329  size_t interestNameLength = m_name.size();
330  const Name& dataName = data.getName();
331  size_t fullNameLength = dataName.size() + 1;
332 
333  // check Name and CanBePrefix
334  if (interestNameLength == fullNameLength) {
335  if (m_name.get(-1).isImplicitSha256Digest()) {
336  if (m_name != data.getFullName()) {
337  return false;
338  }
339  }
340  else {
341  // Interest Name is same length as Data full Name, but last component isn't digest
342  // so there's no possibility of matching
343  return false;
344  }
345  }
346  else if (getCanBePrefix() ? !m_name.isPrefixOf(dataName) : (m_name != dataName)) {
347  return false;
348  }
349 
350  // check MustBeFresh
351  if (getMustBeFresh() && data.getFreshnessPeriod() <= 0_ms) {
352  return false;
353  }
354 
355  return true;
356 }
357 
358 bool
360 {
361  return getName() == other.getName() &&
362  getCanBePrefix() == other.getCanBePrefix() &&
363  getMustBeFresh() == other.getMustBeFresh();
364 }
365 
366 // ---- field accessors and modifiers ----
367 
368 Interest&
370 {
371  ssize_t digestIndex = findParametersDigestComponent(name);
372  if (digestIndex == -2) {
373  NDN_THROW(std::invalid_argument("Name cannot have more than one ParametersSha256DigestComponent"));
374  }
375 
376  if (name != m_name) {
377  m_name = name;
378  if (hasApplicationParameters()) {
379  addOrReplaceParametersDigestComponent();
380  }
381  m_wire.reset();
382  }
383  return *this;
384 }
385 
386 Interest&
387 Interest::setForwardingHint(std::vector<Name> value)
388 {
389  m_forwardingHint = std::move(value);
390  m_wire.reset();
391  return *this;
392 }
393 
394 static auto
395 generateNonce()
396 {
397  uint32_t r = random::generateWord32();
398  Interest::Nonce n;
399  std::memcpy(n.data(), &r, sizeof(r));
400  return n;
401 }
402 
405 {
406  if (!hasNonce()) {
407  m_nonce = generateNonce();
408  m_wire.reset();
409  }
410  return *m_nonce;
411 }
412 
413 Interest&
414 Interest::setNonce(optional<Interest::Nonce> nonce)
415 {
416  if (nonce != m_nonce) {
417  m_nonce = nonce;
418  m_wire.reset();
419  }
420  return *this;
421 }
422 
423 void
425 {
426  if (!hasNonce())
427  return;
428 
429  auto oldNonce = *m_nonce;
430  while (m_nonce == oldNonce)
431  m_nonce = generateNonce();
432 
433  m_wire.reset();
434 }
435 
436 Interest&
438 {
439  if (lifetime < 0_ms) {
440  NDN_THROW(std::invalid_argument("InterestLifetime must be >= 0"));
441  }
442 
443  if (lifetime != m_interestLifetime) {
444  m_interestLifetime = lifetime;
445  m_wire.reset();
446  }
447  return *this;
448 }
449 
450 Interest&
451 Interest::setHopLimit(optional<uint8_t> hopLimit)
452 {
453  if (hopLimit != m_hopLimit) {
454  m_hopLimit = hopLimit;
455  m_wire.reset();
456  }
457  return *this;
458 }
459 
460 Interest&
461 Interest::setApplicationParametersInternal(Block parameters)
462 {
463  parameters.encode(); // ensure we have wire encoding needed by computeParametersDigest()
464  if (m_parameters.empty()) {
465  m_parameters.push_back(std::move(parameters));
466  }
467  else {
468  BOOST_ASSERT(m_parameters[0].type() == tlv::ApplicationParameters);
469  m_parameters[0] = std::move(parameters);
470  }
471 
472  addOrReplaceParametersDigestComponent();
473  m_wire.reset();
474  return *this;
475 }
476 
477 Interest&
479 {
480  if (!parameters.isValid()) {
481  NDN_THROW(std::invalid_argument("ApplicationParameters block must be valid"));
482  }
483 
484  if (parameters.type() == tlv::ApplicationParameters) {
485  return setApplicationParametersInternal(parameters);
486  }
487  else {
488  return setApplicationParametersInternal({tlv::ApplicationParameters, parameters});
489  }
490 }
491 
492 Interest&
493 Interest::setApplicationParameters(span<const uint8_t> value)
494 {
495  return setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value));
496 }
497 
498 Interest&
500 {
501  if (value == nullptr) {
502  NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be nullptr"));
503  }
504 
505  return setApplicationParametersInternal({tlv::ApplicationParameters, std::move(value)});
506 }
507 
508 Interest&
510 {
511  m_parameters.clear();
512  ssize_t digestIndex = findParametersDigestComponent(getName());
513  if (digestIndex >= 0) {
514  m_name.erase(digestIndex);
515  }
516  m_wire.reset();
517  return *this;
518 }
519 
520 bool
521 Interest::isSigned() const noexcept
522 {
523  return m_parameters.size() >= 3 &&
524  getSignatureInfo().has_value() &&
526  !m_name.empty() &&
527  m_name[-1].type() == tlv::ParametersSha256DigestComponent;
528 }
529 
530 optional<SignatureInfo>
532 {
533  auto blockIt = findFirstParameter(tlv::InterestSignatureInfo);
534  if (blockIt != m_parameters.end()) {
535  return make_optional<SignatureInfo>(*blockIt, SignatureInfo::Type::Interest);
536  }
537  return nullopt;
538 }
539 
540 Interest&
542 {
543  // Prepend empty ApplicationParameters element if none present
544  if (m_parameters.empty()) {
545  m_parameters.push_back(makeEmptyBlock(tlv::ApplicationParameters));
546  }
547 
548  // Find first existing InterestSignatureInfo (if any)
549  auto infoIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (const Block& block) {
550  return block.type() == tlv::InterestSignatureInfo;
551  });
552 
553  Block encodedInfo = info.wireEncode(SignatureInfo::Type::Interest);
554  if (infoIt != m_parameters.end()) {
555  if (*infoIt == encodedInfo) {
556  // New InterestSignatureInfo is the same as the old InterestSignatureInfo
557  return *this;
558  }
559 
560  // Replace existing InterestSignatureInfo
561  *infoIt = std::move(encodedInfo);
562  }
563  else {
564  // Place before first InterestSignatureValue element (if any), else at end
565  auto valueIt = findFirstParameter(tlv::InterestSignatureValue);
566  m_parameters.insert(valueIt, std::move(encodedInfo));
567  }
568 
569  addOrReplaceParametersDigestComponent();
570  m_wire.reset();
571  return *this;
572 }
573 
574 Block
576 {
577  auto blockIt = findFirstParameter(tlv::InterestSignatureValue);
578  if (blockIt != m_parameters.end()) {
579  return *blockIt;
580  }
581  return {};
582 }
583 
584 Interest&
585 Interest::setSignatureValueInternal(Block sigValue)
586 {
587  // Ensure presence of InterestSignatureInfo
588  auto infoIt = findFirstParameter(tlv::InterestSignatureInfo);
589  if (infoIt == m_parameters.end()) {
590  NDN_THROW(Error("InterestSignatureInfo must be present to set InterestSignatureValue"));
591  }
592 
593  auto valueIt = std::find_if(m_parameters.begin(), m_parameters.end(), [] (const Block& block) {
594  return block.type() == tlv::InterestSignatureValue;
595  });
596 
597  if (valueIt != m_parameters.end()) {
598  if (*valueIt == sigValue) {
599  // New InterestSignatureValue is the same as the old InterestSignatureValue
600  return *this;
601  }
602 
603  // Replace existing InterestSignatureValue
604  *valueIt = std::move(sigValue);
605  }
606  else {
607  // Place after first InterestSignatureInfo element
608  valueIt = m_parameters.insert(std::next(infoIt), std::move(sigValue));
609  }
610 
611  // computeParametersDigest needs encoded InterestSignatureValue
612  valueIt->encode();
613 
614  addOrReplaceParametersDigestComponent();
615  m_wire.reset();
616  return *this;
617 }
618 
619 Interest&
620 Interest::setSignatureValue(span<const uint8_t> value)
621 {
622  return setSignatureValueInternal(makeBinaryBlock(tlv::InterestSignatureValue, value));
623 }
624 
625 Interest&
627 {
628  if (value == nullptr) {
629  NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be nullptr"));
630  }
631 
632  return setSignatureValueInternal({tlv::InterestSignatureValue, std::move(value)});
633 }
634 
635 InputBuffers
637 {
638  InputBuffers bufs;
639  bufs.reserve(2); // For Name range and parameters range
640 
641  wireEncode();
642 
643  // Get Interest name minus any ParametersSha256DigestComponent
644  // Name is guaranteed to be non-empty if wireEncode() does not throw
645  BOOST_ASSERT(!m_name.empty());
646  if (m_name[-1].type() != tlv::ParametersSha256DigestComponent) {
647  NDN_THROW(Error("Interest Name must end with a ParametersSha256DigestComponent"));
648  }
649 
650  bufs.emplace_back(m_name[0].data(), m_name[-1].data());
651 
652  // Ensure InterestSignatureInfo element is present
653  auto sigInfoIt = findFirstParameter(tlv::InterestSignatureInfo);
654  if (sigInfoIt == m_parameters.end()) {
655  NDN_THROW(Error("Interest missing InterestSignatureInfo"));
656  }
657 
658  // Get range from ApplicationParameters to InterestSignatureValue
659  // or end of parameters (whichever is first)
660  BOOST_ASSERT(!m_parameters.empty() && m_parameters.begin()->type() == tlv::ApplicationParameters);
661  auto lastSignedIt = std::prev(findFirstParameter(tlv::InterestSignatureValue));
662  // Note: we assume that both iterators point to the same underlying buffer
663  bufs.emplace_back(m_parameters.front().begin(), lastSignedIt->end());
664 
665  return bufs;
666 }
667 
668 // ---- ParametersSha256DigestComponent support ----
669 
670 bool
672 {
673  ssize_t digestIndex = findParametersDigestComponent(getName());
674  if (digestIndex == -1) {
675  return !hasApplicationParameters();
676  }
677  // cannot be -2 because of the checks in setName() and wireDecode()
678  BOOST_ASSERT(digestIndex >= 0);
679 
680  if (!hasApplicationParameters()) {
681  return false;
682  }
683 
684  const auto& digestComponent = getName()[digestIndex];
685  auto digest = computeParametersDigest();
686 
687  return std::equal(digestComponent.value_begin(), digestComponent.value_end(),
688  digest->begin(), digest->end());
689 }
690 
691 shared_ptr<Buffer>
692 Interest::computeParametersDigest() const
693 {
694  using namespace security::transform;
695 
696  StepSource in;
697  OBufferStream out;
699 
700  for (const auto& block : m_parameters) {
701  in.write(block);
702  }
703  in.end();
704 
705  return out.buf();
706 }
707 
708 void
709 Interest::addOrReplaceParametersDigestComponent()
710 {
711  BOOST_ASSERT(hasApplicationParameters());
712 
713  ssize_t digestIndex = findParametersDigestComponent(getName());
714  name::Component digestComponent(tlv::ParametersSha256DigestComponent, computeParametersDigest());
715 
716  if (digestIndex == -1) {
717  // no existing digest components, append one
718  m_name.append(std::move(digestComponent));
719  }
720  else {
721  // cannot be -2 because of the checks in setName() and wireDecode()
722  BOOST_ASSERT(digestIndex >= 0);
723  // replace the existing digest component
724  m_name.set(digestIndex, std::move(digestComponent));
725  }
726 }
727 
728 ssize_t
729 Interest::findParametersDigestComponent(const Name& name)
730 {
731  ssize_t pos = -1;
732  for (ssize_t i = 0; i < static_cast<ssize_t>(name.size()); i++) {
733  if (name[i].isParametersSha256Digest()) {
734  if (pos != -1)
735  return -2;
736  pos = i;
737  }
738  }
739  return pos;
740 }
741 
742 std::vector<Block>::const_iterator
743 Interest::findFirstParameter(uint32_t type) const
744 {
745  return std::find_if(m_parameters.begin(), m_parameters.end(), [type] (const Block& block) {
746  return block.type() == type;
747  });
748 }
749 
750 // ---- operators ----
751 
752 std::ostream&
753 operator<<(std::ostream& os, const Interest& interest)
754 {
755  os << interest.getName();
756 
757  char delim = '?';
758  auto printOne = [&] (const auto&... args) {
759  os << delim;
760  delim = '&';
761  using expand = int[];
762  (void)expand{(os << args, 0)...}; // use a fold expression when we switch to C++17
763  };
764 
765  if (interest.getCanBePrefix()) {
766  printOne("CanBePrefix");
767  }
768  if (interest.getMustBeFresh()) {
769  printOne("MustBeFresh");
770  }
771  if (interest.hasNonce()) {
772  printOne("Nonce=", interest.getNonce());
773  }
775  printOne("Lifetime=", interest.getInterestLifetime().count());
776  }
777  if (interest.getHopLimit()) {
778  printOne("HopLimit=", static_cast<unsigned>(*interest.getHopLimit()));
779  }
780 
781  return os;
782 }
783 
784 } // 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:435
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
Definition: block.hpp:444
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:221
bool isValid() const noexcept
Check if the Block is valid.
Definition: block.hpp:192
void encode()
Encode sub-elements into TLV-VALUE.
Definition: block.cpp:351
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:277
void reset() noexcept
Reset the Block to a default-constructed state.
Definition: block.cpp:254
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:324
Represents a Data packet.
Definition: data.hpp:39
const Name & getFullName() const
Get full name including implicit digest.
Definition: data.cpp:207
const Name & getName() const noexcept
Get the data name.
Definition: data.hpp:129
time::milliseconds getFreshnessPeriod() const
Definition: data.hpp:294
Represents an Interest packet.
Definition: interest.hpp:50
void wireDecode(const Block &wire)
Decode from wire.
Definition: interest.cpp:150
const Name & getName() const noexcept
Definition: interest.hpp:173
Interest & setHopLimit(optional< uint8_t > hopLimit)
Set the Interest's hop limit.
Definition: interest.cpp:451
Nonce getNonce() const
Get nonce value.
Definition: interest.cpp:404
Interest & setSignatureValue(span< const uint8_t > value)
Set InterestSignatureValue by copying from a contiguous sequence of bytes.
Definition: interest.cpp:620
bool matchesInterest(const Interest &other) const
Check if this Interest matches other.
Definition: interest.cpp:359
bool hasApplicationParameters() const noexcept
Return whether this Interest has any ApplicationParameters element.
Definition: interest.hpp:307
time::milliseconds getInterestLifetime() const noexcept
Get the Interest's lifetime.
Definition: interest.hpp:274
bool matchesData(const Data &data) const
Check if Interest can be satisfied by data.
Definition: interest.cpp:327
bool getMustBeFresh() const noexcept
Check whether the MustBeFresh element is present.
Definition: interest.hpp:210
Block getSignatureValue() const
Get the InterestSignatureValue element.
Definition: interest.cpp:575
InputBuffers extractSignedRanges() const
Extract ranges of Interest covered by the signature in Packet Specification v0.3.
Definition: interest.cpp:636
bool hasNonce() const noexcept
Check if the Nonce element is present.
Definition: interest.hpp:240
bool getCanBePrefix() const noexcept
Check whether the CanBePrefix element is present.
Definition: interest.hpp:189
void refreshNonce()
Change nonce value.
Definition: interest.cpp:424
optional< uint8_t > getHopLimit() const noexcept
Get the Interest's hop limit.
Definition: interest.hpp:290
bool isSigned() const noexcept
Return whether the Interest is signed.
Definition: interest.cpp:521
optional< SignatureInfo > getSignatureInfo() const
Get the InterestSignatureInfo element.
Definition: interest.cpp:531
Interest & unsetApplicationParameters()
Remove the ApplicationParameters element from this Interest.
Definition: interest.cpp:509
bool isParametersDigestValid() const
Check if the ParametersSha256DigestComponent in the name is valid.
Definition: interest.cpp:671
Interest & setName(const Name &name)
Set the Interest's name.
Definition: interest.cpp:369
Interest & setSignatureInfo(const SignatureInfo &info)
Set the InterestSignatureInfo element.
Definition: interest.cpp:541
Interest & setApplicationParameters(const Block &block)
Set ApplicationParameters from a Block.
Definition: interest.cpp:478
Interest & setForwardingHint(std::vector< Name > value)
Definition: interest.cpp:387
std::string toUri() const
Return a URI-like string that represents the Interest.
Definition: interest.cpp:317
Interest & setNonce(optional< Nonce > nonce)
Set the Interest's nonce.
Definition: interest.cpp:414
const Block & wireEncode() const
Encode into a Block.
Definition: interest.cpp:134
Interest(const Name &name={}, time::milliseconds lifetime=DEFAULT_INTEREST_LIFETIME)
Construct an Interest with given name and lifetime.
Definition: interest.cpp:45
Interest & setInterestLifetime(time::milliseconds lifetime)
Set the Interest's lifetime.
Definition: interest.cpp:437
Represents an absolute name.
Definition: name.hpp:44
Name & set(ssize_t i, const Component &component)
Replace the component at the specified index.
Definition: name.cpp:206
size_t size() const noexcept
Returns the number of components.
Definition: name.hpp:155
bool empty() const noexcept
Checks if the name is empty, i.e., has no components.
Definition: name.hpp:146
Name & append(const Component &component)
Append a name component.
Definition: name.hpp:283
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:117
void erase(ssize_t i)
Erase the component at the specified index.
Definition: name.cpp:270
bool isPrefixOf(const Name &other) const noexcept
Check if this name is a prefix of another name.
Definition: name.cpp:300
const Component & get(ssize_t i) const noexcept
Returns an immutable reference to the component at the specified index.
Definition: name.hpp:167
An output stream that writes to a Buffer.
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:71
#define NDN_THROW(e)
Definition: exception.hpp:61
EncodingImpl< EstimatorTag > EncodingEstimator
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
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)
Definition: exception.cpp:31
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32)
Definition: random.cpp:68
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
boost::chrono::milliseconds milliseconds
Definition: time.hpp:48
@ 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
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:139
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:374
const time::milliseconds DEFAULT_INTEREST_LIFETIME
Default value of InterestLifetime.
Definition: interest.hpp:43
InputBuffers bufs
SignatureInfo info