blob: 03b1454b3bff6f65b979285ae6b0dcaa26c1063a [file] [log] [blame]
Junxiao Shi9b0d3e92014-02-15 12:27:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, 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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Junxiao Shia22a2172015-01-05 11:14:02 -070024 */
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070025
26#include "ndnlp-slicer.hpp"
27
Alexander Afanasyev4a771362014-04-24 21:29:33 -070028#include <ndn-cxx/encoding/encoding-buffer.hpp>
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070029
30namespace nfd {
31namespace ndnlp {
32
33Slicer::Slicer(size_t mtu)
34 : m_mtu(mtu)
35{
36 this->estimateOverhead();
37}
38
39Slicer::~Slicer()
40{
41}
42
43template<bool T>
Junxiao Shia22a2172015-01-05 11:14:02 -070044size_t
45Slicer::encodeFragment(ndn::EncodingImpl<T>& blk,
46 uint64_t seq, uint16_t fragIndex, uint16_t fragCount,
47 const uint8_t* payload, size_t payloadSize)
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070048{
49 size_t totalLength = 0;
Junxiao Shidf3b4382014-02-23 11:28:21 -070050
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070051 // NdnlpPayload
52 size_t payloadLength = blk.prependByteArray(payload, payloadSize);
53 totalLength += payloadLength;
54 totalLength += blk.prependVarNumber(payloadLength);
55 totalLength += blk.prependVarNumber(tlv::NdnlpPayload);
Junxiao Shidf3b4382014-02-23 11:28:21 -070056
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070057 bool needFragIndexAndCount = fragCount > 1;
58 if (needFragIndexAndCount) {
59 // NdnlpFragCount
Junxiao Shidf3b4382014-02-23 11:28:21 -070060 size_t fragCountLength = blk.prependNonNegativeInteger(fragCount);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070061 totalLength += fragCountLength;
62 totalLength += blk.prependVarNumber(fragCountLength);
63 totalLength += blk.prependVarNumber(tlv::NdnlpFragCount);
Junxiao Shidf3b4382014-02-23 11:28:21 -070064
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070065 // NdnlpFragIndex
Junxiao Shidf3b4382014-02-23 11:28:21 -070066 size_t fragIndexLength = blk.prependNonNegativeInteger(fragIndex);
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070067 totalLength += fragIndexLength;
68 totalLength += blk.prependVarNumber(fragIndexLength);
69 totalLength += blk.prependVarNumber(tlv::NdnlpFragIndex);
70 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070071
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070072 // NdnlpSequence
73 uint64_t sequenceBE = htobe64(seq);
74 size_t sequenceLength = blk.prependByteArray(
75 reinterpret_cast<uint8_t*>(&sequenceBE), sizeof(sequenceBE));
76 totalLength += sequenceLength;
77 totalLength += blk.prependVarNumber(sequenceLength);
78 totalLength += blk.prependVarNumber(tlv::NdnlpSequence);
Junxiao Shidf3b4382014-02-23 11:28:21 -070079
80 // NdnlpData
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070081 totalLength += blk.prependVarNumber(totalLength);
82 totalLength += blk.prependVarNumber(tlv::NdnlpData);
Junxiao Shidf3b4382014-02-23 11:28:21 -070083
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070084 return totalLength;
85}
86
87void
88Slicer::estimateOverhead()
89{
Junxiao Shia22a2172015-01-05 11:14:02 -070090 // estimate fragment size with all header fields at largest possible size
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070091 ndn::EncodingEstimator estimator;
Junxiao Shia22a2172015-01-05 11:14:02 -070092 size_t estimatedSize = this->encodeFragment(estimator,
93 std::numeric_limits<uint64_t>::max(),
94 std::numeric_limits<uint16_t>::max() - 1,
95 std::numeric_limits<uint16_t>::max(),
96 nullptr, m_mtu);
Junxiao Shidf3b4382014-02-23 11:28:21 -070097
Junxiao Shia22a2172015-01-05 11:14:02 -070098 size_t overhead = estimatedSize - m_mtu; // minus payload length in estimation
Junxiao Shi9b0d3e92014-02-15 12:27:12 -070099 m_maxPayload = m_mtu - overhead;
100}
101
102PacketArray
103Slicer::slice(const Block& block)
104{
105 BOOST_ASSERT(block.hasWire());
106 const uint8_t* networkPacket = block.wire();
107 size_t networkPacketSize = block.size();
Junxiao Shidf3b4382014-02-23 11:28:21 -0700108
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700109 uint16_t fragCount = static_cast<uint16_t>(
110 (networkPacketSize / m_maxPayload) +
111 (networkPacketSize % m_maxPayload == 0 ? 0 : 1)
112 );
Junxiao Shia22a2172015-01-05 11:14:02 -0700113 PacketArray pa = make_shared<std::vector<Block>>();
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700114 pa->reserve(fragCount);
115 SequenceBlock seqBlock = m_seqgen.nextBlock(fragCount);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700116
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700117 for (uint16_t fragIndex = 0; fragIndex < fragCount; ++fragIndex) {
118 size_t payloadOffset = fragIndex * m_maxPayload;
119 const uint8_t* payload = networkPacket + payloadOffset;
120 size_t payloadSize = std::min(m_maxPayload, networkPacketSize - payloadOffset);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700121
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700122 ndn::EncodingBuffer buffer(m_mtu, 0);
Junxiao Shia22a2172015-01-05 11:14:02 -0700123 size_t pktSize = this->encodeFragment(buffer,
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700124 seqBlock[fragIndex], fragIndex, fragCount, payload, payloadSize);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700125
Junxiao Shiac7b4372014-12-13 21:47:04 -0700126 BOOST_VERIFY(pktSize <= m_mtu);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700127
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700128 pa->push_back(buffer.block());
129 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700130
Junxiao Shi9b0d3e92014-02-15 12:27:12 -0700131 return pa;
132}
133
134} // namespace ndnlp
135} // namespace nfd