NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
tlv.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 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 #ifndef NDN_ENCODING_TLV_HPP
23 #define NDN_ENCODING_TLV_HPP
24 
26 
27 #include <cstring>
28 #include <iterator>
29 #include <ostream>
30 #include <type_traits>
31 #include <vector>
32 
33 #include <boost/endian/conversion.hpp>
34 
35 namespace ndn {
36 
41 const size_t MAX_NDN_PACKET_SIZE = 8800;
42 
46 namespace tlv {
47 
52 class Error : public std::runtime_error
53 {
54 public:
55  using std::runtime_error::runtime_error;
56 
57  Error(const char* expectedType, uint32_t actualType);
58 };
59 
63 enum : uint32_t {
64  Invalid = 0,
65  Interest = 5,
66  Data = 6,
67  Name = 7,
74  Nonce = 10,
76  HopLimit = 34,
78  MetaInfo = 20,
79  Content = 21,
86  KeyLocator = 28,
87  KeyDigest = 29,
90 
93 
95  AppPrivateBlock2 = 32767
96 };
97 
101 enum : uint32_t {
106  Exclude = 16,
108  Any = 19,
109 };
110 
111 [[deprecated("use GenericNameComponent")]]
113 
117 enum : uint32_t {
124 };
125 
129 enum SignatureTypeValue : uint16_t {
134 };
135 
136 std::ostream&
137 operator<<(std::ostream& os, SignatureTypeValue st);
138 
142 enum {
144  NotBefore = 254,
145  NotAfter = 255,
146 
150  DescriptionValue = 514
151 };
152 
156 enum ContentTypeValue : uint32_t {
164 };
165 
166 std::ostream&
167 operator<<(std::ostream& os, ContentTypeValue ct);
168 
173 constexpr bool
174 isCriticalType(uint32_t type)
175 {
176  return type <= 31 || (type & 0x01);
177 }
178 
190 template<typename Iterator>
192 readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
193 
207 template<typename Iterator>
209 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
210 
221 template<typename Iterator>
222 uint64_t
223 readVarNumber(Iterator& begin, Iterator end);
224 
237 template<typename Iterator>
238 uint32_t
239 readType(Iterator& begin, Iterator end);
240 
244 constexpr size_t
245 sizeOfVarNumber(uint64_t number) noexcept;
246 
251 size_t
252 writeVarNumber(std::ostream& os, uint64_t number);
253 
267 template<typename Iterator>
268 uint64_t
269 readNonNegativeInteger(size_t size, Iterator& begin, Iterator end);
270 
274 constexpr size_t
275 sizeOfNonNegativeInteger(uint64_t integer) noexcept;
276 
281 size_t
282 writeNonNegativeInteger(std::ostream& os, uint64_t integer);
283 
287 
288 // Inline definitions
289 
293 
294 namespace detail {
295 
298 template<typename Iterator>
300 {
301 public:
302  constexpr bool
303  operator()(size_t size, Iterator& begin, Iterator end, uint64_t& number) const noexcept
304  {
305  number = 0;
306  size_t count = 0;
307  for (; begin != end && count < size; ++begin, ++count) {
308  number = (number << 8) | *begin;
309  }
310  return count == size;
311  }
312 };
313 
316 template<typename Iterator>
318 {
319 public:
320  constexpr bool
321  operator()(size_t size, Iterator& begin, Iterator end, uint64_t& number) const noexcept
322  {
323  if (begin + size > end) {
324  return false;
325  }
326 
327  switch (size) {
328  case 1: {
329  number = *begin;
330  ++begin;
331  return true;
332  }
333  case 2: {
334  uint16_t value = 0;
335  std::memcpy(&value, &*begin, 2);
336  begin += 2;
337  number = boost::endian::big_to_native(value);
338  return true;
339  }
340  case 4: {
341  uint32_t value = 0;
342  std::memcpy(&value, &*begin, 4);
343  begin += 4;
344  number = boost::endian::big_to_native(value);
345  return true;
346  }
347  case 8: {
348  uint64_t value = 0;
349  std::memcpy(&value, &*begin, 8);
350  begin += 8;
351  number = boost::endian::big_to_native(value);
352  return true;
353  }
354  default: {
356  }
357  }
358  }
359 };
360 
366 template<typename Iterator,
367  typename DecayedIterator = std::decay_t<Iterator>,
368  typename ValueType = typename std::iterator_traits<DecayedIterator>::value_type>
369 constexpr bool
371 {
372  return (std::is_convertible<DecayedIterator, const ValueType*>::value ||
373  std::is_convertible<DecayedIterator, typename std::basic_string<ValueType>::const_iterator>::value ||
374  std::is_convertible<DecayedIterator, typename std::vector<ValueType>::const_iterator>::value) &&
375  sizeof(ValueType) == 1 &&
376  !std::is_same<ValueType, bool>::value;
377 }
378 
379 template<typename Iterator>
380 class ReadNumber : public std::conditional_t<shouldSelectContiguousReadNumber<Iterator>(),
381  ReadNumberFast<Iterator>, ReadNumberSlow<Iterator>>
382 {
383 };
384 
385 } // namespace detail
386 
387 template<typename Iterator>
388 bool
389 readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept
390 {
391  if (begin == end)
392  return false;
393 
394  uint8_t firstOctet = *begin;
395  ++begin;
396  if (firstOctet < 253) {
397  number = firstOctet;
398  return true;
399  }
400 
401  size_t size = firstOctet == 253 ? 2 :
402  firstOctet == 254 ? 4 : 8;
403  return detail::ReadNumber<Iterator>()(size, begin, end, number);
404 }
405 
406 template<typename Iterator>
407 bool
408 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
409 {
410  uint64_t number = 0;
411  bool isOk = readVarNumber(begin, end, number);
412  if (!isOk || number == Invalid || number > std::numeric_limits<uint32_t>::max()) {
413  return false;
414  }
415 
416  type = static_cast<uint32_t>(number);
417  return true;
418 }
419 
420 template<typename Iterator>
421 uint64_t
422 readVarNumber(Iterator& begin, Iterator end)
423 {
424  if (begin == end) {
425  NDN_THROW(Error("Empty buffer during TLV parsing"));
426  }
427 
428  uint64_t value = 0;
429  bool isOk = readVarNumber(begin, end, value);
430  if (!isOk) {
431  NDN_THROW(Error("Insufficient data during TLV parsing"));
432  }
433 
434  return value;
435 }
436 
437 template<typename Iterator>
438 uint32_t
439 readType(Iterator& begin, Iterator end)
440 {
441  uint64_t type = readVarNumber(begin, end);
442  if (type == Invalid || type > std::numeric_limits<uint32_t>::max()) {
443  NDN_THROW(Error("Illegal TLV-TYPE " + to_string(type)));
444  }
445 
446  return static_cast<uint32_t>(type);
447 }
448 
449 constexpr size_t
450 sizeOfVarNumber(uint64_t number) noexcept
451 {
452  return number < 253 ? 1 :
453  number <= std::numeric_limits<uint16_t>::max() ? 3 :
454  number <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
455 }
456 
457 inline size_t
458 writeVarNumber(std::ostream& os, uint64_t number)
459 {
460  if (number < 253) {
461  os.put(static_cast<char>(number));
462  return 1;
463  }
464  else if (number <= std::numeric_limits<uint16_t>::max()) {
465  os.put(static_cast<char>(253));
466  uint16_t value = boost::endian::native_to_big(static_cast<uint16_t>(number));
467  os.write(reinterpret_cast<const char*>(&value), 2);
468  return 3;
469  }
470  else if (number <= std::numeric_limits<uint32_t>::max()) {
471  os.put(static_cast<char>(254));
472  uint32_t value = boost::endian::native_to_big(static_cast<uint32_t>(number));
473  os.write(reinterpret_cast<const char*>(&value), 4);
474  return 5;
475  }
476  else {
477  os.put(static_cast<char>(255));
478  uint64_t value = boost::endian::native_to_big(number);
479  os.write(reinterpret_cast<const char*>(&value), 8);
480  return 9;
481  }
482 }
483 
484 template<typename Iterator>
485 uint64_t
486 readNonNegativeInteger(size_t size, Iterator& begin, Iterator end)
487 {
488  if (size != 1 && size != 2 && size != 4 && size != 8) {
489  NDN_THROW(Error("Invalid length " + to_string(size) + " for nonNegativeInteger"));
490  }
491 
492  uint64_t number = 0;
493  bool isOk = detail::ReadNumber<Iterator>()(size, begin, end, number);
494  if (!isOk) {
495  NDN_THROW(Error("Insufficient data during nonNegativeInteger parsing"));
496  }
497 
498  return number;
499 }
500 
501 constexpr size_t
502 sizeOfNonNegativeInteger(uint64_t integer) noexcept
503 {
504  return integer <= std::numeric_limits<uint8_t>::max() ? 1 :
505  integer <= std::numeric_limits<uint16_t>::max() ? 2 :
506  integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
507 }
508 
509 inline size_t
510 writeNonNegativeInteger(std::ostream& os, uint64_t integer)
511 {
512  if (integer <= std::numeric_limits<uint8_t>::max()) {
513  os.put(static_cast<char>(integer));
514  return 1;
515  }
516  else if (integer <= std::numeric_limits<uint16_t>::max()) {
517  uint16_t value = boost::endian::native_to_big(static_cast<uint16_t>(integer));
518  os.write(reinterpret_cast<const char*>(&value), 2);
519  return 2;
520  }
521  else if (integer <= std::numeric_limits<uint32_t>::max()) {
522  uint32_t value = boost::endian::native_to_big(static_cast<uint32_t>(integer));
523  os.write(reinterpret_cast<const char*>(&value), 4);
524  return 4;
525  }
526  else {
527  uint64_t value = boost::endian::native_to_big(integer);
528  os.write(reinterpret_cast<const char*>(&value), 8);
529  return 8;
530  }
531 }
532 
533 } // namespace tlv
534 } // namespace ndn
535 
536 #endif // NDN_ENCODING_TLV_HPP
ndn::tlv::ValidityPeriod
@ ValidityPeriod
Definition: tlv.hpp:143
ndn::tlv::ContentType_Key
@ ContentType_Key
public key, certificate
Definition: tlv.hpp:159
ndn::tlv::detail::ReadNumberFast::operator()
constexpr bool operator()(size_t size, Iterator &begin, Iterator end, uint64_t &number) const noexcept
Definition: tlv.hpp:321
common.hpp
Common includes and macros used throughout the library.
ndn::tlv::SegmentNameComponent
@ SegmentNameComponent
Definition: tlv.hpp:119
ndn::tlv::CanBePrefix
@ CanBePrefix
Definition: tlv.hpp:71
ndn::tlv::sizeOfNonNegativeInteger
constexpr size_t sizeOfNonNegativeInteger(uint64_t integer) noexcept
Get the number of bytes necessary to hold the value of integer encoded as nonNegativeInteger.
Definition: tlv.hpp:502
ndn::tlv::Selectors
@ Selectors
Definition: tlv.hpp:102
ndn::tlv::Nonce
@ Nonce
Definition: tlv.hpp:74
ndn::tlv::PublisherPublicKeyLocator
@ PublisherPublicKeyLocator
Definition: tlv.hpp:105
ndn::tlv::VersionNameComponent
@ VersionNameComponent
Definition: tlv.hpp:121
ndn::tlv::detail::shouldSelectContiguousReadNumber
constexpr bool shouldSelectContiguousReadNumber()
Determine whether to select ReadNumber implementation for ContiguousIterator.
Definition: tlv.hpp:370
ndn::tlv::ContentTypeValue
ContentTypeValue
ContentType values.
Definition: tlv.hpp:156
ndn::tlv::AppPrivateBlock2
@ AppPrivateBlock2
Definition: tlv.hpp:95
ndn::tlv::TimestampNameComponent
@ TimestampNameComponent
Definition: tlv.hpp:122
ndn::tlv::NameComponent
constexpr int NameComponent
Definition: tlv.hpp:112
ndn::tlv::ParametersSha256DigestComponent
@ ParametersSha256DigestComponent
Definition: tlv.hpp:70
ndn::tlv::InterestLifetime
@ InterestLifetime
Definition: tlv.hpp:75
ndn::tlv::KeyDigest
@ KeyDigest
Definition: tlv.hpp:87
ndn::tlv::writeVarNumber
size_t writeVarNumber(std::ostream &os, uint64_t number)
Write VAR-NUMBER to the specified stream.
Definition: tlv.hpp:458
ndn::tlv::ForwardingHint
@ ForwardingHint
Definition: tlv.hpp:73
NDN_CXX_UNREACHABLE
#define NDN_CXX_UNREACHABLE
Definition: backports.hpp:72
ndn::tlv::FreshnessPeriod
@ FreshnessPeriod
Definition: tlv.hpp:83
ndn::tlv::MinSuffixComponents
@ MinSuffixComponents
Definition: tlv.hpp:103
ndn::tlv::NameComponentMax
@ NameComponentMax
Definition: tlv.hpp:92
ndn::tlv::DescriptionKey
@ DescriptionKey
Definition: tlv.hpp:149
ndn::tlv::ContentType_Manifest
@ ContentType_Manifest
Definition: tlv.hpp:161
ndn::tlv::Exclude
@ Exclude
Definition: tlv.hpp:106
ndn::tlv::DescriptionEntry
@ DescriptionEntry
Definition: tlv.hpp:148
ndn::tlv::detail::ReadNumberFast
Function object to read a number from ContiguousIterator.
Definition: tlv.hpp:318
ndn::MetaInfo
A MetaInfo holds the meta info which is signed inside the data packet.
Definition: meta-info.hpp:59
ndn::tlv::SignatureValue
@ SignatureValue
Definition: tlv.hpp:81
ndn::Name
Represents an absolute name.
Definition: name.hpp:44
ndn::tlv::ContentType_Link
@ ContentType_Link
another name that identifies the actual data content
Definition: tlv.hpp:158
ndn::tlv::NameComponentMin
@ NameComponentMin
Definition: tlv.hpp:91
NDN_CXX_NODISCARD
#define NDN_CXX_NODISCARD
Definition: backports.hpp:68
ndn::tlv::writeNonNegativeInteger
size_t writeNonNegativeInteger(std::ostream &os, uint64_t integer)
Write nonNegativeInteger to the specified stream.
Definition: tlv.hpp:510
ndn::tlv::HopLimit
@ HopLimit
Definition: tlv.hpp:76
ndn::tlv::MustBeFresh
@ MustBeFresh
Definition: tlv.hpp:72
ndn::tlv::SequenceNumNameComponent
@ SequenceNumNameComponent
Definition: tlv.hpp:123
ndn::tlv::DescriptionValue
@ DescriptionValue
Definition: tlv.hpp:150
ndn::tlv::readType
NDN_CXX_NODISCARD bool readType(Iterator &begin, Iterator end, uint32_t &type) noexcept
Read TLV-TYPE.
Definition: tlv.hpp:408
ndn::tlv::ContentType_Nack
@ ContentType_Nack
application-level nack
Definition: tlv.hpp:160
NDN_THROW
#define NDN_THROW(e)
Definition: exception.hpp:61
ndn::tlv::NotBefore
@ NotBefore
Definition: tlv.hpp:144
ndn::SignatureInfo
Represents a SignatureInfo TLV element.
Definition: signature-info.hpp:35
ndn::tlv::detail::ReadNumberSlow
Function object to read a number from InputIterator.
Definition: tlv.hpp:300
ndn::tlv::ContentType_Flic
@ ContentType_Flic
File-Like ICN Collection.
Definition: tlv.hpp:163
ndn::tlv::sizeOfVarNumber
constexpr size_t sizeOfVarNumber(uint64_t number) noexcept
Get the number of bytes necessary to hold the value of number encoded as VAR-NUMBER.
Definition: tlv.hpp:450
ndn::tlv::readVarNumber
NDN_CXX_NODISCARD bool readVarNumber(Iterator &begin, Iterator end, uint64_t &number) noexcept
Read VAR-NUMBER in NDN-TLV encoding.
Definition: tlv.hpp:389
ndn::tlv::SignatureTypeValue
SignatureTypeValue
SignatureType values.
Definition: tlv.hpp:129
ndn::tlv::operator<<
std::ostream & operator<<(std::ostream &os, SignatureTypeValue st)
Definition: tlv.cpp:33
ndn::tlv::ContentType_Blob
@ ContentType_Blob
payload
Definition: tlv.hpp:157
ndn::tlv::detail::ReadNumberSlow::operator()
constexpr bool operator()(size_t size, Iterator &begin, Iterator end, uint64_t &number) const noexcept
Definition: tlv.hpp:303
ndn::Interest
Represents an Interest packet.
Definition: interest.hpp:44
ndn::tlv::LinkPreference
@ LinkPreference
Definition: tlv.hpp:89
ndn::tlv::GenericNameComponent
@ GenericNameComponent
Definition: tlv.hpp:68
ndn::tlv::ChildSelector
@ ChildSelector
Definition: tlv.hpp:107
ndn::tlv::NotAfter
@ NotAfter
Definition: tlv.hpp:145
ndn::Data
Represents a Data packet.
Definition: data.hpp:36
ndn::tlv::FinalBlockId
@ FinalBlockId
Definition: tlv.hpp:84
ndn::tlv::readNonNegativeInteger
uint64_t readNonNegativeInteger(size_t size, Iterator &begin, Iterator end)
Read nonNegativeInteger in NDN-TLV encoding.
Definition: tlv.hpp:486
ndn::SignatureSha256WithRsa
Represents a signature of Sha256WithRsa type.
Definition: signature-sha256-with-rsa.hpp:35
ndn::MAX_NDN_PACKET_SIZE
const size_t MAX_NDN_PACKET_SIZE
practical limit of network layer packet size
Definition: tlv.hpp:41
ndn::tlv::SignatureHmacWithSha256
@ SignatureHmacWithSha256
Definition: tlv.hpp:133
ndn::tlv::isCriticalType
constexpr bool isCriticalType(uint32_t type)
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
Definition: tlv.hpp:174
ndn::tlv::Any
@ Any
Definition: tlv.hpp:108
ndn::to_string
std::string to_string(const T &val)
Definition: backports.hpp:102
ndn::tlv::AdditionalDescription
@ AdditionalDescription
Definition: tlv.hpp:147
ndn::tlv::Error
represents an error in TLV encoding or decoding
Definition: tlv.hpp:53
ndn::tlv::ByteOffsetNameComponent
@ ByteOffsetNameComponent
Definition: tlv.hpp:120
ndn::tlv::Invalid
@ Invalid
Definition: tlv.hpp:64
ndn::KeyLocator
Definition: key-locator.hpp:30
ndn::tlv::AppPrivateBlock1
@ AppPrivateBlock1
Definition: tlv.hpp:94
ndn::tlv::MaxSuffixComponents
@ MaxSuffixComponents
Definition: tlv.hpp:104
ndn::tlv::LinkDelegation
@ LinkDelegation
Definition: tlv.hpp:88
ndn::tlv::Error::Error
Error(const char *expectedType, uint32_t actualType)
Definition: tlv.cpp:27
ndn::DigestSha256
Represents a signature of DigestSha256 type.
Definition: digest-sha256.hpp:35
ndn::tlv::ContentType_PrefixAnn
@ ContentType_PrefixAnn
prefix announcement
Definition: tlv.hpp:162
ndn
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-strategy-choice-helper.hpp:34
ndn::tlv::ImplicitSha256DigestComponent
@ ImplicitSha256DigestComponent
Definition: tlv.hpp:69
ndn::tlv::SignatureType
@ SignatureType
Definition: tlv.hpp:85
ndn::tlv::Content
@ Content
Definition: tlv.hpp:79
ndn::tlv::KeywordNameComponent
@ KeywordNameComponent
Definition: tlv.hpp:118
ndn::tlv::detail::ReadNumber
Definition: tlv.hpp:382
ndn::tlv::ApplicationParameters
@ ApplicationParameters
Definition: tlv.hpp:77
ndn::SignatureSha256WithEcdsa
Represents a signature of Sha256WithEcdsa type.
Definition: signature-sha256-with-ecdsa.hpp:35
ndn::tlv::ContentType
@ ContentType
Definition: tlv.hpp:82