ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
packet.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2023 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/lp/packet.hpp"
23#include "ndn-cxx/lp/fields.hpp"
24
25#include <boost/mp11/algorithm.hpp>
26
27namespace ndn::lp {
28
29namespace {
30
31template<typename Tag>
32constexpr int8_t
33getLocationSortOrder() noexcept
34{
35 if constexpr (std::is_same_v<Tag, field_location_tags::Header>)
36 return 1;
37 if constexpr (std::is_same_v<Tag, field_location_tags::Fragment>)
38 return 2;
39}
40
41struct FieldInfo
42{
43 constexpr
44 FieldInfo() noexcept = default;
45
46 explicit
47 FieldInfo(uint32_t type) noexcept;
48
49 uint32_t tlvType = 0;
50 bool isRecognized = false;
51 bool canIgnore = false;
52 bool isRepeatable = false;
53 int8_t locationSortOrder = getLocationSortOrder<field_location_tags::Header>();
54};
55
56FieldInfo::FieldInfo(uint32_t type) noexcept
57 : tlvType(type)
58{
59 boost::mp11::mp_for_each<FieldSet>([this] (auto fieldDecl) {
60 if (tlvType == decltype(fieldDecl)::TlvType::value) {
61 isRecognized = true;
62 isRepeatable = decltype(fieldDecl)::IsRepeatable::value;
63 locationSortOrder = getLocationSortOrder<typename decltype(fieldDecl)::FieldLocation>();
64 }
65 });
66
67 if (!isRecognized) {
70 (tlvType & 0x03) == 0x00;
71 }
72}
73
74constexpr bool
75compareFieldSortOrder(const FieldInfo& first, const FieldInfo& second) noexcept
76{
77 return (first.locationSortOrder < second.locationSortOrder) ||
78 (first.locationSortOrder == second.locationSortOrder && first.tlvType < second.tlvType);
79}
80
81} // namespace
82
83Packet::Packet() = default;
84
86{
87 wireDecode(wire);
88}
89
92{
93 // If no header or trailer, return bare network packet
94 auto elements = m_wire.elements();
95 if (elements.size() == 1 && elements.front().type() == FragmentField::TlvType::value) {
96 elements.front().parse();
97 return elements.front().elements().front();
98 }
99
100 m_wire.encode();
101 return m_wire;
102}
103
104void
106{
107 if (wire.type() == ndn::tlv::Interest || wire.type() == ndn::tlv::Data) {
108 m_wire = Block(tlv::LpPacket);
109 add<FragmentField>({wire.begin(), wire.end()});
110 return;
111 }
112
113 if (wire.type() != tlv::LpPacket) {
114 NDN_THROW(Error("LpPacket", wire.type()));
115 }
116
117 wire.parse();
118
119 bool isFirst = true;
120 FieldInfo prev;
121 for (const Block& element : wire.elements()) {
122 FieldInfo info(element.type());
123
124 if (!info.isRecognized && !info.canIgnore) {
125 NDN_THROW(Error("unrecognized field " + to_string(element.type()) + " cannot be ignored"));
126 }
127
128 if (!isFirst) {
129 if (info.tlvType == prev.tlvType && !info.isRepeatable) {
130 NDN_THROW(Error("non-repeatable field " + to_string(element.type()) + " cannot be repeated"));
131 }
132
133 else if (info.tlvType != prev.tlvType && !compareFieldSortOrder(prev, info)) {
134 NDN_THROW(Error("fields are not in correct sort order"));
135 }
136 }
137
138 isFirst = false;
139 prev = info;
140 }
141
142 m_wire = wire;
143}
144
145bool
146Packet::comparePos(uint32_t first, const Block& second) noexcept
147{
148 return compareFieldSortOrder(FieldInfo(first), FieldInfo(second.type()));
149}
150
151} // namespace ndn::lp
Represents a TLV element of the NDN packet format.
Definition block.hpp:45
const element_container & elements() const noexcept
Get container of sub-elements.
Definition block.hpp:424
const_iterator begin() const
Returns an iterator to the beginning of the encoded wire.
Definition block.cpp:275
void encode()
Encode sub-elements into TLV-VALUE.
Definition block.cpp:353
const_iterator end() const
Returns an iterator past-the-end of the encoded wire.
Definition block.cpp:284
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition block.hpp:275
void parse() const
Parse TLV-VALUE into sub-elements.
Definition block.cpp:326
Block wireEncode() const
Encode packet into wire format.
Definition packet.cpp:91
void wireDecode(const Block &wire)
Decode packet from wire format.
Definition packet.cpp:105
#define NDN_THROW(e)
Definition exception.hpp:56
@ HEADER3_MAX
Upper bound of 3-octet header field.
Definition tlv.hpp:70
@ HEADER3_MIN
Lower bound of 3-octet header field.
Definition tlv.hpp:66
Contains classes and functions related to NDNLPv2.
@ Data
Definition tlv.hpp:69
@ Interest
Definition tlv.hpp:68
bool isRecognized
is this field known
Definition packet.cpp:50
uint32_t tlvType
TLV-TYPE of the field; 0 if field does not exist.
Definition packet.cpp:49
bool canIgnore
can this unknown field be ignored
Definition packet.cpp:51
int8_t locationSortOrder
sort order of field_location_tag
Definition packet.cpp:53
bool isRepeatable
is the field repeatable
Definition packet.cpp:52
SignatureInfo info