blob: fafeaf08d9b16c24bf6872cc8290b0c4fa191276 [file] [log] [blame]
Junxiao Shid6dcd2c2014-02-16 14:49:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shia37405d2015-01-26 10:50:58 -07003 * 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 Shia37405d2015-01-26 10:50:58 -070024 */
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070025
26#include "ndnlp-partial-message-store.hpp"
27
28namespace nfd {
29namespace ndnlp {
30
31PartialMessage::PartialMessage()
32 : m_fragCount(0)
33 , m_received(0)
34 , m_totalLength(0)
35{
36}
37
38bool
39PartialMessage::add(uint16_t fragIndex, uint16_t fragCount, const Block& payload)
40{
41 if (m_received == 0) { // first packet
42 m_fragCount = fragCount;
43 m_payloads.resize(fragCount);
44 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070045
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070046 if (m_fragCount != fragCount || fragIndex >= m_fragCount) {
47 return false;
48 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070049
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070050 if (!m_payloads[fragIndex].empty()) { // duplicate
51 return false;
52 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070053
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070054 m_payloads[fragIndex] = payload;
55 ++m_received;
56 m_totalLength += payload.value_size();
Junxiao Shic0d05912014-02-17 19:06:21 -070057 return true;
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070058}
59
60bool
61PartialMessage::isComplete() const
62{
63 return m_received == m_fragCount;
64}
65
66Block
67PartialMessage::reassemble()
68{
69 BOOST_ASSERT(this->isComplete());
Junxiao Shidf3b4382014-02-23 11:28:21 -070070
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070071 ndn::BufferPtr buffer = make_shared<ndn::Buffer>(m_totalLength);
72 uint8_t* buf = buffer->get();
73 for (std::vector<Block>::const_iterator it = m_payloads.begin();
74 it != m_payloads.end(); ++it) {
75 const Block& payload = *it;
76 memcpy(buf, payload.value(), payload.value_size());
77 buf += payload.value_size();
78 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070079
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070080 return Block(buffer);
81}
82
Junxiao Shi98e29f42014-03-31 10:27:26 -070083PartialMessageStore::PartialMessageStore(const time::nanoseconds& idleDuration)
84 : m_idleDuration(idleDuration)
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070085{
86}
87
88PartialMessageStore::~PartialMessageStore()
89{
90}
91
92void
93PartialMessageStore::receiveNdnlpData(const Block& pkt)
94{
95 NdnlpData parsed;
96 parsed.wireDecode(pkt);
97 if (parsed.m_fragCount == 1) { // single fragment
98 this->onReceive(parsed.m_payload.blockFromValue());
99 return;
100 }
Junxiao Shidf3b4382014-02-23 11:28:21 -0700101
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700102 uint64_t messageIdentifier = parsed.m_seq - parsed.m_fragIndex;
Junxiao Shia37405d2015-01-26 10:50:58 -0700103 PartialMessage& pm = m_partialMessages[messageIdentifier];
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700104 this->scheduleCleanup(messageIdentifier, pm);
Junxiao Shidf3b4382014-02-23 11:28:21 -0700105
Junxiao Shia37405d2015-01-26 10:50:58 -0700106 pm.add(parsed.m_fragIndex, parsed.m_fragCount, parsed.m_payload);
107 if (pm.isComplete()) {
108 this->onReceive(pm.reassemble());
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700109 this->cleanup(messageIdentifier);
110 }
111}
112
113void
114PartialMessageStore::scheduleCleanup(uint64_t messageIdentifier,
Junxiao Shia37405d2015-01-26 10:50:58 -0700115 PartialMessage& partialMessage)
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700116{
Junxiao Shia37405d2015-01-26 10:50:58 -0700117 partialMessage.expiry = scheduler::schedule(m_idleDuration,
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700118 bind(&PartialMessageStore::cleanup, this, messageIdentifier));
119}
120
121void
122PartialMessageStore::cleanup(uint64_t messageIdentifier)
123{
Junxiao Shia37405d2015-01-26 10:50:58 -0700124 m_partialMessages.erase(messageIdentifier);
Junxiao Shid6dcd2c2014-02-16 14:49:54 -0700125}
126
127} // namespace ndnlp
128} // namespace nfd