face: EthernetTransport
This commit replaces NDNLPv1 fragmentation and reassembly
with NDNLPv2 fragmentation and reassembly.
Change-Id: I10751157fcced94d441167ce470aaed79c12bb54
Refs: #3170
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 3d88590..3592530 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -24,16 +24,16 @@
*/
#include "ethernet-factory.hpp"
-#include "face/ethernet-face.hpp"
-
-#include "core/logger.hpp"
+#include "ethernet-transport.hpp"
+#include "generic-link-service.hpp"
+#include "lp-face-wrapper.hpp"
#include "core/global-io.hpp"
namespace nfd {
-shared_ptr<EthernetFace>
+shared_ptr<face::LpFaceWrapper>
EthernetFactory::createMulticastFace(const NetworkInterfaceInfo& interface,
- const ethernet::Address &address)
+ const ethernet::Address& address)
{
if (!address.isMulticast())
BOOST_THROW_EXCEPTION(Error(address.toString() + " is not a multicast address"));
@@ -42,8 +42,14 @@
if (face)
return face;
- face = make_shared<EthernetFace>(boost::asio::posix::stream_descriptor(getGlobalIoService()),
- interface, address);
+ face::GenericLinkService::Options opts;
+ opts.allowFragmentation = true;
+ opts.allowReassembly = true;
+
+ auto linkService = make_unique<face::GenericLinkService>(opts);
+ auto transport = make_unique<face::EthernetTransport>(interface, address);
+ auto lpFace = make_unique<face::LpFace>(std::move(linkService), std::move(transport));
+ face = make_shared<face::LpFaceWrapper>(std::move(lpFace));
auto key = std::make_pair(interface.name, address);
face->onFail.connectSingleShot([this, key] (const std::string& reason) {
@@ -69,7 +75,7 @@
return {};
}
-shared_ptr<EthernetFace>
+shared_ptr<face::LpFaceWrapper>
EthernetFactory::findMulticastFace(const std::string& interfaceName,
const ethernet::Address& address) const
{
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index c14e093..c0a951d 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -31,7 +31,9 @@
namespace nfd {
-class EthernetFace;
+namespace face {
+class LpFaceWrapper;
+} // namespace face
class EthernetFactory : public ProtocolFactory
{
@@ -50,7 +52,7 @@
};
typedef std::map<std::pair<std::string, ethernet::Address>,
- shared_ptr<EthernetFace>> MulticastFaceMap;
+ shared_ptr<face::LpFaceWrapper>> MulticastFaceMap;
/**
* \brief Create an EthernetFace to communicate with the given multicast group
@@ -65,9 +67,9 @@
* \returns always a valid shared pointer to an EthernetFace object,
* an exception will be thrown if the creation fails
*
- * \throws EthernetFactory::Error or EthernetFace::Error
+ * \throws EthernetFactory::Error or EthernetTransport::Error
*/
- shared_ptr<EthernetFace>
+ shared_ptr<face::LpFaceWrapper>
createMulticastFace(const NetworkInterfaceInfo& interface,
const ethernet::Address& address);
@@ -94,7 +96,7 @@
* \returns shared pointer to the existing EthernetFace object
* or nullptr when such face does not exist
*/
- shared_ptr<EthernetFace>
+ shared_ptr<face::LpFaceWrapper>
findMulticastFace(const std::string& interfaceName,
const ethernet::Address& address) const;
diff --git a/daemon/face/ethernet-face.cpp b/daemon/face/ethernet-transport.cpp
similarity index 62%
rename from daemon/face/ethernet-face.cpp
rename to daemon/face/ethernet-transport.cpp
index f31a8f6..5318097 100644
--- a/daemon/face/ethernet-face.cpp
+++ b/daemon/face/ethernet-transport.cpp
@@ -23,17 +23,17 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ethernet-face.hpp"
+#include "ethernet-transport.hpp"
#include "core/global-io.hpp"
#include <pcap/pcap.h>
#include <cerrno> // for errno
-#include <cstring> // for std::strerror() and std::strncpy()
-#include <stdio.h> // for snprintf()
+#include <cstring> // for memcpy(), strerror(), strncpy()
#include <arpa/inet.h> // for htons() and ntohs()
#include <net/ethernet.h> // for struct ether_header
#include <net/if.h> // for struct ifreq
+#include <stdio.h> // for snprintf()
#include <sys/ioctl.h> // for ioctl()
#include <unistd.h> // for dup()
@@ -57,28 +57,32 @@
#endif
namespace nfd {
+namespace face {
-NFD_LOG_INIT("EthernetFace");
+NFD_LOG_INIT("EthernetTransport");
-const time::nanoseconds EthernetFace::REASSEMBLER_LIFETIME = time::seconds(60);
-
-EthernetFace::EthernetFace(boost::asio::posix::stream_descriptor socket,
- const NetworkInterfaceInfo& interface,
- const ethernet::Address& address)
- : Face(FaceUri(address), FaceUri::fromDev(interface.name), false, true)
- , m_pcap(nullptr, pcap_close)
- , m_socket(std::move(socket))
+EthernetTransport::EthernetTransport(const NetworkInterfaceInfo& interface,
+ const ethernet::Address& mcastAddress)
+ : m_pcap(nullptr, pcap_close)
+ , m_socket(getGlobalIoService())
+ , m_srcAddress(interface.etherAddress)
+ , m_destAddress(mcastAddress)
+ , m_interfaceName(interface.name)
#if defined(__linux__)
, m_interfaceIndex(interface.index)
#endif
- , m_interfaceName(interface.name)
- , m_srcAddress(interface.etherAddress)
- , m_destAddress(address)
#ifdef _DEBUG
, m_nDropped(0)
#endif
{
- NFD_LOG_FACE_INFO("Creating face on " << m_interfaceName << "/" << m_srcAddress);
+ this->setLocalUri(FaceUri::fromDev(interface.name));
+ this->setRemoteUri(FaceUri(mcastAddress));
+ this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
+ this->setPersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+ this->setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS);
+
+ NFD_LOG_FACE_INFO("Creating transport");
+
pcapInit();
int fd = pcap_get_selectable_fd(m_pcap.get());
@@ -90,10 +94,8 @@
// same fd and one of them will fail
m_socket.assign(::dup(fd));
- m_interfaceMtu = getInterfaceMtu();
- NFD_LOG_FACE_DEBUG("Interface MTU is: " << m_interfaceMtu);
-
- m_slicer.reset(new ndnlp::Slicer(m_interfaceMtu));
+ // do this after assigning m_socket because getInterfaceMtu uses it
+ this->setMtu(getInterfaceMtu());
char filter[100];
// std::snprintf not found in some environments
@@ -105,62 +107,54 @@
m_srcAddress.toString().c_str());
setPacketFilter(filter);
- if (!m_destAddress.isBroadcast() && !joinMulticastGroup())
- {
- NFD_LOG_FACE_WARN("Falling back to promiscuous mode");
- pcap_set_promisc(m_pcap.get(), 1);
- }
+ if (!m_destAddress.isBroadcast() && !joinMulticastGroup()) {
+ NFD_LOG_FACE_WARN("Falling back to promiscuous mode");
+ pcap_set_promisc(m_pcap.get(), 1);
+ }
m_socket.async_read_some(boost::asio::null_buffers(),
- bind(&EthernetFace::handleRead, this,
+ bind(&EthernetTransport::handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
-void
-EthernetFace::sendInterest(const Interest& interest)
+void EthernetTransport::beforeChangePersistency(ndn::nfd::FacePersistency newPersistency)
{
- NFD_LOG_FACE_TRACE(__func__);
-
- this->emitSignal(onSendInterest, interest);
-
- ndnlp::PacketArray pa = m_slicer->slice(interest.wireEncode());
- for (const auto& packet : *pa) {
- sendPacket(packet);
+ if (newPersistency != ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
+ BOOST_THROW_EXCEPTION(
+ std::invalid_argument("EthernetTransport supports only FACE_PERSISTENCY_PERMANENT"));
}
}
-void
-EthernetFace::sendData(const Data& data)
+void EthernetTransport::doSend(Transport::Packet&& packet)
{
NFD_LOG_FACE_TRACE(__func__);
- this->emitSignal(onSendData, data);
-
- ndnlp::PacketArray pa = m_slicer->slice(data.wireEncode());
- for (const auto& packet : *pa) {
- sendPacket(packet);
- }
+ sendPacket(packet.packet);
}
-void
-EthernetFace::close()
+void EthernetTransport::doClose()
{
- if (!m_pcap)
- return;
+ NFD_LOG_FACE_TRACE(__func__);
- NFD_LOG_FACE_INFO("Closing face");
-
- boost::system::error_code error;
- m_socket.cancel(error); // ignore errors
- m_socket.close(error); // ignore errors
+ if (m_socket.is_open()) {
+ // Cancel all outstanding operations and close the socket.
+ // Use the non-throwing variants and ignore errors, if any.
+ boost::system::error_code error;
+ m_socket.cancel(error);
+ m_socket.close(error);
+ }
m_pcap.reset();
- fail("Face closed");
+ // Ensure that the Transport stays alive at least
+ // until all pending handlers are dispatched
+ getGlobalIoService().post([this] {
+ this->setState(TransportState::CLOSED);
+ });
}
void
-EthernetFace::pcapInit()
+EthernetTransport::pcapInit()
{
char errbuf[PCAP_ERRBUF_SIZE] = {};
m_pcap.reset(pcap_create(m_interfaceName.c_str(), errbuf));
@@ -187,7 +181,7 @@
}
void
-EthernetFace::setPacketFilter(const char* filterString)
+EthernetTransport::setPacketFilter(const char* filterString)
{
bpf_program filter;
if (pcap_compile(m_pcap.get(), &filter, filterString, 1, PCAP_NETMASK_UNKNOWN) < 0)
@@ -200,14 +194,14 @@
}
bool
-EthernetFace::joinMulticastGroup()
+EthernetTransport::joinMulticastGroup()
{
#if defined(__linux__)
packet_mreq mr{};
mr.mr_ifindex = m_interfaceIndex;
mr.mr_type = PACKET_MR_MULTICAST;
mr.mr_alen = m_destAddress.size();
- std::copy(m_destAddress.begin(), m_destAddress.end(), mr.mr_address);
+ std::memcpy(mr.mr_address, m_destAddress.data(), m_destAddress.size());
if (::setsockopt(m_socket.native_handle(), SOL_PACKET,
PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == 0)
@@ -223,7 +217,7 @@
#if defined(__APPLE__) || defined(__FreeBSD__)
// see bug #2327
using boost::asio::ip::udp;
- udp::socket sock(ref(getGlobalIoService()), udp::v4());
+ udp::socket sock(getGlobalIoService(), udp::v4());
int fd = sock.native_handle();
/*
@@ -242,7 +236,7 @@
sdl->sdl_len = sizeof(ifr.ifr_addr);
sdl->sdl_family = AF_LINK;
sdl->sdl_alen = m_destAddress.size();
- std::copy(m_destAddress.begin(), m_destAddress.end(), LLADDR(sdl));
+ std::memcpy(LLADDR(sdl), m_destAddress.data(), m_destAddress.size());
static_assert(sizeof(ifr.ifr_addr) >= offsetof(sockaddr_dl, sdl_data) + ethernet::ADDR_LEN,
"ifr_addr in struct ifreq is too small on this platform");
@@ -250,9 +244,9 @@
int fd = m_socket.native_handle();
ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
- std::copy(m_destAddress.begin(), m_destAddress.end(), ifr.ifr_hwaddr.sa_data);
+ std::memcpy(ifr.ifr_hwaddr.sa_data, m_destAddress.data(), m_destAddress.size());
- static_assert(sizeof(ifr.ifr_hwaddr) >= offsetof(sockaddr, sa_data) + ethernet::ADDR_LEN,
+ static_assert(sizeof(ifr.ifr_hwaddr.sa_data) >= ethernet::ADDR_LEN,
"ifr_hwaddr in struct ifreq is too small on this platform");
#endif
@@ -266,26 +260,17 @@
}
void
-EthernetFace::sendPacket(const ndn::Block& block)
+EthernetTransport::sendPacket(const ndn::Block& block)
{
- if (!m_pcap)
- {
- NFD_LOG_FACE_WARN("Trying to send on closed face");
- return fail("Face closed");
- }
-
- BOOST_ASSERT(block.size() <= m_interfaceMtu);
-
/// \todo Right now there is no reserve when packet is received, but
/// we should reserve some space at the beginning and at the end
ndn::EncodingBuffer buffer(block);
// pad with zeroes if the payload is too short
- if (block.size() < ethernet::MIN_DATA_LEN)
- {
- static const uint8_t padding[ethernet::MIN_DATA_LEN] = {};
- buffer.appendByteArray(padding, ethernet::MIN_DATA_LEN - block.size());
- }
+ if (block.size() < ethernet::MIN_DATA_LEN) {
+ static const uint8_t padding[ethernet::MIN_DATA_LEN] = {};
+ buffer.appendByteArray(padding, ethernet::MIN_DATA_LEN - block.size());
+ }
// construct and prepend the ethernet header
static uint16_t ethertype = htons(ethernet::ETHERTYPE_NDN);
@@ -296,66 +281,53 @@
// send the packet
int sent = pcap_inject(m_pcap.get(), buffer.buf(), buffer.size());
if (sent < 0)
- {
- return fail("pcap_inject: " + std::string(pcap_geterr(m_pcap.get())));
- }
+ NFD_LOG_FACE_ERROR("pcap_inject failed: " << pcap_geterr(m_pcap.get()));
else if (static_cast<size_t>(sent) < buffer.size())
- {
- return fail("Failed to inject frame");
- }
-
- NFD_LOG_FACE_TRACE("Successfully sent: " << block.size() << " bytes");
- this->getMutableCounters().getNOutBytes() += block.size();
+ NFD_LOG_FACE_ERROR("Failed to send the full frame: bufsize=" << buffer.size() << " sent=" << sent);
+ else
+ // print block size because we don't want to count the padding in buffer
+ NFD_LOG_FACE_TRACE("Successfully sent: " << block.size() << " bytes");
}
void
-EthernetFace::handleRead(const boost::system::error_code& error, size_t)
+EthernetTransport::handleRead(const boost::system::error_code& error, size_t)
{
- if (!m_pcap)
- return fail("Face closed");
-
if (error)
return processErrorCode(error);
pcap_pkthdr* header;
const uint8_t* packet;
+
+ // read the pcap header and packet data
int ret = pcap_next_ex(m_pcap.get(), &header, &packet);
if (ret < 0)
- {
- return fail("pcap_next_ex: " + std::string(pcap_geterr(m_pcap.get())));
- }
+ NFD_LOG_FACE_ERROR("pcap_next_ex failed: " << pcap_geterr(m_pcap.get()));
else if (ret == 0)
- {
- NFD_LOG_FACE_WARN("Read timeout");
- }
+ NFD_LOG_FACE_WARN("Read timeout");
else
- {
- processIncomingPacket(header, packet);
- }
+ processIncomingPacket(header, packet);
#ifdef _DEBUG
pcap_stat ps{};
ret = pcap_stats(m_pcap.get(), &ps);
- if (ret < 0)
- {
- NFD_LOG_FACE_DEBUG("pcap_stats failed: " << pcap_geterr(m_pcap.get()));
- }
- else if (ret == 0)
- {
- if (ps.ps_drop - m_nDropped > 0)
- NFD_LOG_FACE_DEBUG("Detected " << ps.ps_drop - m_nDropped << " dropped packet(s)");
- m_nDropped = ps.ps_drop;
- }
+ if (ret < 0) {
+ NFD_LOG_FACE_DEBUG("pcap_stats failed: " << pcap_geterr(m_pcap.get()));
+ }
+ else if (ret == 0) {
+ if (ps.ps_drop - m_nDropped > 0)
+ NFD_LOG_FACE_DEBUG("Detected " << ps.ps_drop - m_nDropped << " dropped packet(s)");
+ m_nDropped = ps.ps_drop;
+ }
#endif
m_socket.async_read_some(boost::asio::null_buffers(),
- bind(&EthernetFace::handleRead, this,
+ bind(&EthernetTransport::handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void
-EthernetFace::processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet)
+EthernetTransport::processIncomingPacket(const pcap_pkthdr* header, const uint8_t* packet)
{
size_t length = header->caplen;
if (length < ethernet::HDR_LEN + ethernet::MIN_DATA_LEN) {
@@ -377,77 +349,46 @@
packet += ethernet::HDR_LEN;
length -= ethernet::HDR_LEN;
- /// \todo Reserve space in front and at the back of the underlying buffer
bool isOk = false;
- Block fragmentBlock;
- std::tie(isOk, fragmentBlock) = Block::fromBuffer(packet, length);
+ Block element;
+ std::tie(isOk, element) = Block::fromBuffer(packet, length);
if (!isOk) {
- NFD_LOG_FACE_WARN("Block received from " << sourceAddress.toString()
- << " is invalid or too large to process");
+ NFD_LOG_FACE_WARN("Received invalid packet from " << sourceAddress.toString());
return;
}
- NFD_LOG_FACE_TRACE("Received: " << fragmentBlock.size() << " bytes from "
- << sourceAddress.toString());
- this->getMutableCounters().getNInBytes() += fragmentBlock.size();
+ NFD_LOG_FACE_TRACE("Received: " << element.size() << " bytes from " << sourceAddress.toString());
- Reassembler& reassembler = m_reassemblers[sourceAddress];
- if (!reassembler.pms) {
- // new sender, setup a PartialMessageStore for it
- reassembler.pms.reset(new ndnlp::PartialMessageStore);
- reassembler.pms->onReceive.connect(
- [this, sourceAddress] (const Block& block) {
- NFD_LOG_FACE_TRACE("All fragments received from " << sourceAddress.toString());
- if (!decodeAndDispatchInput(block))
- NFD_LOG_FACE_WARN("Received unrecognized TLV block of type " << block.type()
- << " from " << sourceAddress.toString());
- });
- }
-
- scheduler::cancel(reassembler.expireEvent);
- reassembler.expireEvent = scheduler::schedule(REASSEMBLER_LIFETIME,
- [this, sourceAddress] {
- BOOST_VERIFY(m_reassemblers.erase(sourceAddress) == 1);
- });
-
- ndnlp::NdnlpData fragment;
- std::tie(isOk, fragment) = ndnlp::NdnlpData::fromBlock(fragmentBlock);
- if (!isOk) {
- NFD_LOG_FACE_WARN("Received invalid NDNLP fragment from " << sourceAddress.toString());
- return;
- }
-
- reassembler.pms->receive(fragment);
+ Transport::Packet tp(std::move(element));
+ static_assert(sizeof(tp.remoteEndpoint) >= ethernet::ADDR_LEN,
+ "Transport::Packet::remoteEndpoint is too small");
+ std::memcpy(&tp.remoteEndpoint, sourceAddress.data(), sourceAddress.size());
+ this->receive(std::move(tp));
}
void
-EthernetFace::processErrorCode(const boost::system::error_code& error)
+EthernetTransport::processErrorCode(const boost::system::error_code& error)
{
- if (error == boost::asio::error::operation_aborted)
- // cancel() has been called on the socket
+ NFD_LOG_FACE_TRACE(__func__);
+
+ if (getState() == TransportState::CLOSING ||
+ getState() == TransportState::FAILED ||
+ getState() == TransportState::CLOSED ||
+ error == boost::asio::error::operation_aborted)
+ // transport is shutting down, ignore any errors
return;
- std::string msg;
- if (error == boost::asio::error::eof)
- {
- msg = "Face closed";
- }
- else
- {
- msg = "Receive operation failed: " + error.message();
- NFD_LOG_FACE_WARN(msg);
- }
- fail(msg);
+ NFD_LOG_FACE_WARN("Receive operation failed: " << error.message());
}
size_t
-EthernetFace::getInterfaceMtu()
+EthernetTransport::getInterfaceMtu()
{
#ifdef SIOCGIFMTU
#if defined(__APPLE__) || defined(__FreeBSD__)
// see bug #2328
using boost::asio::ip::udp;
- udp::socket sock(ref(getGlobalIoService()), udp::v4());
+ udp::socket sock(getGlobalIoService(), udp::v4());
int fd = sock.native_handle();
#else
int fd = m_socket.native_handle();
@@ -456,13 +397,17 @@
ifreq ifr{};
std::strncpy(ifr.ifr_name, m_interfaceName.c_str(), sizeof(ifr.ifr_name) - 1);
- if (::ioctl(fd, SIOCGIFMTU, &ifr) == 0)
+ if (::ioctl(fd, SIOCGIFMTU, &ifr) == 0) {
+ NFD_LOG_FACE_DEBUG("Interface MTU is " << ifr.ifr_mtu);
return static_cast<size_t>(ifr.ifr_mtu);
+ }
NFD_LOG_FACE_WARN("Failed to get interface MTU: " << std::strerror(errno));
#endif
+ NFD_LOG_FACE_DEBUG("Assuming default MTU of " << ethernet::MAX_DATA_LEN);
return ethernet::MAX_DATA_LEN;
}
+} // namespace face
} // namespace nfd
diff --git a/daemon/face/ethernet-face.hpp b/daemon/face/ethernet-transport.hpp
similarity index 71%
rename from daemon/face/ethernet-face.hpp
rename to daemon/face/ethernet-transport.hpp
index 2bbd781..1d41008 100644
--- a/daemon/face/ethernet-face.hpp
+++ b/daemon/face/ethernet-transport.hpp
@@ -23,17 +23,13 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NFD_DAEMON_FACE_ETHERNET_FACE_HPP
-#define NFD_DAEMON_FACE_ETHERNET_FACE_HPP
+#ifndef NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
+#define NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
#include "common.hpp"
-#include "face.hpp"
-#include "ndnlp-partial-message-store.hpp"
-#include "ndnlp-slicer.hpp"
+#include "transport.hpp"
#include "core/network-interface.hpp"
-#include <unordered_map>
-
#ifndef HAVE_LIBPCAP
#error "Cannot include this file when libpcap is not available"
#endif
@@ -44,43 +40,41 @@
struct pcap_pkthdr;
namespace nfd {
+namespace face {
/**
- * @brief Implementation of Face abstraction that uses raw
- * Ethernet frames as underlying transport mechanism
+ * \brief A multicast Transport that uses raw Ethernet II frames
*/
-class EthernetFace : public Face
+class EthernetTransport DECL_CLASS_FINAL : public Transport
{
public:
- /**
- * @brief EthernetFace-related error
- */
- struct Error : public Face::Error
+ class Error : public std::runtime_error
{
- Error(const std::string& what) : Face::Error(what) {}
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
};
- EthernetFace(boost::asio::posix::stream_descriptor socket,
- const NetworkInterfaceInfo& interface,
- const ethernet::Address& address);
-
- /// send an Interest
- void
- sendInterest(const Interest& interest) DECL_OVERRIDE;
-
- /// send a Data
- void
- sendData(const Data& data) DECL_OVERRIDE;
-
/**
- * @brief Closes the face
- *
- * This terminates all communication on the face and triggers the onFail() event.
+ * @brief Creates an Ethernet-based transport for multicast communication
*/
- void
- close() DECL_OVERRIDE;
+ EthernetTransport(const NetworkInterfaceInfo& interface,
+ const ethernet::Address& mcastAddress);
+
+protected:
+ virtual void
+ beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) DECL_FINAL;
+
+ virtual void
+ doClose() DECL_FINAL;
private:
+ virtual void
+ doSend(Transport::Packet&& packet) DECL_FINAL;
+
/**
* @brief Allocates and initializes a libpcap context for live capture
*/
@@ -139,26 +133,15 @@
getInterfaceMtu();
private:
- struct Reassembler
- {
- unique_ptr<ndnlp::PartialMessageStore> pms;
- scheduler::EventId expireEvent;
- };
-
unique_ptr<pcap_t, void(*)(pcap_t*)> m_pcap;
boost::asio::posix::stream_descriptor m_socket;
+ ethernet::Address m_srcAddress;
+ ethernet::Address m_destAddress;
+ std::string m_interfaceName;
#if defined(__linux__)
int m_interfaceIndex;
#endif
- std::string m_interfaceName;
- ethernet::Address m_srcAddress;
- ethernet::Address m_destAddress;
-
- size_t m_interfaceMtu;
- unique_ptr<ndnlp::Slicer> m_slicer;
- std::unordered_map<ethernet::Address, Reassembler> m_reassemblers;
- static const time::nanoseconds REASSEMBLER_LIFETIME;
#ifdef _DEBUG
/// number of packets dropped by the kernel, as reported by libpcap
@@ -166,6 +149,7 @@
#endif
};
+} // namespace face
} // namespace nfd
-#endif // NFD_DAEMON_FACE_ETHERNET_FACE_HPP
+#endif // NFD_DAEMON_FACE_ETHERNET_TRANSPORT_HPP
diff --git a/daemon/face/ndnlp-data.cpp b/daemon/face/ndnlp-data.cpp
deleted file mode 100644
index 7cfacac..0000000
--- a/daemon/face/ndnlp-data.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ndnlp-data.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-std::tuple<bool, NdnlpData>
-NdnlpData::fromBlock(const Block& wire)
-{
- if (wire.type() != tlv::NdnlpData) {
- // top element is not NdnlpData
- return std::make_tuple(false, NdnlpData());
- }
- wire.parse();
- const Block::element_container& elements = wire.elements();
- if (elements.size() < 2) {
- // NdnlpData element has incorrect number of children
- return std::make_tuple(false, NdnlpData());
- }
-
- NdnlpData parsed;
-
- const Block& sequenceElement = elements.front();
- if (sequenceElement.type() != tlv::NdnlpSequence) {
- // NdnlpSequence element is missing
- return std::make_tuple(false, NdnlpData());
- }
- if (sequenceElement.value_size() != sizeof(uint64_t)) {
- // NdnlpSequence element has incorrect length
- return std::make_tuple(false, NdnlpData());
- }
- parsed.seq = be64toh(*reinterpret_cast<const uint64_t*>(&*sequenceElement.value_begin()));
-
- const Block& payloadElement = elements.back();
- if (payloadElement.type() != tlv::NdnlpPayload) {
- // NdnlpPayload element is missing
- return std::make_tuple(false, NdnlpData());
- }
- parsed.payload = payloadElement;
-
- if (elements.size() == 2) { // single wire packet
- parsed.fragIndex = 0;
- parsed.fragCount = 1;
- return std::make_tuple(true, parsed);
- }
- if (elements.size() != 4) {
- // NdnlpData element has incorrect number of children
- return std::make_tuple(false, NdnlpData());
- }
-
- const Block& fragIndexElement = elements.at(1);
- if (fragIndexElement.type() != tlv::NdnlpFragIndex) {
- // NdnlpFragIndex element is missing
- return std::make_tuple(false, NdnlpData());
- }
- uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
- if (fragIndex > std::numeric_limits<uint16_t>::max()) {
- // NdnlpFragIndex is too large
- return std::make_tuple(false, NdnlpData());
- }
- parsed.fragIndex = static_cast<uint16_t>(fragIndex);
-
- const Block& fragCountElement = elements.at(2);
- if (fragCountElement.type() != tlv::NdnlpFragCount) {
- // NdnlpFragCount element is missing
- return std::make_tuple(false, NdnlpData());
- }
- uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
- if (fragCount > std::numeric_limits<uint16_t>::max()) {
- // NdnlpFragCount is too large
- return std::make_tuple(false, NdnlpData());
- }
- parsed.fragCount = static_cast<uint16_t>(fragCount);
-
- if (parsed.fragIndex >= parsed.fragCount) {
- // NdnlpFragIndex must be less than NdnlpFragCount
- return std::make_tuple(false, NdnlpData());
- }
-
- return std::make_tuple(true, parsed);
-}
-
-} // namespace ndnlp
-} // namespace nfd
diff --git a/daemon/face/ndnlp-data.hpp b/daemon/face/ndnlp-data.hpp
deleted file mode 100644
index fd921e2..0000000
--- a/daemon/face/ndnlp-data.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_NDNLP_PARSE_HPP
-#define NFD_DAEMON_FACE_NDNLP_PARSE_HPP
-
-#include "common.hpp"
-#include "ndnlp-tlv.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-/** \brief represents a NdnlpData packet
- *
- * NdnlpData ::= NDNLP-DATA-TYPE TLV-LENGTH
- * NdnlpSequence
- * NdnlpFragIndex?
- * NdnlpFragCount?
- * NdnlpPayload
- */
-class NdnlpData
-{
-public:
- /** \brief parse a NdnlpData packet
- * \return whether \p wire has a valid NdnlpData packet, and the parsed packet
- */
- static std::tuple<bool, NdnlpData>
- fromBlock(const Block& wire);
-
-public:
- uint64_t seq;
- uint16_t fragIndex;
- uint16_t fragCount;
- Block payload;
-};
-
-} // namespace ndnlp
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_NDNLP_PARSE_HPP
diff --git a/daemon/face/ndnlp-partial-message-store.cpp b/daemon/face/ndnlp-partial-message-store.cpp
deleted file mode 100644
index 252e77d..0000000
--- a/daemon/face/ndnlp-partial-message-store.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ndnlp-partial-message-store.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-NFD_LOG_INIT("NdnlpPartialMessageStore");
-
-PartialMessage::PartialMessage()
- : m_fragCount(0)
- , m_received(0)
- , m_totalLength(0)
-{
-}
-
-bool
-PartialMessage::add(uint16_t fragIndex, uint16_t fragCount, const Block& payload)
-{
- if (m_received == 0) { // first packet
- 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();
- return true;
-}
-
-bool
-PartialMessage::isComplete() const
-{
- return m_received == m_fragCount;
-}
-
-std::tuple<bool, Block>
-PartialMessage::reassemble()
-{
- BOOST_ASSERT(this->isComplete());
-
- ndn::BufferPtr buffer = make_shared<ndn::Buffer>(m_totalLength);
- ndn::Buffer::iterator buf = buffer->begin();
- for (const Block& payload : m_payloads) {
- buf = std::copy(payload.value_begin(), payload.value_end(), buf);
- }
- BOOST_ASSERT(buf == buffer->end());
-
- return Block::fromBuffer(buffer, 0);
-}
-
-std::tuple<bool, Block>
-PartialMessage::reassembleSingle(const NdnlpData& fragment)
-{
- BOOST_ASSERT(fragment.fragCount == 1);
-
- try {
- return std::make_tuple(true, fragment.payload.blockFromValue());
- }
- catch (tlv::Error&) {
- return std::make_tuple(false, Block());
- }
-}
-
-PartialMessageStore::PartialMessageStore(const time::nanoseconds& idleDuration)
- : m_idleDuration(idleDuration)
-{
-}
-
-void
-PartialMessageStore::receive(const NdnlpData& pkt)
-{
- bool isReassembled = false;
- Block reassembled;
-
- if (pkt.fragCount == 1) { // single fragment
- std::tie(isReassembled, reassembled) = PartialMessage::reassembleSingle(pkt);
- }
- else {
- uint64_t messageIdentifier = pkt.seq - pkt.fragIndex;
- PartialMessage& pm = m_partialMessages[messageIdentifier];
- this->scheduleCleanup(messageIdentifier, pm);
-
- pm.add(pkt.fragIndex, pkt.fragCount, pkt.payload);
-
- if (pm.isComplete()) {
- std::tie(isReassembled, reassembled) = pm.reassemble();
- m_partialMessages.erase(messageIdentifier);
- }
- else {
- return;
- }
- }
-
- if (!isReassembled) {
- NFD_LOG_TRACE(pkt.seq << " reassemble error");
- return;
- }
-
- NFD_LOG_TRACE(pkt.seq << " deliver");
- this->onReceive(reassembled);
-}
-
-void
-PartialMessageStore::scheduleCleanup(uint64_t messageIdentifier,
- PartialMessage& partialMessage)
-{
- partialMessage.expiry = scheduler::schedule(m_idleDuration,
- bind(&PartialMessageStore::cleanup, this, messageIdentifier));
-}
-
-void
-PartialMessageStore::cleanup(uint64_t messageIdentifier)
-{
- NFD_LOG_TRACE(messageIdentifier << " cleanup");
- m_partialMessages.erase(messageIdentifier);
-}
-
-} // namespace ndnlp
-} // namespace nfd
diff --git a/daemon/face/ndnlp-partial-message-store.hpp b/daemon/face/ndnlp-partial-message-store.hpp
deleted file mode 100644
index 25afcd8..0000000
--- a/daemon/face/ndnlp-partial-message-store.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_NDNLP_PARTIAL_MESSAGE_STORE_HPP
-#define NFD_DAEMON_FACE_NDNLP_PARTIAL_MESSAGE_STORE_HPP
-
-#include "ndnlp-data.hpp"
-#include "core/scheduler.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-/** \brief represents a partially received message
- */
-class PartialMessage
-{
-public:
- PartialMessage();
-
- PartialMessage(const PartialMessage&) = delete;
-
- PartialMessage&
- operator=(const PartialMessage&) = delete;
-
- PartialMessage(PartialMessage&&) = default;
-
- PartialMessage&
- operator=(PartialMessage&&) = default;
-
- bool
- add(uint16_t fragIndex, uint16_t fragCount, const Block& payload);
-
- bool
- isComplete() const;
-
- /** \brief reassemble network layer packet
- * \pre isComplete() == true
- * \return whether success, network layer packet
- */
- std::tuple<bool, Block>
- reassemble();
-
- /** \brief reassemble network layer packet from a single fragment
- * \pre fragment.fragCount == 1
- * \return whether success, network layer packet
- */
- static std::tuple<bool, Block>
- reassembleSingle(const NdnlpData& fragment);
-
-public:
- scheduler::ScopedEventId expiry;
-
-private:
- size_t m_fragCount;
- size_t m_received;
- std::vector<Block> m_payloads;
- size_t m_totalLength;
-};
-
-/** \brief provides reassembly feature at receiver
- */
-class PartialMessageStore : noncopyable
-{
-public:
- explicit
- PartialMessageStore(const time::nanoseconds& idleDuration = time::milliseconds(100));
-
- /** \brief receive a NdnlpData packet
- *
- * Reassembly errors will be ignored.
- */
- void
- receive(const NdnlpData& pkt);
-
- /** \brief fires when network layer packet is received
- */
- signal::Signal<PartialMessageStore, Block> onReceive;
-
-private:
- void
- scheduleCleanup(uint64_t messageIdentifier, PartialMessage& partialMessage);
-
- void
- cleanup(uint64_t messageIdentifier);
-
-private:
- std::unordered_map<uint64_t, PartialMessage> m_partialMessages;
-
- time::nanoseconds m_idleDuration;
-};
-
-} // namespace ndnlp
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_NDNLP_PARTIAL_MESSAGE_STORE_HPP
diff --git a/daemon/face/ndnlp-sequence-generator.cpp b/daemon/face/ndnlp-sequence-generator.cpp
deleted file mode 100644
index 842a319..0000000
--- a/daemon/face/ndnlp-sequence-generator.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "ndnlp-sequence-generator.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-SequenceBlock::SequenceBlock(uint64_t start, size_t count)
- : m_start(start)
- , m_count(count)
-{
-}
-
-SequenceGenerator::SequenceGenerator()
- : m_next(0)
-{
-}
-
-SequenceBlock
-SequenceGenerator::nextBlock(size_t count)
-{
- SequenceBlock sb(m_next, count);
- m_next += count;
- return sb;
-}
-
-} // namespace ndnlp
-} // namespace nfd
diff --git a/daemon/face/ndnlp-sequence-generator.hpp b/daemon/face/ndnlp-sequence-generator.hpp
deleted file mode 100644
index 3019933..0000000
--- a/daemon/face/ndnlp-sequence-generator.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_FACE_NDNLP_SEQUENCE_GENERATOR_HPP
-#define NFD_DAEMON_FACE_NDNLP_SEQUENCE_GENERATOR_HPP
-
-#include "common.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-/** \brief represents a block of sequence numbers
- */
-class SequenceBlock
-{
-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;
-};
-
-inline uint64_t
-SequenceBlock::operator[](size_t pos) const
-{
- if (pos >= m_count)
- BOOST_THROW_EXCEPTION(std::out_of_range("pos"));
- return m_start + static_cast<uint64_t>(pos);
-}
-
-inline size_t
-SequenceBlock::count() const
-{
- return m_count;
-}
-
-/** \class SequenceGenerator
- * \brief generates sequence numbers
- */
-class SequenceGenerator : noncopyable
-{
-public:
- SequenceGenerator();
-
- /** \brief generates a block of consecutive sequence numbers
- *
- * This block must not overlap with a recent block.
- */
- SequenceBlock
- nextBlock(size_t count);
-
-private:
- /// next sequence number
- uint64_t m_next;
-};
-
-} // namespace ndnlp
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_NDNLP_SEQUENCE_GENERATOR_HPP
diff --git a/daemon/face/ndnlp-slicer.cpp b/daemon/face/ndnlp-slicer.cpp
deleted file mode 100644
index 03b1454..0000000
--- a/daemon/face/ndnlp-slicer.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ndnlp-slicer.hpp"
-
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-
-namespace nfd {
-namespace ndnlp {
-
-Slicer::Slicer(size_t mtu)
- : m_mtu(mtu)
-{
- this->estimateOverhead();
-}
-
-Slicer::~Slicer()
-{
-}
-
-template<bool T>
-size_t
-Slicer::encodeFragment(ndn::EncodingImpl<T>& blk,
- uint64_t seq, uint16_t fragIndex, uint16_t fragCount,
- 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
- size_t fragCountLength = blk.prependNonNegativeInteger(fragCount);
- totalLength += fragCountLength;
- totalLength += blk.prependVarNumber(fragCountLength);
- totalLength += blk.prependVarNumber(tlv::NdnlpFragCount);
-
- // NdnlpFragIndex
- 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(
- reinterpret_cast<uint8_t*>(&sequenceBE), sizeof(sequenceBE));
- totalLength += sequenceLength;
- totalLength += blk.prependVarNumber(sequenceLength);
- totalLength += blk.prependVarNumber(tlv::NdnlpSequence);
-
- // NdnlpData
- totalLength += blk.prependVarNumber(totalLength);
- totalLength += blk.prependVarNumber(tlv::NdnlpData);
-
- return totalLength;
-}
-
-void
-Slicer::estimateOverhead()
-{
- // estimate fragment size with all header fields at largest possible size
- ndn::EncodingEstimator estimator;
- size_t estimatedSize = this->encodeFragment(estimator,
- std::numeric_limits<uint64_t>::max(),
- std::numeric_limits<uint16_t>::max() - 1,
- std::numeric_limits<uint16_t>::max(),
- nullptr, m_mtu);
-
- size_t overhead = estimatedSize - m_mtu; // minus payload length in estimation
- m_maxPayload = m_mtu - overhead;
-}
-
-PacketArray
-Slicer::slice(const Block& block)
-{
- 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)
- );
- 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 = this->encodeFragment(buffer,
- seqBlock[fragIndex], fragIndex, fragCount, payload, payloadSize);
-
- BOOST_VERIFY(pktSize <= m_mtu);
-
- pa->push_back(buffer.block());
- }
-
- return pa;
-}
-
-} // namespace ndnlp
-} // namespace nfd
diff --git a/daemon/face/ndnlp-slicer.hpp b/daemon/face/ndnlp-slicer.hpp
deleted file mode 100644
index 1e2985a..0000000
--- a/daemon/face/ndnlp-slicer.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_NDNLP_SLICER_HPP
-#define NFD_DAEMON_FACE_NDNLP_SLICER_HPP
-
-#include "ndnlp-tlv.hpp"
-#include "ndnlp-sequence-generator.hpp"
-
-namespace nfd {
-namespace ndnlp {
-
-typedef shared_ptr<std::vector<Block>> PacketArray;
-
-/** \brief provides fragmentation feature at sender
- */
-class Slicer : noncopyable
-{
-public:
- /** \param mtu maximum size of NDNLP header and payload
- * \note If NDNLP packets are to be encapsulated in an additional header
- * (eg. in UDP packets), the caller must deduct such overhead.
- */
- explicit
- Slicer(size_t mtu);
-
- virtual
- ~Slicer();
-
- PacketArray
- slice(const Block& block);
-
-private:
- template<bool T>
- size_t
- encodeFragment(ndn::EncodingImpl<T>& blk,
- uint64_t seq, uint16_t fragIndex, uint16_t fragCount,
- const uint8_t* payload, size_t payloadSize);
-
- /// 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;
-};
-
-} // namespace ndnlp
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_NDNLP_SLICER_HPP
diff --git a/daemon/face/ndnlp-tlv.hpp b/daemon/face/ndnlp-tlv.hpp
deleted file mode 100644
index 0c41f52..0000000
--- a/daemon/face/ndnlp-tlv.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_FACE_NDNLP_TLV_HPP
-#define NFD_DAEMON_FACE_NDNLP_TLV_HPP
-
-namespace nfd {
-namespace tlv {
-
-enum
-{
- NdnlpData = 80,
- NdnlpSequence = 81,
- NdnlpFragIndex = 82,
- NdnlpFragCount = 83,
- NdnlpPayload = 84
-};
-
-} // namespace tlv
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_NDNLP_TLV_HPP