NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
lp-fragmenter.cpp
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2014-2018, Regents of the University of California,
4
* Arizona Board of Regents,
5
* Colorado State University,
6
* University Pierre & Marie Curie, Sorbonne University,
7
* Washington University in St. Louis,
8
* Beijing Institute of Technology,
9
* The University of Memphis.
10
*
11
* This file is part of NFD (Named Data Networking Forwarding Daemon).
12
* See AUTHORS.md for complete list of NFD authors and contributors.
13
*
14
* NFD is free software: you can redistribute it and/or modify it under the terms
15
* of the GNU General Public License as published by the Free Software Foundation,
16
* either version 3 of the License, or (at your option) any later version.
17
*
18
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20
* PURPOSE. See the GNU General Public License for more details.
21
*
22
* You should have received a copy of the GNU General Public License along with
23
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24
*/
25
26
#include "
lp-fragmenter.hpp
"
27
#include "
link-service.hpp
"
28
29
#include <
ndn-cxx/encoding/tlv.hpp
>
30
31
namespace
nfd
{
32
namespace
face {
33
34
NFD_LOG_INIT
(
LpFragmenter
);
35
36
static_assert(
lp::tlv::LpPacket
< 253,
"LpPacket TLV-TYPE must fit in 1 octet"
);
37
static_assert(
lp::tlv::Sequence
< 253,
"Sequence TLV-TYPE must fit in 1 octet"
);
38
static_assert(
lp::tlv::FragIndex
< 253,
"FragIndex TLV-TYPE must fit in 1 octet"
);
39
static_assert(
lp::tlv::FragCount
< 253,
"FragCount TLV-TYPE must fit in 1 octet"
);
40
static_assert(
lp::tlv::Fragment
< 253,
"Fragment TLV-TYPE must fit in 1 octet"
);
41
45
static
const
size_t
MAX_SINGLE_FRAG_OVERHEAD
=
46
1 + 9 +
// LpPacket TLV-TYPE and TLV-LENGTH
47
1 + 1 + 8 +
// Sequence TLV
48
1 + 9;
// Fragment TLV-TYPE and TLV-LENGTH
49
53
static
const
size_t
MAX_FRAG_OVERHEAD
=
54
1 + 9 +
// LpPacket TLV-TYPE and TLV-LENGTH
55
1 + 1 + 8 +
// Sequence TLV
56
1 + 1 + 8 +
// FragIndex TLV
57
1 + 1 + 8 +
// FragCount TLV
58
1 + 9;
// Fragment TLV-TYPE and TLV-LENGTH
59
60
LpFragmenter::LpFragmenter
(
const
LpFragmenter::Options
& options,
const
LinkService
* linkService)
61
: m_options(options)
62
, m_linkService(linkService)
63
{
64
}
65
66
void
67
LpFragmenter::setOptions
(
const
Options
& options)
68
{
69
m_options = options;
70
}
71
72
const
LinkService
*
73
LpFragmenter::getLinkService
()
const
74
{
75
return
m_linkService;
76
}
77
78
std::tuple<bool, std::vector<lp::Packet>>
79
LpFragmenter::fragmentPacket
(
const
lp::Packet
& packet,
size_t
mtu)
80
{
81
BOOST_ASSERT(packet.
has
<
lp::FragmentField
>());
82
BOOST_ASSERT(!packet.
has
<
lp::FragIndexField
>());
83
BOOST_ASSERT(!packet.
has
<
lp::FragCountField
>());
84
85
if
(
MAX_SINGLE_FRAG_OVERHEAD
+ packet.
wireEncode
().
size
() <= mtu) {
86
// fast path: fragmentation not needed
87
// To qualify for fast path, the packet must have space for adding a sequence number,
88
// because another NDNLPv2 feature may require the sequence number.
89
return
std::make_tuple(
true
, std::vector<lp::Packet>{packet});
90
}
91
92
ndn::Buffer::const_iterator netPktBegin, netPktEnd;
93
std::tie(netPktBegin, netPktEnd) = packet.
get
<
lp::FragmentField
>();
94
size_t
netPktSize = std::distance(netPktBegin, netPktEnd);
95
96
// compute size of other NDNLPv2 headers to be placed on the first fragment
97
size_t
firstHeaderSize = 0;
98
const
Block
& packetWire = packet.
wireEncode
();
99
if
(packetWire.
type
() ==
lp::tlv::LpPacket
) {
100
for
(
const
Block
& element : packetWire.
elements
()) {
101
if
(element.type() !=
lp::tlv::Fragment
) {
102
firstHeaderSize += element.
size
();
103
}
104
}
105
}
106
107
// compute payload size
108
if
(
MAX_FRAG_OVERHEAD
+ firstHeaderSize + 1 > mtu) {
// 1-octet fragment
109
NFD_LOG_FACE_WARN
(
"fragmentation error, MTU too small for first fragment: DROP"
);
110
return
std::make_tuple(
false
, std::vector<lp::Packet>{});
111
}
112
size_t
firstPayloadSize = std::min(netPktSize, mtu - firstHeaderSize -
MAX_FRAG_OVERHEAD
);
113
size_t
payloadSize = mtu -
MAX_FRAG_OVERHEAD
;
114
size_t
fragCount = 1 + ((netPktSize - firstPayloadSize) / payloadSize) +
115
((netPktSize - firstPayloadSize) % payloadSize != 0);
116
117
// compute FragCount
118
if
(fragCount > m_options.
nMaxFragments
) {
119
NFD_LOG_FACE_WARN
(
"fragmentation error, FragCount over limit: DROP"
);
120
return
std::make_tuple(
false
, std::vector<lp::Packet>{});
121
}
122
123
// populate fragments
124
std::vector<lp::Packet> frags(fragCount);
125
frags.front() = packet;
// copy input packet to preserve other NDNLPv2 fields
126
size_t
fragIndex = 0;
127
auto
fragBegin = netPktBegin,
128
fragEnd = fragBegin + firstPayloadSize;
129
while
(fragBegin < netPktEnd) {
130
lp::Packet
& frag = frags[fragIndex];
131
frag.
add
<
lp::FragIndexField
>(fragIndex);
132
frag.
add
<
lp::FragCountField
>(fragCount);
133
frag.
set
<
lp::FragmentField
>({fragBegin, fragEnd});
134
BOOST_ASSERT(frag.
wireEncode
().
size
() <= mtu);
135
136
++fragIndex;
137
fragBegin = fragEnd;
138
fragEnd = std::min(netPktEnd, fragBegin + payloadSize);
139
}
140
BOOST_ASSERT(fragIndex == fragCount);
141
142
return
std::make_tuple(
true
, frags);
143
}
144
145
std::ostream&
146
operator<<
(std::ostream& os,
const
FaceLogHelper<LpFragmenter>
& flh)
147
{
148
if
(flh.
obj
.
getLinkService
() ==
nullptr
) {
149
os <<
"[id=0,local=unknown,remote=unknown] "
;
150
}
151
else
{
152
os << FaceLogHelper<LinkService>(*flh.
obj
.
getLinkService
());
153
}
154
return
os;
155
}
156
157
}
// namespace face
158
}
// namespace nfd
ndn::lp::Packet
Definition:
packet.hpp:31
ndn::Block::elements
const element_container & elements() const
Get container of sub-elements.
Definition:
block.hpp:391
nfd::face::LpFragmenter::LpFragmenter
LpFragmenter(const Options &options, const LinkService *linkService=nullptr)
Definition:
lp-fragmenter.cpp:60
tlv.hpp
ndn::lp::Packet::add
Packet & add(const typename FIELD::ValueType &value)
add a FIELD with value
Definition:
packet.hpp:148
ndn::lp::Packet::has
NDN_CXX_NODISCARD bool has() const
Definition:
packet.hpp:74
nfd::face::LpFragmenter::Options
Options that control the behavior of LpFragmenter.
Definition:
lp-fragmenter.hpp:45
link-service.hpp
ndn::lp::tlv::LpPacket
@ LpPacket
Definition:
tlv.hpp:33
nfd::face::LpFragmenter::Options::nMaxFragments
size_t nMaxFragments
maximum number of fragments in a packet
Definition:
lp-fragmenter.hpp:48
nfd::face::operator<<
std::ostream & operator<<(std::ostream &os, const Face &face)
Definition:
ndn-common.hpp:87
lp-fragmenter.hpp
ndn::lp::Packet::set
Packet & set(const typename FIELD::ValueType &value)
remove all occurrences of FIELD, and add a FIELD with value
Definition:
packet.hpp:136
nfd
Copyright (c) 2011-2015 Regents of the University of California.
Definition:
ndn-common.hpp:40
nfd::face::LinkService
the upper part of a Face
Definition:
link-service.hpp:76
ndn::Block::type
uint32_t type() const
Return the TLV-TYPE of the Block.
Definition:
block.hpp:274
ndn::lp::FieldDecl
Declare a field.
Definition:
field-decl.hpp:180
nfd::face::LpFragmenter
fragments network-layer packets into NDNLPv2 link-layer packets
Definition:
lp-fragmenter.hpp:40
nfd::face::LpFragmenter::getLinkService
const LinkService * getLinkService() const
Definition:
lp-fragmenter.cpp:73
ndn::lp::Packet::wireEncode
Block wireEncode() const
encode packet into wire format
Definition:
packet.cpp:119
ndn::lp::tlv::Fragment
@ Fragment
Definition:
tlv.hpp:34
ndn::lp::tlv::FragCount
@ FragCount
Definition:
tlv.hpp:37
ndn::lp::tlv::FragIndex
@ FragIndex
Definition:
tlv.hpp:36
nfd::face::LpFragmenter::setOptions
void setOptions(const Options &options)
set options for fragmenter
Definition:
lp-fragmenter.cpp:67
nfd::face::LpFragmenter::fragmentPacket
std::tuple< bool, std::vector< lp::Packet > > fragmentPacket(const lp::Packet &packet, size_t mtu)
fragments a network-layer packet into link-layer packets
Definition:
lp-fragmenter.cpp:79
ndn::Block
Represents a TLV element of NDN packet format.
Definition:
block.hpp:43
ndn::Block::size
size_t size() const
Return the size of the encoded wire, i.e.
Definition:
block.cpp:290
nfd::face::MAX_SINGLE_FRAG_OVERHEAD
static const size_t MAX_SINGLE_FRAG_OVERHEAD
maximum overhead on a single fragment, not counting other NDNLPv2 headers
Definition:
lp-fragmenter.cpp:45
nfd::face::FaceLogHelper
For internal use by FaceLogging macros.
Definition:
face-common.hpp:93
NFD_LOG_FACE_WARN
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.
Definition:
face-common.hpp:142
ndn::lp::Sequence
uint64_t Sequence
represents a sequence number
Definition:
sequence.hpp:35
ndn::lp::Packet::get
FIELD::ValueType get(size_t index=0) const
Definition:
packet.hpp:96
NFD_LOG_INIT
#define NFD_LOG_INIT(name)
Definition:
logger.hpp:31
nfd::face::FaceLogHelper::obj
const T & obj
Definition:
face-common.hpp:102
nfd::face::MAX_FRAG_OVERHEAD
static const size_t MAX_FRAG_OVERHEAD
maximum overhead of adding fragmentation to payload, not counting other NDNLPv2 headers
Definition:
lp-fragmenter.cpp:53
ndnSIM
NFD
daemon
face
lp-fragmenter.cpp
Generated on Mon Jun 1 2020 22:32:16 for ndnSIM by
1.8.18