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