face: NDNLP encoding change
FragIndex and FragCount fields are encoded as nonNegativeInteger.
refs #1283
Change-Id: I4654078c3bfd73c83ce06ce6a9cd97952a4f49f8
diff --git a/daemon/face/ndnlp-parse.cpp b/daemon/face/ndnlp-parse.cpp
index 1162f0e..5ce4fc5 100644
--- a/daemon/face/ndnlp-parse.cpp
+++ b/daemon/face/ndnlp-parse.cpp
@@ -20,7 +20,7 @@
if (elements.size() < 2) {
throw ParseError("NdnlpData element has incorrect number of children");
}
-
+
const Block& sequenceElement = elements.front();
if (sequenceElement.type() != tlv::NdnlpSequence) {
throw ParseError("NdnlpSequence element is missing");
@@ -29,7 +29,7 @@
throw ParseError("NdnlpSequence element has incorrect length");
}
m_seq = be64toh(*reinterpret_cast<const uint64_t*>(&*sequenceElement.value_begin()));
-
+
const Block& payloadElement = elements.back();
if (payloadElement.type() != tlv::NdnlpPayload) {
throw ParseError("NdnlpPayload element is missing");
@@ -44,24 +44,30 @@
if (elements.size() != 4) {
throw ParseError("NdnlpData element has incorrect number of children");
}
-
+
const Block& fragIndexElement = elements.at(1);
if (fragIndexElement.type() != tlv::NdnlpFragIndex) {
throw ParseError("NdnlpFragIndex element is missing");
}
- if (fragIndexElement.value_size() != sizeof(uint16_t)) {
- throw ParseError("NdnlpFragIndex element has incorrect length");
+ uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
+ if (fragIndex > std::numeric_limits<uint16_t>::max()) {
+ throw ParseError("NdnlpFragIndex is too large");
}
- m_fragIndex = be16toh(*reinterpret_cast<const uint16_t*>(&*fragIndexElement.value_begin()));
-
+ m_fragIndex = static_cast<uint16_t>(fragIndex);
+
const Block& fragCountElement = elements.at(2);
if (fragCountElement.type() != tlv::NdnlpFragCount) {
throw ParseError("NdnlpFragCount element is missing");
}
- if (fragCountElement.value_size() != sizeof(uint16_t)) {
- throw ParseError("NdnlpFragCount element has incorrect length");
+ uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
+ if (fragCount > std::numeric_limits<uint16_t>::max()) {
+ throw ParseError("NdnlpFragCount is too large");
}
- m_fragCount = be16toh(*reinterpret_cast<const uint16_t*>(&*fragCountElement.value_begin()));
+ m_fragCount = static_cast<uint16_t>(fragCount);
+
+ if (m_fragIndex >= m_fragCount) {
+ throw ParseError("NdnlpFragIndex must be less than NdnlpFragCount");
+ }
}
} // namespace ndnlp
diff --git a/daemon/face/ndnlp-parse.hpp b/daemon/face/ndnlp-parse.hpp
index 2790569..4215620 100644
--- a/daemon/face/ndnlp-parse.hpp
+++ b/daemon/face/ndnlp-parse.hpp
@@ -22,7 +22,7 @@
};
/** \brief represents a NdnlpData packet
- *
+ *
* NdnlpData ::= NDNLP-DATA-TYPE TLV-LENGTH
* NdnlpSequence
* NdnlpFragIndex?
@@ -33,12 +33,12 @@
{
public:
/** \brief parse a NdnlpData packet
- *
+ *
* \exception ParseError packet is malformated
*/
void
wireDecode(const Block& wire);
-
+
public:
uint64_t m_seq;
uint16_t m_fragIndex;
diff --git a/daemon/face/ndnlp-partial-message-store.cpp b/daemon/face/ndnlp-partial-message-store.cpp
index df8a285..74c109f 100644
--- a/daemon/face/ndnlp-partial-message-store.cpp
+++ b/daemon/face/ndnlp-partial-message-store.cpp
@@ -23,15 +23,15 @@
m_fragCount = fragCount;
m_payloads.resize(fragCount);
}
-
+
if (m_fragCount != fragCount || fragIndex >= m_fragCount) {
return false;
}
-
+
if (!m_payloads[fragIndex].empty()) { // duplicate
return false;
}
-
+
m_payloads[fragIndex] = payload;
++m_received;
m_totalLength += payload.value_size();
@@ -48,7 +48,7 @@
PartialMessage::reassemble()
{
BOOST_ASSERT(this->isComplete());
-
+
ndn::BufferPtr buffer = make_shared<ndn::Buffer>(m_totalLength);
uint8_t* buf = buffer->get();
for (std::vector<Block>::const_iterator it = m_payloads.begin();
@@ -57,7 +57,7 @@
memcpy(buf, payload.value(), payload.value_size());
buf += payload.value_size();
}
-
+
return Block(buffer);
}
@@ -80,14 +80,14 @@
this->onReceive(parsed.m_payload.blockFromValue());
return;
}
-
+
uint64_t messageIdentifier = parsed.m_seq - parsed.m_fragIndex;
shared_ptr<PartialMessage> pm = m_partialMessages[messageIdentifier];
if (!static_cast<bool>(pm)) {
m_partialMessages[messageIdentifier] = pm = make_shared<PartialMessage>();
}
this->scheduleCleanup(messageIdentifier, pm);
-
+
pm->add(parsed.m_fragIndex, parsed.m_fragCount, parsed.m_payload);
if (pm->isComplete()) {
this->onReceive(pm->reassemble());
@@ -111,7 +111,7 @@
if (it == m_partialMessages.end()) {
return;
}
-
+
m_scheduler.cancelEvent(it->second->m_expiry);
m_partialMessages.erase(it);
}
diff --git a/daemon/face/ndnlp-partial-message-store.hpp b/daemon/face/ndnlp-partial-message-store.hpp
index 954b79a..e5de5b1 100644
--- a/daemon/face/ndnlp-partial-message-store.hpp
+++ b/daemon/face/ndnlp-partial-message-store.hpp
@@ -20,26 +20,26 @@
{
public:
PartialMessage();
-
+
bool
add(uint16_t fragIndex, uint16_t fragCount, const Block& payload);
-
+
bool
isComplete() const;
-
+
/** \brief reassemble network layer packet
- *
+ *
* isComplete() must be true before calling this method
- *
+ *
* \exception ndn::Block::Error packet is malformated
* \return network layer packet
*/
Block
reassemble();
-
+
public:
EventId m_expiry;
-
+
private:
size_t m_fragCount;
size_t m_received;
@@ -54,28 +54,28 @@
public:
PartialMessageStore(Scheduler& scheduler,
time::Duration idleDuration = time::milliseconds(100));
-
+
virtual
~PartialMessageStore();
-
+
/** \brief receive a NdnlpData packet
- *
+ *
* \exception ParseError NDNLP packet is malformated
* \exception ndn::Block::Error network layer packet is malformated
*/
void
receiveNdnlpData(const Block& pkt);
-
+
/// fires when network layer packet is received
EventEmitter<Block> onReceive;
-
+
private:
void
scheduleCleanup(uint64_t messageIdentifier, shared_ptr<PartialMessage> partialMessage);
-
+
void
cleanup(uint64_t messageIdentifier);
-
+
private:
std::map<uint64_t, shared_ptr<PartialMessage> > m_partialMessages;
diff --git a/daemon/face/ndnlp-sequence-generator.hpp b/daemon/face/ndnlp-sequence-generator.hpp
index f067552..537cac2 100644
--- a/daemon/face/ndnlp-sequence-generator.hpp
+++ b/daemon/face/ndnlp-sequence-generator.hpp
@@ -18,15 +18,15 @@
{
public:
SequenceBlock(uint64_t start, size_t count);
-
+
/** \return{ the pos-th sequence number }
*/
uint64_t
operator[](size_t pos) const;
-
+
size_t
count() const;
-
+
private:
uint64_t m_start;
size_t m_count;
@@ -53,7 +53,7 @@
{
public:
SequenceGenerator();
-
+
/** \brief generates a block of consecutive sequence numbers
*
* This block must not overlap with a recent block.
diff --git a/daemon/face/ndnlp-slicer.cpp b/daemon/face/ndnlp-slicer.cpp
index 074a4f7..1cc64a4 100644
--- a/daemon/face/ndnlp-slicer.cpp
+++ b/daemon/face/ndnlp-slicer.cpp
@@ -28,32 +28,28 @@
const uint8_t* payload, size_t payloadSize)
{
size_t totalLength = 0;
-
+
// NdnlpPayload
size_t payloadLength = blk.prependByteArray(payload, payloadSize);
totalLength += payloadLength;
totalLength += blk.prependVarNumber(payloadLength);
totalLength += blk.prependVarNumber(tlv::NdnlpPayload);
-
+
bool needFragIndexAndCount = fragCount > 1;
if (needFragIndexAndCount) {
// NdnlpFragCount
- uint16_t fragCountBE = htobe16(fragCount);
- size_t fragCountLength = blk.prependByteArray(
- reinterpret_cast<uint8_t*>(&fragCountBE), sizeof(fragCountBE));
+ size_t fragCountLength = blk.prependNonNegativeInteger(fragCount);
totalLength += fragCountLength;
totalLength += blk.prependVarNumber(fragCountLength);
totalLength += blk.prependVarNumber(tlv::NdnlpFragCount);
-
+
// NdnlpFragIndex
- uint16_t fragIndexBE = htobe16(fragIndex);
- size_t fragIndexLength = blk.prependByteArray(
- reinterpret_cast<uint8_t*>(&fragIndexBE), sizeof(fragIndexBE));
+ size_t fragIndexLength = blk.prependNonNegativeInteger(fragIndex);
totalLength += fragIndexLength;
totalLength += blk.prependVarNumber(fragIndexLength);
totalLength += blk.prependVarNumber(tlv::NdnlpFragIndex);
}
-
+
// NdnlpSequence
uint64_t sequenceBE = htobe64(seq);
size_t sequenceLength = blk.prependByteArray(
@@ -61,10 +57,11 @@
totalLength += sequenceLength;
totalLength += blk.prependVarNumber(sequenceLength);
totalLength += blk.prependVarNumber(tlv::NdnlpSequence);
-
+
+ // NdnlpData
totalLength += blk.prependVarNumber(totalLength);
totalLength += blk.prependVarNumber(tlv::NdnlpData);
-
+
return totalLength;
}
@@ -74,7 +71,7 @@
ndn::EncodingEstimator estimator;
size_t estimatedSize = Slicer_encodeFragment(estimator,
0, 0, 2, 0, m_mtu);
-
+
size_t overhead = estimatedSize - m_mtu;
m_maxPayload = m_mtu - overhead;
}
@@ -85,7 +82,7 @@
BOOST_ASSERT(block.hasWire());
const uint8_t* networkPacket = block.wire();
size_t networkPacketSize = block.size();
-
+
uint16_t fragCount = static_cast<uint16_t>(
(networkPacketSize / m_maxPayload) +
(networkPacketSize % m_maxPayload == 0 ? 0 : 1)
@@ -93,21 +90,21 @@
PacketArray pa = make_shared<std::vector<Block> >();
pa->reserve(fragCount);
SequenceBlock seqBlock = m_seqgen.nextBlock(fragCount);
-
+
for (uint16_t fragIndex = 0; fragIndex < fragCount; ++fragIndex) {
size_t payloadOffset = fragIndex * m_maxPayload;
const uint8_t* payload = networkPacket + payloadOffset;
size_t payloadSize = std::min(m_maxPayload, networkPacketSize - payloadOffset);
-
+
ndn::EncodingBuffer buffer(m_mtu, 0);
size_t pktSize = Slicer_encodeFragment(buffer,
seqBlock[fragIndex], fragIndex, fragCount, payload, payloadSize);
-
+
BOOST_ASSERT(pktSize <= m_mtu);
-
+
pa->push_back(buffer.block());
}
-
+
return pa;
}
diff --git a/daemon/face/ndnlp-slicer.hpp b/daemon/face/ndnlp-slicer.hpp
index ba04e3c..716cddc 100644
--- a/daemon/face/ndnlp-slicer.hpp
+++ b/daemon/face/ndnlp-slicer.hpp
@@ -22,10 +22,10 @@
public:
explicit
Slicer(size_t mtu);
-
+
virtual
~Slicer();
-
+
PacketArray
slice(const Block& block);
@@ -33,13 +33,13 @@
/// estimate the size of NDNLP header and maximum payload size per packet
void
estimateOverhead();
-
+
private:
SequenceGenerator m_seqgen;
-
+
/// maximum packet size
size_t m_mtu;
-
+
/// maximum payload size
size_t m_maxPayload;
};
diff --git a/daemon/face/ndnlp-tlv.hpp b/daemon/face/ndnlp-tlv.hpp
index fe15e6a..ed97dae 100644
--- a/daemon/face/ndnlp-tlv.hpp
+++ b/daemon/face/ndnlp-tlv.hpp
@@ -10,7 +10,8 @@
namespace nfd {
namespace tlv {
-enum {
+enum
+{
NdnlpData = 80,
NdnlpSequence = 81,
NdnlpFragIndex = 82,