face: eliminate Transport::Packet wrapper type

Refs: #4843
Change-Id: I5977be55e8bdac33c989e3b8523fea764f304c37
diff --git a/daemon/face/datagram-transport.hpp b/daemon/face/datagram-transport.hpp
index fcde63b..dfe8bee 100644
--- a/daemon/face/datagram-transport.hpp
+++ b/daemon/face/datagram-transport.hpp
@@ -69,7 +69,7 @@
   doClose() override;
 
   void
-  doSend(Transport::Packet&& packet) override;
+  doSend(const Block& packet, const EndpointId& endpoint) override;
 
   void
   handleSend(const boost::system::error_code& error, size_t nBytesSent);
@@ -157,13 +157,13 @@
 
 template<class T, class U>
 void
-DatagramTransport<T, U>::doSend(Transport::Packet&& packet)
+DatagramTransport<T, U>::doSend(const Block& packet, const EndpointId&)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
-  m_socket.async_send(boost::asio::buffer(packet.packet),
-                      // packet.packet is copied into the lambda to retain the underlying Buffer
-                      [this, p = packet.packet] (auto&&... args) {
+  m_socket.async_send(boost::asio::buffer(packet),
+                      // 'packet' is copied into the lambda to retain the underlying Buffer
+                      [this, packet] (auto&&... args) {
                         this->handleSend(std::forward<decltype(args)>(args)...);
                       });
 }
@@ -193,9 +193,7 @@
   }
   m_hasRecentlyReceived = true;
 
-  Transport::Packet tp(std::move(element));
-  tp.remoteEndpoint = makeEndpointId(m_sender);
-  this->receive(std::move(tp));
+  this->receive(element, makeEndpointId(m_sender));
 }
 
 template<class T, class U>
diff --git a/daemon/face/ethernet-transport.cpp b/daemon/face/ethernet-transport.cpp
index a2f3e9b..6b419bf 100644
--- a/daemon/face/ethernet-transport.cpp
+++ b/daemon/face/ethernet-transport.cpp
@@ -102,11 +102,11 @@
 }
 
 void
-EthernetTransport::doSend(Transport::Packet&& packet)
+EthernetTransport::doSend(const Block& packet, const EndpointId&)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
-  sendPacket(packet.packet);
+  sendPacket(packet);
 }
 
 void
@@ -209,13 +209,13 @@
   }
   m_hasRecentlyReceived = true;
 
-  Transport::Packet tp(std::move(element));
-  static_assert(sizeof(tp.remoteEndpoint) >= ethernet::ADDR_LEN,
-                "Transport::Packet::remoteEndpoint is too small");
+  static_assert(sizeof(EndpointId) >= ethernet::ADDR_LEN, "EndpointId is too small");
+  EndpointId endpoint = 0;
   if (m_destAddress.isMulticast()) {
-    std::memcpy(&tp.remoteEndpoint, sender.data(), sender.size());
+    std::memcpy(&endpoint, sender.data(), sender.size());
   }
-  this->receive(std::move(tp));
+
+  this->receive(element, endpoint);
 }
 
 void
diff --git a/daemon/face/ethernet-transport.hpp b/daemon/face/ethernet-transport.hpp
index 798b937..8258285 100644
--- a/daemon/face/ethernet-transport.hpp
+++ b/daemon/face/ethernet-transport.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,6 +29,7 @@
 #include "ethernet-protocol.hpp"
 #include "pcap-helper.hpp"
 #include "transport.hpp"
+
 #include <ndn-cxx/net/network-interface.hpp>
 
 namespace nfd {
@@ -43,11 +44,7 @@
   class Error : public std::runtime_error
   {
   public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
+    using std::runtime_error::runtime_error;
   };
 
   /**
@@ -84,7 +81,7 @@
   handleNetifStateChange(ndn::net::InterfaceState netifState);
 
   void
-  doSend(Transport::Packet&& packet) final;
+  doSend(const Block& packet, const EndpointId& endpoint) final;
 
   /**
    * @brief Sends the specified TLV block on the network wrapped in an Ethernet frame
diff --git a/daemon/face/face-endpoint.hpp b/daemon/face/face-endpoint.hpp
index cf2c466..4d33634 100644
--- a/daemon/face/face-endpoint.hpp
+++ b/daemon/face/face-endpoint.hpp
@@ -30,7 +30,8 @@
 
 namespace nfd {
 
-/** \brief Represents a face-endpoint pair in the forwarder
+/** \brief Represents a face-endpoint pair in the forwarder.
+ *  \sa face::Face, face::EndpointId
  */
 class FaceEndpoint
 {
@@ -49,7 +50,7 @@
 inline std::ostream&
 operator<<(std::ostream& os, const FaceEndpoint& fe)
 {
-  return os << "(" << fe.face.getId() << "," << fe.endpoint << ")";
+  return os << '(' << fe.face.getId() << ',' << fe.endpoint << ')';
 }
 
 } // namespace nfd
diff --git a/daemon/face/generic-link-service.cpp b/daemon/face/generic-link-service.cpp
index 09b874c..5a3664c 100644
--- a/daemon/face/generic-link-service.cpp
+++ b/daemon/face/generic-link-service.cpp
@@ -85,13 +85,13 @@
     checkCongestionLevel(pkt);
   }
 
-  Transport::Packet tp(pkt.wireEncode());
-  if (mtu != MTU_UNLIMITED && tp.packet.size() > static_cast<size_t>(mtu)) {
+  auto block = pkt.wireEncode();
+  if (mtu != MTU_UNLIMITED && block.size() > static_cast<size_t>(mtu)) {
     ++this->nOutOverMtu;
     NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
     return;
   }
-  this->sendPacket(std::move(tp), endpointId);
+  this->sendPacket(block, endpointId);
 }
 
 void
@@ -276,10 +276,10 @@
 }
 
 void
-GenericLinkService::doReceivePacket(Transport::Packet&& packet)
+GenericLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
 {
   try {
-    lp::Packet pkt(packet.packet);
+    lp::Packet pkt(packet);
 
     if (m_options.reliabilityOptions.isEnabled) {
       m_reliability.processIncomingPacket(pkt);
@@ -299,10 +299,9 @@
     bool isReassembled = false;
     Block netPkt;
     lp::Packet firstPkt;
-    std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(packet.remoteEndpoint,
-                                                                              pkt);
+    std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(endpoint, pkt);
     if (isReassembled) {
-      this->decodeNetPacket(netPkt, firstPkt, packet.remoteEndpoint);
+      this->decodeNetPacket(netPkt, firstPkt, endpoint);
     }
   }
   catch (const tlv::Error& e) {
diff --git a/daemon/face/generic-link-service.hpp b/daemon/face/generic-link-service.hpp
index c28b9ef..fe8e962 100644
--- a/daemon/face/generic-link-service.hpp
+++ b/daemon/face/generic-link-service.hpp
@@ -232,7 +232,7 @@
   /** \brief receive Packet from Transport
    */
   void
-  doReceivePacket(Transport::Packet&& packet) OVERRIDE_WITH_TESTS_ELSE_FINAL;
+  doReceivePacket(const Block& packet, const EndpointId& endpoint) OVERRIDE_WITH_TESTS_ELSE_FINAL;
 
   /** \brief decode incoming network-layer packet
    *  \param netPkt reassembled network-layer packet
diff --git a/daemon/face/internal-transport.cpp b/daemon/face/internal-transport.cpp
index 18bfe0a..e5d598a 100644
--- a/daemon/face/internal-transport.cpp
+++ b/daemon/face/internal-transport.cpp
@@ -46,21 +46,21 @@
 }
 
 void
-InternalForwarderTransport::receivePacket(Block&& packet)
+InternalForwarderTransport::receivePacket(const Block& packet)
 {
-  getGlobalIoService().post([this, pkt = std::move(packet)] () mutable {
-    NFD_LOG_FACE_TRACE("Received: " << pkt.size() << " bytes");
-    receive(Packet{std::move(pkt)});
+  getGlobalIoService().post([this, packet] {
+    NFD_LOG_FACE_TRACE("Received: " << packet.size() << " bytes");
+    receive(packet);
   });
 }
 
 void
-InternalForwarderTransport::doSend(Packet&& packet)
+InternalForwarderTransport::doSend(const Block& packet, const EndpointId&)
 {
   NFD_LOG_FACE_TRACE("Sending to " << m_peer);
 
   if (m_peer)
-    m_peer->receivePacket(std::move(packet.packet));
+    m_peer->receivePacket(packet);
 }
 
 void
@@ -104,12 +104,12 @@
 }
 
 void
-InternalClientTransport::receivePacket(Block&& packet)
+InternalClientTransport::receivePacket(const Block& packet)
 {
-  getGlobalIoService().post([this, pkt = std::move(packet)] {
-    NFD_LOG_TRACE("Received: " << pkt.size() << " bytes");
+  getGlobalIoService().post([this, packet] {
+    NFD_LOG_TRACE("Received: " << packet.size() << " bytes");
     if (m_receiveCallback) {
-      m_receiveCallback(pkt);
+      m_receiveCallback(packet);
     }
   });
 }
@@ -120,7 +120,7 @@
   NFD_LOG_TRACE("Sending to " << m_forwarder);
 
   if (m_forwarder)
-    m_forwarder->receivePacket(Block{wire});
+    m_forwarder->receivePacket(wire);
 }
 
 void
diff --git a/daemon/face/internal-transport.hpp b/daemon/face/internal-transport.hpp
index f859099..71ae4d5 100644
--- a/daemon/face/internal-transport.hpp
+++ b/daemon/face/internal-transport.hpp
@@ -42,7 +42,7 @@
   ~InternalTransportBase() = default;
 
   virtual void
-  receivePacket(Block&& packet) = 0;
+  receivePacket(const Block& packet) = 0;
 };
 
 /** \brief Implements a forwarder-side transport that can be paired with another transport.
@@ -63,7 +63,7 @@
   }
 
   void
-  receivePacket(Block&& packet) final;
+  receivePacket(const Block& packet) final;
 
 protected:
   void
@@ -71,7 +71,7 @@
 
 private:
   void
-  doSend(Packet&& packet) final;
+  doSend(const Block& packet, const EndpointId& endpoint) final;
 
 private:
   NFD_LOG_MEMBER_DECL();
@@ -98,7 +98,7 @@
   connectToForwarder(InternalForwarderTransport* forwarder);
 
   void
-  receivePacket(Block&& packet) final;
+  receivePacket(const Block& packet) final;
 
   void
   send(const Block& wire) final;
diff --git a/daemon/face/link-service.cpp b/daemon/face/link-service.cpp
index 34abd58..a382ebe 100644
--- a/daemon/face/link-service.cpp
+++ b/daemon/face/link-service.cpp
@@ -52,66 +52,66 @@
 }
 
 void
-LinkService::sendInterest(const Interest& interest, const EndpointId& endpointId)
+LinkService::sendInterest(const Interest& interest, const EndpointId& endpoint)
 {
   BOOST_ASSERT(m_transport != nullptr);
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nOutInterests;
 
-  doSendInterest(interest, endpointId);
+  doSendInterest(interest, endpoint);
 }
 
 void
-LinkService::sendData(const Data& data, const EndpointId& endpointId)
+LinkService::sendData(const Data& data, const EndpointId& endpoint)
 {
   BOOST_ASSERT(m_transport != nullptr);
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nOutData;
 
-  doSendData(data, endpointId);
+  doSendData(data, endpoint);
 }
 
 void
-LinkService::sendNack(const ndn::lp::Nack& nack, const EndpointId& endpointId)
+LinkService::sendNack(const ndn::lp::Nack& nack, const EndpointId& endpoint)
 {
   BOOST_ASSERT(m_transport != nullptr);
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nOutNacks;
 
-  doSendNack(nack, endpointId);
+  doSendNack(nack, endpoint);
 }
 
 void
-LinkService::receiveInterest(const Interest& interest, const EndpointId& endpointId)
+LinkService::receiveInterest(const Interest& interest, const EndpointId& endpoint)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nInInterests;
 
-  afterReceiveInterest(interest, endpointId);
+  afterReceiveInterest(interest, endpoint);
 }
 
 void
-LinkService::receiveData(const Data& data, const EndpointId& endpointId)
+LinkService::receiveData(const Data& data, const EndpointId& endpoint)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nInData;
 
-  afterReceiveData(data, endpointId);
+  afterReceiveData(data, endpoint);
 }
 
 void
-LinkService::receiveNack(const ndn::lp::Nack& nack, const EndpointId& endpointId)
+LinkService::receiveNack(const ndn::lp::Nack& nack, const EndpointId& endpoint)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nInNacks;
 
-  afterReceiveNack(nack, endpointId);
+  afterReceiveNack(nack, endpoint);
 }
 
 void
diff --git a/daemon/face/link-service.hpp b/daemon/face/link-service.hpp
index fd77391..8396137 100644
--- a/daemon/face/link-service.hpp
+++ b/daemon/face/link-service.hpp
@@ -112,23 +112,23 @@
   getCounters() const;
 
 public: // upper interface to be used by forwarding
-  /** \brief send Interest to \p endpointId
+  /** \brief Send Interest to \p endpoint
    *  \pre setTransport has been called
    */
   void
-  sendInterest(const Interest& interest, const EndpointId& endpointId);
+  sendInterest(const Interest& interest, const EndpointId& endpoint);
 
-  /** \brief send Data to \p endpointId
+  /** \brief Send Data to \p endpoint
    *  \pre setTransport has been called
    */
   void
-  sendData(const Data& data, const EndpointId& endpointId);
+  sendData(const Data& data, const EndpointId& endpoint);
 
-  /** \brief send Nack to \p endpointId
+  /** \brief Send Nack to \p endpoint
    *  \pre setTransport has been called
    */
   void
-  sendNack(const ndn::lp::Nack& nack, const EndpointId& endpointId);
+  sendNack(const ndn::lp::Nack& nack, const EndpointId& endpoint);
 
   /** \brief signals on Interest received
    */
@@ -150,53 +150,53 @@
   /** \brief performs LinkService specific operations to receive a lower-layer packet
    */
   void
-  receivePacket(Transport::Packet&& packet);
+  receivePacket(const Block& packet, const EndpointId& endpoint);
 
 protected: // upper interface to be invoked in subclass (receive path termination)
   /** \brief delivers received Interest to forwarding
    */
   void
-  receiveInterest(const Interest& interest, const EndpointId& endpointId);
+  receiveInterest(const Interest& interest, const EndpointId& endpoint);
 
   /** \brief delivers received Data to forwarding
    */
   void
-  receiveData(const Data& data, const EndpointId& endpointId);
+  receiveData(const Data& data, const EndpointId& endpoint);
 
   /** \brief delivers received Nack to forwarding
    */
   void
-  receiveNack(const lp::Nack& nack, const EndpointId& endpointId);
+  receiveNack(const lp::Nack& nack, const EndpointId& endpoint);
 
 protected: // lower interface to be invoked in subclass (send path termination)
-  /** \brief send a lower-layer packet via Transport to \p endpointId
+  /** \brief send a lower-layer packet via Transport to \p endpoint
    */
   void
-  sendPacket(Transport::Packet&& packet, const EndpointId& endpointId);
+  sendPacket(const Block& packet, const EndpointId& endpoint);
 
 protected:
   void
   notifyDroppedInterest(const Interest& packet);
 
 private: // upper interface to be overridden in subclass (send path entrypoint)
-  /** \brief performs LinkService specific operations to send an Interest to \p endpointId
+  /** \brief performs LinkService specific operations to send an Interest to \p endpoint
    */
   virtual void
-  doSendInterest(const Interest& interest, const EndpointId& endpointId) = 0;
+  doSendInterest(const Interest& interest, const EndpointId& endpoint) = 0;
 
-  /** \brief performs LinkService specific operations to send a Data to \p endpointId
+  /** \brief performs LinkService specific operations to send a Data to \p endpoint
    */
   virtual void
-  doSendData(const Data& data, const EndpointId& endpointId) = 0;
+  doSendData(const Data& data, const EndpointId& endpoint) = 0;
 
-  /** \brief performs LinkService specific operations to send a Nack to \p endpointId
+  /** \brief performs LinkService specific operations to send a Nack to \p endpoint
    */
   virtual void
-  doSendNack(const lp::Nack& nack, const EndpointId& endpointId) = 0;
+  doSendNack(const lp::Nack& nack, const EndpointId& endpoint) = 0;
 
 private: // lower interface to be overridden in subclass
   virtual void
-  doReceivePacket(Transport::Packet&& packet) = 0;
+  doReceivePacket(const Block& packet, const EndpointId& endpoint) = 0;
 
 private:
   Face* m_face;
@@ -228,16 +228,15 @@
 }
 
 inline void
-LinkService::receivePacket(Transport::Packet&& packet)
+LinkService::receivePacket(const Block& packet, const EndpointId& endpoint)
 {
-  doReceivePacket(std::move(packet));
+  doReceivePacket(packet, endpoint);
 }
 
 inline void
-LinkService::sendPacket(Transport::Packet&& packet, const EndpointId& endpointId)
+LinkService::sendPacket(const Block& packet, const EndpointId& endpoint)
 {
-  packet.remoteEndpoint = endpointId;
-  m_transport->send(std::move(packet));
+  m_transport->send(packet, endpoint);
 }
 
 std::ostream&
diff --git a/daemon/face/lp-reassembler.hpp b/daemon/face/lp-reassembler.hpp
index 2c5ff91..e9f0556 100644
--- a/daemon/face/lp-reassembler.hpp
+++ b/daemon/face/lp-reassembler.hpp
@@ -72,13 +72,13 @@
   const LinkService*
   getLinkService() const;
 
-  /** \brief adds received fragment to buffer
-   *  \param remoteEndpoint endpoint whose sends the packet
-   *  \param packet received fragment;
-   *                must have Fragment field
-   *  \return whether network-layer packet has been completely received,
+  /** \brief adds received fragment to the buffer
+   *  \param remoteEndpoint endpoint that sent the packet
+   *  \param packet received fragment; must have Fragment field
+   *  \return a tuple containing:
+   *          whether a network-layer packet has been completely received,
    *          the reassembled network-layer packet,
-   *          and the first fragment for inspecting other NDNLPv2 headers
+   *          the first fragment for inspecting other NDNLPv2 headers
    *  \throw tlv::Error packet is malformed
    */
   std::tuple<bool, Block, lp::Packet>
diff --git a/daemon/face/multicast-udp-transport.cpp b/daemon/face/multicast-udp-transport.cpp
index 689b7e0..5017e7d 100644
--- a/daemon/face/multicast-udp-transport.cpp
+++ b/daemon/face/multicast-udp-transport.cpp
@@ -82,13 +82,13 @@
 }
 
 void
-MulticastUdpTransport::doSend(Transport::Packet&& packet)
+MulticastUdpTransport::doSend(const Block& packet, const EndpointId&)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
-  m_sendSocket.async_send_to(boost::asio::buffer(packet.packet), m_multicastGroup,
-                             // packet.packet is copied into the lambda to retain the underlying Buffer
-                             [this, p = packet.packet] (auto&&... args) {
+  m_sendSocket.async_send_to(boost::asio::buffer(packet), m_multicastGroup,
+                             // 'packet' is copied into the lambda to retain the underlying Buffer
+                             [this, packet] (auto&&... args) {
                                this->handleSend(std::forward<decltype(args)>(args)...);
                              });
 }
diff --git a/daemon/face/multicast-udp-transport.hpp b/daemon/face/multicast-udp-transport.hpp
index bea7cb4..c85df82 100644
--- a/daemon/face/multicast-udp-transport.hpp
+++ b/daemon/face/multicast-udp-transport.hpp
@@ -52,11 +52,7 @@
   class Error : public std::runtime_error
   {
   public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
+    using std::runtime_error::runtime_error;
   };
 
   /**
@@ -88,7 +84,7 @@
 
 private:
   void
-  doSend(Transport::Packet&& packet) final;
+  doSend(const Block& packet, const EndpointId& endpoint) final;
 
   void
   doClose() final;
diff --git a/daemon/face/null-link-service.hpp b/daemon/face/null-link-service.hpp
index d31304b..3823d9a 100644
--- a/daemon/face/null-link-service.hpp
+++ b/daemon/face/null-link-service.hpp
@@ -52,7 +52,7 @@
   }
 
   void
-  doReceivePacket(Transport::Packet&&) final
+  doReceivePacket(const Block&, const EndpointId&) final
   {
   }
 };
diff --git a/daemon/face/null-transport.hpp b/daemon/face/null-transport.hpp
index 9f8e54e..303b1e8 100644
--- a/daemon/face/null-transport.hpp
+++ b/daemon/face/null-transport.hpp
@@ -51,7 +51,7 @@
 
 private:
   void
-  doSend(Packet&&) OVERRIDE_WITH_TESTS_ELSE_FINAL
+  doSend(const Block&, const EndpointId&) OVERRIDE_WITH_TESTS_ELSE_FINAL
   {
   }
 };
diff --git a/daemon/face/stream-transport.hpp b/daemon/face/stream-transport.hpp
index e0a7d6d..04941b5 100644
--- a/daemon/face/stream-transport.hpp
+++ b/daemon/face/stream-transport.hpp
@@ -63,7 +63,7 @@
   deferredClose();
 
   void
-  doSend(Transport::Packet&& packet) override;
+  doSend(const Block& packet, const EndpointId& endpoint) override;
 
   void
   sendFromQueue();
@@ -180,7 +180,7 @@
 
 template<class T>
 void
-StreamTransport<T>::doSend(Transport::Packet&& packet)
+StreamTransport<T>::doSend(const Block& packet, const EndpointId&)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
@@ -188,8 +188,8 @@
     return;
 
   bool wasQueueEmpty = m_sendQueue.empty();
-  m_sendQueue.push(packet.packet);
-  m_sendQueueBytes += packet.packet.size();
+  m_sendQueue.push(packet);
+  m_sendQueueBytes += packet.size();
 
   if (wasQueueEmpty)
     sendFromQueue();
@@ -255,7 +255,7 @@
     offset += element.size();
     BOOST_ASSERT(offset <= m_receiveBufferSize);
 
-    this->receive(Transport::Packet(std::move(element)));
+    this->receive(element);
   }
 
   if (!isOk && m_receiveBufferSize == ndn::MAX_NDN_PACKET_SIZE && offset == 0) {
diff --git a/daemon/face/transport.cpp b/daemon/face/transport.cpp
index e93480f..7b1bb18 100644
--- a/daemon/face/transport.cpp
+++ b/daemon/face/transport.cpp
@@ -52,12 +52,6 @@
   }
 }
 
-Transport::Packet::Packet(Block&& packet1)
-  : packet(std::move(packet1))
-  , remoteEndpoint(0)
-{
-}
-
 Transport::Transport()
   : m_face(nullptr)
   , m_service(nullptr)
@@ -97,10 +91,11 @@
 }
 
 void
-Transport::send(Packet&& packet)
+Transport::send(const Block& packet, const EndpointId& endpoint)
 {
+  BOOST_ASSERT(packet.isValid());
   BOOST_ASSERT(this->getMtu() == MTU_UNLIMITED ||
-               packet.packet.size() <= static_cast<size_t>(this->getMtu()));
+               packet.size() <= static_cast<size_t>(this->getMtu()));
 
   TransportState state = this->getState();
   if (state != TransportState::UP && state != TransportState::DOWN) {
@@ -110,22 +105,23 @@
 
   if (state == TransportState::UP) {
     ++this->nOutPackets;
-    this->nOutBytes += packet.packet.size();
+    this->nOutBytes += packet.size();
   }
 
-  this->doSend(std::move(packet));
+  this->doSend(packet, endpoint);
 }
 
 void
-Transport::receive(Packet&& packet)
+Transport::receive(const Block& packet, const EndpointId& endpoint)
 {
+  BOOST_ASSERT(packet.isValid());
   BOOST_ASSERT(this->getMtu() == MTU_UNLIMITED ||
-               packet.packet.size() <= static_cast<size_t>(this->getMtu()));
+               packet.size() <= static_cast<size_t>(this->getMtu()));
 
   ++this->nInPackets;
-  this->nInBytes += packet.packet.size();
+  this->nInBytes += packet.size();
 
-  m_service->receivePacket(std::move(packet));
+  m_service->receivePacket(packet, endpoint);
 }
 
 bool
diff --git a/daemon/face/transport.hpp b/daemon/face/transport.hpp
index aaea75a..2dd81a0 100644
--- a/daemon/face/transport.hpp
+++ b/daemon/face/transport.hpp
@@ -37,11 +37,19 @@
 class Face;
 class LinkService;
 
-/** \brief identifies an endpoint on the link
+/** \brief Identifies a remote endpoint on the link.
+ *
+ *  This ID is only meaningful in the context of the same Transport.
+ *  Incoming packets from the same remote endpoint have the same EndpointId,
+ *  and incoming packets from different remote endpoints have different EndpointIds.
+ *
+ *  Typically, a point-to-point Transport has only one meaningful EndpointId (usually 0).
+ *
+ *  \sa FaceEndpoint
  */
-typedef uint64_t EndpointId;
+using EndpointId = uint64_t;
 
-/** \brief indicates the state of a transport
+/** \brief Indicates the state of a transport.
  */
 enum class TransportState {
   NONE,
@@ -55,9 +63,9 @@
 std::ostream&
 operator<<(std::ostream& os, TransportState state);
 
-/** \brief counters provided by Transport
- *  \note The type name 'TransportCounters' is implementation detail.
- *        Use 'Transport::Counters' in public API.
+/** \brief Counters provided by a transport.
+ *  \note The type name TransportCounters is an implementation detail.
+ *        Use Transport::Counters in public API.
  */
 class TransportCounters
 {
@@ -111,43 +119,20 @@
  */
 const ssize_t QUEUE_ERROR = -2;
 
-/** \brief the lower part of a Face
+/** \brief The lower half of a Face.
  *  \sa Face
  */
 class Transport : protected virtual TransportCounters, noncopyable
 {
 public:
-  /** \brief stores a packet along with the remote endpoint
+  /** \brief Counters provided by a transport.
+   *  \sa TransportCounters
    */
-  class Packet
-  {
-  public:
-    Packet() = default;
+  using Counters = TransportCounters;
 
-    explicit
-    Packet(Block&& packet);
-
-  public:
-    /** \brief the packet as a TLV block
-     */
-    Block packet;
-
-    /** \brief identifies the remote endpoint
-     *
-     *  This ID is only meaningful in the context of the same Transport.
-     *  Incoming packets from the same remote endpoint have the same EndpointId,
-     *  and incoming packets from different remote endpoints have different EndpointIds.
-     */
-    EndpointId remoteEndpoint;
-  };
-
-  /** \brief counters provided by Transport
-   */
-  typedef TransportCounters Counters;
-
-  /** \brief constructor
+  /** \brief Default constructor.
    *
-   *  Transport constructor initializes static properties to invalid values.
+   *  This constructor initializes static properties to invalid values.
    *  Subclass constructor must explicitly set every static property.
    *
    *  This constructor initializes TransportState to UP;
@@ -184,7 +169,7 @@
   getCounters() const;
 
 public: // upper interface
-  /** \brief request the transport to be closed
+  /** \brief Request the transport to be closed
    *
    *  This operation is effective only if transport is in UP or DOWN state,
    *  otherwise it has no effect.
@@ -195,12 +180,14 @@
   void
   close();
 
-  /** \brief send a link-layer packet
-   *  \note This operation has no effect if \p getState() is neither UP nor DOWN
-   *  \warning undefined behavior if packet size exceeds MTU limit
+  /** \brief Send a link-layer packet
+   *  \param packet the packet to be sent, must be a valid and well-formed TLV block
+   *  \param endpoint the destination endpoint
+   *  \note This operation has no effect if getState() is neither UP nor DOWN
+   *  \warning Behavior is undefined if packet size exceeds the MTU limit
    */
   void
-  send(Packet&& packet);
+  send(const Block& packet, const EndpointId& endpoint = 0);
 
 public: // static properties
   /** \return a FaceUri representing local endpoint
@@ -239,7 +226,7 @@
   void
   setPersistency(ndn::nfd::FacePersistency newPersistency);
 
-  /** \return whether face is point-to-point or multi-access
+  /** \return the link type of the transport
    */
   ndn::nfd::LinkType
   getLinkType() const;
@@ -290,11 +277,13 @@
   }
 
 protected: // upper interface to be invoked by subclass
-  /** \brief receive a link-layer packet
-   *  \warning undefined behavior if packet size exceeds MTU limit
+  /** \brief Pass a received link-layer packet to the upper layer for further processing
+   *  \param packet the received packet, must be a valid and well-formed TLV block
+   *  \param endpoint the source endpoint
+   *  \warning Behavior is undefined if packet size exceeds the MTU limit
    */
   void
-  receive(Packet&& packet);
+  receive(const Block& packet, const EndpointId& endpoint = 0);
 
 protected: // properties to be set by subclass
   void
@@ -360,11 +349,12 @@
 
 private: // to be overridden by subclass
   /** \brief performs Transport specific operations to send a packet
-   *  \param packet the packet, which must be a well-formed TLV block
-   *  \pre state is either UP or DOWN
+   *  \param packet the packet to be sent, can be assumed to be valid and well-formed
+   *  \param endpoint the destination endpoint
+   *  \pre transport state is either UP or DOWN
    */
   virtual void
-  doSend(Packet&& packet) = 0;
+  doSend(const Block& packet, const EndpointId& endpoint) = 0;
 
 public:
   /** \brief minimum MTU that may be set on a transport
diff --git a/daemon/face/websocket-transport.cpp b/daemon/face/websocket-transport.cpp
index d20e54c..bd45711 100644
--- a/daemon/face/websocket-transport.cpp
+++ b/daemon/face/websocket-transport.cpp
@@ -78,17 +78,17 @@
 }
 
 void
-WebSocketTransport::doSend(Transport::Packet&& packet)
+WebSocketTransport::doSend(const Block& packet, const EndpointId&)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   websocketpp::lib::error_code error;
-  m_server.send(m_handle, packet.packet.wire(), packet.packet.size(),
+  m_server.send(m_handle, packet.wire(), packet.size(),
                 websocketpp::frame::opcode::binary, error);
   if (error)
     return processErrorCode(error);
 
-  NFD_LOG_FACE_TRACE("Successfully sent: " << packet.packet.size() << " bytes");
+  NFD_LOG_FACE_TRACE("Successfully sent: " << packet.size() << " bytes");
 }
 
 void
@@ -104,7 +104,7 @@
     return;
   }
 
-  this->receive(Transport::Packet(std::move(element)));
+  this->receive(element);
 }
 
 void
diff --git a/daemon/face/websocket-transport.hpp b/daemon/face/websocket-transport.hpp
index 0bdadb5..10f4b2a 100644
--- a/daemon/face/websocket-transport.hpp
+++ b/daemon/face/websocket-transport.hpp
@@ -83,7 +83,7 @@
 
 private:
   void
-  doSend(Transport::Packet&& packet) final;
+  doSend(const Block& packet, const EndpointId& endpoint) final;
 
   void
   schedulePing();
diff --git a/tests/daemon/face/datagram-transport.t.cpp b/tests/daemon/face/datagram-transport.t.cpp
index fd1a8e0..28b73e1 100644
--- a/tests/daemon/face/datagram-transport.t.cpp
+++ b/tests/daemon/face/datagram-transport.t.cpp
@@ -49,7 +49,7 @@
   TRANSPORT_TEST_INIT();
 
   auto block1 = ndn::encoding::makeStringBlock(300, "hello");
-  this->transport->send(Transport::Packet{Block{block1}}); // make a copy of the block
+  this->transport->send(block1);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 1);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutBytes, block1.size());
 
@@ -64,14 +64,26 @@
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt = ndn::encoding::makeStringBlock(300, "hello");
-  ndn::Buffer buf(pkt.begin(), pkt.end());
-  this->remoteWrite(buf);
+  auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  ndn::Buffer buf1(pkt1.begin(), pkt1.end());
+  this->remoteWrite(buf1);
 
   BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 1);
-  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt.size());
-  BOOST_CHECK_EQUAL(this->receivedPackets->size(), 1);
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size());
+
+  auto pkt2 = ndn::encoding::makeStringBlock(301, "world!");
+  ndn::Buffer buf2(pkt2.begin(), pkt2.end());
+  this->remoteWrite(buf2);
+
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 2);
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size() + pkt2.size());
   BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
+
+  BOOST_REQUIRE_EQUAL(this->receivedPackets->size(), 2);
+  BOOST_CHECK(this->receivedPackets->at(0).packet == pkt1);
+  BOOST_CHECK(this->receivedPackets->at(1).packet == pkt2);
+  BOOST_CHECK_EQUAL(this->receivedPackets->at(0).endpoint,
+                    this->receivedPackets->at(1).endpoint);
 }
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(ReceiveIncomplete, T, DatagramTransportFixtures, T)
@@ -90,8 +102,8 @@
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
-  Block pkt2 = ndn::encoding::makeStringBlock(301, "world");
+  auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  auto pkt2 = ndn::encoding::makeStringBlock(301, "world");
   ndn::Buffer buf(pkt1.size() + pkt2.size());
   std::copy(pkt1.begin(), pkt1.end(), buf.begin());
   std::copy(pkt2.begin(), pkt2.end(), buf.begin() + pkt1.size());
@@ -109,11 +121,11 @@
   TRANSPORT_TEST_INIT();
 
   std::vector<uint8_t> bytes(ndn::MAX_NDN_PACKET_SIZE, 0);
-  Block pkt1 = ndn::encoding::makeBinaryBlock(300, bytes.data(), bytes.size() - 6);
+  auto pkt1 = ndn::encoding::makeBinaryBlock(300, bytes.data(), bytes.size() - 6);
   ndn::Buffer buf1(pkt1.begin(), pkt1.end());
   BOOST_REQUIRE_EQUAL(buf1.size(), ndn::MAX_NDN_PACKET_SIZE);
 
-  Block pkt2 = ndn::encoding::makeBinaryBlock(301, bytes.data(), bytes.size());
+  auto pkt2 = ndn::encoding::makeBinaryBlock(301, bytes.data(), bytes.size());
   ndn::Buffer buf2(pkt2.begin(), pkt2.end());
   BOOST_REQUIRE_GT(buf2.size(), ndn::MAX_NDN_PACKET_SIZE);
 
@@ -136,14 +148,14 @@
 {
   TRANSPORT_TEST_INIT();
 
-  this->transport->afterStateChange.connectSingleShot([] (TransportState oldState, TransportState newState) {
+  this->transport->afterStateChange.connectSingleShot([] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
   });
 
   this->transport->close();
 
-  this->transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  this->transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
     this->limitedIo.afterOp();
diff --git a/tests/daemon/face/dummy-link-service.cpp b/tests/daemon/face/dummy-link-service.cpp
index 019e9dc..ce006cb 100644
--- a/tests/daemon/face/dummy-link-service.cpp
+++ b/tests/daemon/face/dummy-link-service.cpp
@@ -30,7 +30,7 @@
 namespace tests {
 
 void
-DummyLinkService::doSendInterest(const Interest& interest, const EndpointId& endpointId)
+DummyLinkService::doSendInterest(const Interest& interest, const EndpointId&)
 {
   if (m_loggingFlags & LogSentInterests)
     sentInterests.push_back(interest);
@@ -39,7 +39,7 @@
 }
 
 void
-DummyLinkService::doSendData(const Data& data, const EndpointId& endpointId)
+DummyLinkService::doSendData(const Data& data, const EndpointId&)
 {
   if (m_loggingFlags & LogSentData)
     sentData.push_back(data);
@@ -48,7 +48,7 @@
 }
 
 void
-DummyLinkService::doSendNack(const lp::Nack& nack, const EndpointId& endpointId)
+DummyLinkService::doSendNack(const lp::Nack& nack, const EndpointId&)
 {
   if (m_loggingFlags & LogSentNacks)
     sentNacks.push_back(nack);
@@ -57,10 +57,10 @@
 }
 
 void
-DummyLinkService::doReceivePacket(Transport::Packet&& packet)
+DummyLinkService::doReceivePacket(const Block& packet, const EndpointId& endpoint)
 {
   if (m_loggingFlags & LogReceivedPackets)
-    receivedPackets.push_back(std::move(packet));
+    receivedPackets.push_back({packet, endpoint});
 }
 
 } // namespace tests
diff --git a/tests/daemon/face/dummy-link-service.hpp b/tests/daemon/face/dummy-link-service.hpp
index b1caf8c..44ed991 100644
--- a/tests/daemon/face/dummy-link-service.hpp
+++ b/tests/daemon/face/dummy-link-service.hpp
@@ -38,10 +38,16 @@
   LogSentData         = 1 << 1, ///< log sent Data packets
   LogSentNacks        = 1 << 2, ///< log sent Nack packets
   LogSentPackets      = LogSentInterests | LogSentData | LogSentNacks, ///< log all sent packets
-  LogReceivedPackets  = 1 << 3, ///< log all received packets (as Transport::Packet)
+  LogReceivedPackets  = 1 << 3, ///< log all received link-layer packets
   LogAllPackets       = LogSentPackets | LogReceivedPackets, ///< log all sent and received packets
 };
 
+struct RxPacket
+{
+  Block packet;
+  EndpointId endpoint;
+};
+
 /** \brief A dummy LinkService that logs all sent and received packets.
  */
 class DummyLinkService final : public LinkService
@@ -67,22 +73,22 @@
 
 private:
   void
-  doSendInterest(const Interest& interest, const EndpointId& endpointId) final;
+  doSendInterest(const Interest& interest, const EndpointId& endpoint) final;
 
   void
-  doSendData(const Data& data, const EndpointId& endpointId) final;
+  doSendData(const Data& data, const EndpointId& endpoint) final;
 
   void
-  doSendNack(const lp::Nack& nack, const EndpointId& endpointId) final;
+  doSendNack(const lp::Nack& nack, const EndpointId& endpoint) final;
 
   void
-  doReceivePacket(Transport::Packet&& packet) final;
+  doReceivePacket(const Block& packet, const EndpointId& endpoint) final;
 
 public:
   std::vector<Interest> sentInterests;
   std::vector<Data> sentData;
   std::vector<lp::Nack> sentNacks;
-  std::vector<Transport::Packet> receivedPackets;
+  std::vector<RxPacket> receivedPackets;
 
 private:
   PacketLoggingFlags m_loggingFlags = LogAllPackets;
diff --git a/tests/daemon/face/dummy-transport.hpp b/tests/daemon/face/dummy-transport.hpp
index 1594df8..3f3141e 100644
--- a/tests/daemon/face/dummy-transport.hpp
+++ b/tests/daemon/face/dummy-transport.hpp
@@ -34,6 +34,12 @@
 namespace face {
 namespace tests {
 
+struct TxPacket
+{
+  Block packet;
+  EndpointId endpoint;
+};
+
 /** \brief Dummy Transport type used in unit tests.
  *
  *  All packets sent through this transport are stored in `sentPackets`.
@@ -75,9 +81,9 @@
   }
 
   void
-  receivePacket(Block block)
+  receivePacket(const Block& block)
   {
-    receive(Packet(std::move(block)));
+    receive(block);
   }
 
 protected:
@@ -95,14 +101,14 @@
 
 private:
   void
-  doSend(Packet&& packet) override
+  doSend(const Block& packet, const EndpointId& endpoint) override
   {
-    sentPackets.push_back(std::move(packet));
+    sentPackets.push_back({packet, endpoint});
   }
 
 public:
   std::vector<ndn::nfd::FacePersistency> persistencyHistory;
-  std::vector<Packet> sentPackets;
+  std::vector<TxPacket> sentPackets;
 
 private:
   ssize_t m_sendQueueLength = 0;
diff --git a/tests/daemon/face/generic-link-service.t.cpp b/tests/daemon/face/generic-link-service.t.cpp
index 74e388f..fc5efc2 100644
--- a/tests/daemon/face/generic-link-service.t.cpp
+++ b/tests/daemon/face/generic-link-service.t.cpp
@@ -50,12 +50,10 @@
 {
 protected:
   GenericLinkServiceFixture()
-    : service(nullptr)
-    , transport(nullptr)
   {
     // By default, GenericLinkService is created with default options.
-    // Test cases may invoke .initialize with alternate options.
-    this->initialize({});
+    // Test cases may invoke initialize() with alternate options.
+    initialize({});
   }
 
   void
@@ -64,13 +62,11 @@
              ssize_t sendQueueCapacity = QUEUE_UNSUPPORTED)
   {
     face = make_unique<Face>(make_unique<GenericLinkService>(options),
-                             make_unique<DummyTransport>("dummy://",
-                                                         "dummy://",
+                             make_unique<DummyTransport>("dummy://", "dummy://",
                                                          ndn::nfd::FACE_SCOPE_NON_LOCAL,
                                                          ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
                                                          ndn::nfd::LINK_TYPE_POINT_TO_POINT,
-                                                         mtu,
-                                                         sendQueueCapacity));
+                                                         mtu, sendQueueCapacity));
     service = static_cast<GenericLinkService*>(face->getLinkService());
     transport = static_cast<DummyTransport*>(face->getTransport());
 
@@ -85,14 +81,14 @@
   lp::PrefixAnnouncementHeader
   makePrefixAnnHeader(const Name& announcedName)
   {
-    return lp::PrefixAnnouncementHeader{signPrefixAnn(
-      makePrefixAnn(announcedName, 1_h), m_keyChain, ndn::signingWithSha256())};
+    return lp::PrefixAnnouncementHeader{signPrefixAnn(makePrefixAnn(announcedName, 1_h),
+                                                      m_keyChain, ndn::signingWithSha256())};
   }
 
 protected:
   unique_ptr<Face> face;
-  GenericLinkService* service;
-  DummyTransport* transport;
+  GenericLinkService* service = nullptr;
+  DummyTransport* transport = nullptr;
   std::vector<Interest> receivedInterests;
   std::vector<Data> receivedData;
   std::vector<lp::Nack> receivedNacks;
@@ -100,7 +96,6 @@
 
 BOOST_FIXTURE_TEST_SUITE(TestGenericLinkService, GenericLinkServiceFixture)
 
-
 BOOST_AUTO_TEST_SUITE(SimpleSendReceive) // send and receive without other fields
 
 BOOST_AUTO_TEST_CASE(SendInterest)
@@ -110,14 +105,12 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  shared_ptr<Interest> interest1 = makeInterest("/localhost/test");
-
+  auto interest1 = makeInterest("/localhost/test");
   face->sendInterest(*interest1, 0);
 
   BOOST_CHECK_EQUAL(service->getCounters().nOutInterests, 1);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet interest1pkt;
-  BOOST_REQUIRE_NO_THROW(interest1pkt.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet interest1pkt(transport->sentPackets.back().packet);
   BOOST_CHECK(interest1pkt.has<lp::FragmentField>());
   BOOST_CHECK(!interest1pkt.has<lp::SequenceField>());
 }
@@ -129,14 +122,12 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  shared_ptr<Data> data1 = makeData("/localhost/test");
-
+  auto data1 = makeData("/localhost/test");
   face->sendData(*data1, 0);
 
   BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet data1pkt;
-  BOOST_REQUIRE_NO_THROW(data1pkt.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet data1pkt(transport->sentPackets.back().packet);
   BOOST_CHECK(data1pkt.has<lp::FragmentField>());
   BOOST_CHECK(!data1pkt.has<lp::SequenceField>());
 }
@@ -148,14 +139,12 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  lp::Nack nack1 = makeNack("/localhost/test", 323, lp::NackReason::NO_ROUTE);
-
+  auto nack1 = makeNack("/localhost/test", 323, lp::NackReason::NO_ROUTE);
   face->sendNack(nack1, 0);
 
   BOOST_CHECK_EQUAL(service->getCounters().nOutNacks, 1);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet nack1pkt;
-  BOOST_REQUIRE_NO_THROW(nack1pkt.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet nack1pkt(transport->sentPackets.back().packet);
   BOOST_CHECK(nack1pkt.has<lp::NackField>());
   BOOST_CHECK(nack1pkt.has<lp::FragmentField>());
   BOOST_CHECK(!nack1pkt.has<lp::SequenceField>());
@@ -168,8 +157,7 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  shared_ptr<Interest> interest1 = makeInterest("/23Rd9hEiR");
-
+  auto interest1 = makeInterest("/23Rd9hEiR");
   transport->receivePacket(interest1->wireEncode());
 
   BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
@@ -204,8 +192,7 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  shared_ptr<Data> data1 = makeData("/12345678");
-
+  auto data1 = makeData("/12345678");
   transport->receivePacket(data1->wireEncode());
 
   BOOST_CHECK_EQUAL(service->getCounters().nInData, 1);
@@ -264,7 +251,7 @@
   lp::Packet lpPacket;
   lpPacket.set<lp::SequenceField>(0);
 
-  BOOST_CHECK_NO_THROW(transport->receivePacket(lpPacket.wireEncode()));
+  transport->receivePacket(lpPacket.wireEncode());
 
   // IDLE packet should be ignored, but is not an error
   BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0);
@@ -423,14 +410,12 @@
   options.reliabilityOptions.isEnabled = true;
   initialize(options);
 
-  shared_ptr<Interest> interest1 = makeInterest("/localhost/test");
-
+  auto interest1 = makeInterest("/localhost/test");
   face->sendInterest(*interest1, 0);
 
   BOOST_CHECK_EQUAL(service->getCounters().nOutInterests, 1);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet interest1pkt;
-  BOOST_REQUIRE_NO_THROW(interest1pkt.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet interest1pkt(transport->sentPackets.back().packet);
   BOOST_CHECK(interest1pkt.has<lp::FragmentField>());
   BOOST_CHECK(interest1pkt.has<lp::TxSequenceField>());
 }
@@ -443,14 +428,12 @@
   options.reliabilityOptions.isEnabled = true;
   initialize(options);
 
-  shared_ptr<Data> data1 = makeData("/localhost/test");
-
+  auto data1 = makeData("/localhost/test");
   face->sendData(*data1, 0);
 
   BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet data1pkt;
-  BOOST_REQUIRE_NO_THROW(data1pkt.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet data1pkt(transport->sentPackets.back().packet);
   BOOST_CHECK(data1pkt.has<lp::FragmentField>());
   BOOST_CHECK(data1pkt.has<lp::TxSequenceField>());
 }
@@ -463,14 +446,12 @@
   options.reliabilityOptions.isEnabled = true;
   initialize(options);
 
-  lp::Nack nack1 = makeNack("/localhost/test", 323, lp::NackReason::NO_ROUTE);
-
+  auto nack1 = makeNack("/localhost/test", 323, lp::NackReason::NO_ROUTE);
   face->sendNack(nack1, 0);
 
   BOOST_CHECK_EQUAL(service->getCounters().nOutNacks, 1);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet nack1pkt;
-  BOOST_REQUIRE_NO_THROW(nack1pkt.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet nack1pkt(transport->sentPackets.back().packet);
   BOOST_CHECK(nack1pkt.has<lp::NackField>());
   BOOST_CHECK(nack1pkt.has<lp::FragmentField>());
   BOOST_CHECK(nack1pkt.has<lp::TxSequenceField>());
@@ -499,8 +480,7 @@
   transport->setSendQueueLength(0);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet pkt1;
-  BOOST_REQUIRE_NO_THROW(pkt1.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt1(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt1.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
@@ -510,8 +490,7 @@
   transport->setSendQueueLength(32768);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
-  lp::Packet pkt2;
-  BOOST_REQUIRE_NO_THROW(pkt2.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt2(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
@@ -537,8 +516,7 @@
   transport->setSendQueueLength(32769);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet pkt1;
-  BOOST_REQUIRE_NO_THROW(pkt1.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt1(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt1.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt1.get<lp::CongestionMarkField>(), 1);
   time::steady_clock::TimePoint nextMarkTime = time::steady_clock::now() + 100_ms;
@@ -555,8 +533,7 @@
   transport->setSendQueueLength(33000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
-  lp::Packet pkt2;
-  BOOST_REQUIRE_NO_THROW(pkt2.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt2(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -570,8 +547,7 @@
   transport->setSendQueueLength(40000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
-  lp::Packet pkt3;
-  BOOST_REQUIRE_NO_THROW(pkt3.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt3(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt3.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt3.get<lp::CongestionMarkField>(), 1);
   time::nanoseconds markingInterval(
@@ -591,8 +567,7 @@
   transport->setSendQueueLength(38000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 4);
-  lp::Packet pkt4;
-  BOOST_REQUIRE_NO_THROW(pkt4.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt4(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt4.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -606,8 +581,7 @@
   transport->setSendQueueLength(39000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
-  lp::Packet pkt5;
-  BOOST_REQUIRE_NO_THROW(pkt5.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt5(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt5.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt5.get<lp::CongestionMarkField>(), 1);
   markingInterval = time::nanoseconds(
@@ -626,8 +600,7 @@
   transport->setSendQueueLength(38000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 6);
-  lp::Packet pkt6;
-  BOOST_REQUIRE_NO_THROW(pkt6.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt6(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt6.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -640,8 +613,7 @@
   transport->setSendQueueLength(34000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 7);
-  lp::Packet pkt7;
-  BOOST_REQUIRE_NO_THROW(pkt7.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt7(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt7.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt7.get<lp::CongestionMarkField>(), 1);
   markingInterval = time::nanoseconds(
@@ -658,8 +630,7 @@
   transport->setSendQueueLength(30000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 8);
-  lp::Packet pkt8;
-  BOOST_REQUIRE_NO_THROW(pkt8.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt8(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt8.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -672,8 +643,7 @@
   transport->setSendQueueLength(50000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 9);
-  lp::Packet pkt9;
-  BOOST_REQUIRE_NO_THROW(pkt9.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt9(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt9.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -686,8 +656,7 @@
   transport->setSendQueueLength(40000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 10);
-  lp::Packet pkt10;
-  BOOST_REQUIRE_NO_THROW(pkt10.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt10(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt10.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt10.get<lp::CongestionMarkField>(), 1);
   nextMarkTime = time::steady_clock::now() + 100_ms;
@@ -704,8 +673,7 @@
   transport->setSendQueueLength(50000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 11);
-  lp::Packet pkt11;
-  BOOST_REQUIRE_NO_THROW(pkt11.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt11(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt11.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -719,8 +687,7 @@
   transport->setSendQueueLength(33000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 12);
-  lp::Packet pkt12;
-  BOOST_REQUIRE_NO_THROW(pkt12.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt12(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt12.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt12.get<lp::CongestionMarkField>(), 1);
   markingInterval = time::nanoseconds(
@@ -737,8 +704,7 @@
   transport->setSendQueueLength(10000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 13);
-  lp::Packet pkt13;
-  BOOST_REQUIRE_NO_THROW(pkt13.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt13(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt13.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -752,8 +718,7 @@
   transport->setSendQueueLength(50000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 14);
-  lp::Packet pkt14;
-  BOOST_REQUIRE_NO_THROW(pkt14.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt14(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt14.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt14.get<lp::CongestionMarkField>(), 1);
   nextMarkTime = time::steady_clock::now() + 100_ms;
@@ -767,8 +732,7 @@
   transport->setSendQueueLength(5000);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 15);
-  lp::Packet pkt15;
-  BOOST_REQUIRE_NO_THROW(pkt15.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt15(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt15.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_lastMarkTime, lastMarkTime);
@@ -795,8 +759,7 @@
   transport->setSendQueueLength(0);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
-  lp::Packet pkt1;
-  BOOST_REQUIRE_NO_THROW(pkt1.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt1(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt1.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
@@ -806,8 +769,7 @@
   transport->setSendQueueLength(65536);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
-  lp::Packet pkt2;
-  BOOST_REQUIRE_NO_THROW(pkt2.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt2(transport->sentPackets.back().packet);
   BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
   BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::TimePoint::max());
   BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
@@ -817,8 +779,7 @@
   transport->setSendQueueLength(65537);
   face->sendInterest(*interest, 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
-  lp::Packet pkt3;
-  BOOST_REQUIRE_NO_THROW(pkt3.wireDecode(transport->sentPackets.back().packet));
+  lp::Packet pkt3(transport->sentPackets.back().packet);
   BOOST_REQUIRE_EQUAL(pkt3.count<lp::CongestionMarkField>(), 1);
   BOOST_CHECK_EQUAL(pkt3.get<lp::CongestionMarkField>(), 1);
   time::steady_clock::TimePoint nextMarkTime = time::steady_clock::now() + 100_ms;
@@ -1360,9 +1321,8 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  Block packet = ndn::encoding::makeEmptyBlock(tlv::Name);
-
-  BOOST_CHECK_NO_THROW(transport->receivePacket(std::move(packet)));
+  auto packet = ndn::encoding::makeEmptyBlock(tlv::Name);
+  transport->receivePacket(packet);
 
   BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 1);
   BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
@@ -1377,10 +1337,9 @@
   options.allowLocalFields = false;
   initialize(options);
 
-  Block packet = ndn::encoding::makeStringBlock(lp::tlv::LpPacket, "x");
+  auto packet = ndn::encoding::makeStringBlock(lp::tlv::LpPacket, "x");
   BOOST_CHECK_THROW(packet.parse(), tlv::Error);
-
-  BOOST_CHECK_NO_THROW(transport->receivePacket(std::move(packet)));
+  transport->receivePacket(packet);
 
   BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 1);
   BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
@@ -1390,7 +1349,6 @@
 
 BOOST_AUTO_TEST_SUITE_END() // Malformed
 
-
 BOOST_AUTO_TEST_SUITE_END() // TestGenericLinkService
 BOOST_AUTO_TEST_SUITE_END() // Face
 
diff --git a/tests/daemon/face/lp-reliability.t.cpp b/tests/daemon/face/lp-reliability.t.cpp
index 2b3a48e..a4ec6d3 100644
--- a/tests/daemon/face/lp-reliability.t.cpp
+++ b/tests/daemon/face/lp-reliability.t.cpp
@@ -86,7 +86,7 @@
   }
 
   void
-  doReceivePacket(Transport::Packet&&) final
+  doReceivePacket(const Block&, const EndpointId&) final
   {
     BOOST_ASSERT(false);
   }
diff --git a/tests/daemon/face/multicast-ethernet-transport.t.cpp b/tests/daemon/face/multicast-ethernet-transport.t.cpp
index 4961a69..8dde05f 100644
--- a/tests/daemon/face/multicast-ethernet-transport.t.cpp
+++ b/tests/daemon/face/multicast-ethernet-transport.t.cpp
@@ -68,22 +68,22 @@
   BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
 
   // simulate 'ip link set IFNAME down'
-  getScheduler().schedule(10_ms, [=] { netif->setState(ndn::net::InterfaceState::DOWN); });
-  transport->afterStateChange.connectSingleShot([&] (TransportState oldState, TransportState newState) {
+  getScheduler().schedule(10_ms, [this] { netif->setState(ndn::net::InterfaceState::DOWN); });
+  transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::DOWN);
-    limitedIo.afterOp();
+    this->limitedIo.afterOp();
   });
   BOOST_CHECK_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
   BOOST_CHECK_EQUAL(transport->getState(), TransportState::DOWN);
 
   // simulate 'ip link set IFNAME up'
-  getScheduler().schedule(10_ms, [=] { netif->setState(ndn::net::InterfaceState::NO_CARRIER); });
-  getScheduler().schedule(80_ms, [=] { netif->setState(ndn::net::InterfaceState::RUNNING); });
-  transport->afterStateChange.connectSingleShot([&] (TransportState oldState, TransportState newState) {
+  getScheduler().schedule(10_ms, [this] { netif->setState(ndn::net::InterfaceState::NO_CARRIER); });
+  getScheduler().schedule(80_ms, [this] { netif->setState(ndn::net::InterfaceState::RUNNING); });
+  transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::DOWN);
     BOOST_CHECK_EQUAL(newState, TransportState::UP);
-    limitedIo.afterOp();
+    this->limitedIo.afterOp();
   });
   BOOST_CHECK_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
   BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
@@ -94,17 +94,17 @@
   SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
   initializeMulticast();
 
-  transport->afterStateChange.connectSingleShot([] (TransportState oldState, TransportState newState) {
+  transport->afterStateChange.connectSingleShot([] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
   });
 
   transport->close();
 
-  transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
-    limitedIo.afterOp();
+    this->limitedIo.afterOp();
   });
 
   BOOST_REQUIRE_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
diff --git a/tests/daemon/face/multicast-udp-transport-fixture.hpp b/tests/daemon/face/multicast-udp-transport-fixture.hpp
index cdcb26a..99d039c 100644
--- a/tests/daemon/face/multicast-udp-transport-fixture.hpp
+++ b/tests/daemon/face/multicast-udp-transport-fixture.hpp
@@ -111,7 +111,7 @@
   sendToGroup(udp::socket& sock, const std::vector<uint8_t>& buf, bool needToCheck = true) const
   {
     sock.async_send_to(boost::asio::buffer(buf), remoteMcastEp,
-      [needToCheck] (const boost::system::error_code& error, size_t) {
+      [needToCheck] (const auto& error, size_t) {
         if (needToCheck) {
           BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
         }
@@ -123,7 +123,7 @@
   MulticastUdpTransport* transport;
   udp::endpoint mcastEp;
   uint16_t txPort;
-  std::vector<Transport::Packet>* receivedPackets;
+  std::vector<RxPacket>* receivedPackets;
 
 private:
   unique_ptr<Face> face;
diff --git a/tests/daemon/face/multicast-udp-transport.t.cpp b/tests/daemon/face/multicast-udp-transport.t.cpp
index 80d4c30..636bdc5 100644
--- a/tests/daemon/face/multicast-udp-transport.t.cpp
+++ b/tests/daemon/face/multicast-udp-transport.t.cpp
@@ -93,8 +93,8 @@
   BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
 
   BOOST_REQUIRE_EQUAL(this->receivedPackets->size(), 2);
-  BOOST_CHECK_EQUAL(this->receivedPackets->at(0).remoteEndpoint,
-                    this->receivedPackets->at(1).remoteEndpoint);
+  BOOST_CHECK_EQUAL(this->receivedPackets->at(0).endpoint,
+                    this->receivedPackets->at(1).endpoint);
 
   this->sendToGroup(remoteSockTx2, buf1);
   this->sendToGroup(remoteSockTx2, buf2);
@@ -105,10 +105,10 @@
   BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
 
   BOOST_REQUIRE_EQUAL(this->receivedPackets->size(), 4);
-  BOOST_CHECK_EQUAL(this->receivedPackets->at(2).remoteEndpoint,
-                    this->receivedPackets->at(3).remoteEndpoint);
-  BOOST_CHECK_NE(this->receivedPackets->at(0).remoteEndpoint,
-                 this->receivedPackets->at(2).remoteEndpoint);
+  BOOST_CHECK_EQUAL(this->receivedPackets->at(2).endpoint,
+                    this->receivedPackets->at(3).endpoint);
+  BOOST_CHECK_NE(this->receivedPackets->at(0).endpoint,
+                 this->receivedPackets->at(2).endpoint);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestMulticastUdpTransport
diff --git a/tests/daemon/face/stream-transport.t.cpp b/tests/daemon/face/stream-transport.t.cpp
index de32a4d..2a1d554 100644
--- a/tests/daemon/face/stream-transport.t.cpp
+++ b/tests/daemon/face/stream-transport.t.cpp
@@ -47,12 +47,12 @@
   TRANSPORT_TEST_INIT();
 
   auto block1 = ndn::encoding::makeStringBlock(300, "hello");
-  this->transport->send(Transport::Packet{Block{block1}}); // make a copy of the block
+  this->transport->send(block1);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 1);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutBytes, block1.size());
 
   auto block2 = ndn::encoding::makeStringBlock(301, "world");
-  this->transport->send(Transport::Packet{Block{block2}}); // make a copy of the block
+  this->transport->send(block2);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 2);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutBytes, block1.size() + block2.size());
 
@@ -74,21 +74,33 @@
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt = ndn::encoding::makeStringBlock(300, "hello");
-  ndn::Buffer buf(pkt.begin(), pkt.end());
-  this->remoteWrite(buf);
+  auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  ndn::Buffer buf1(pkt1.begin(), pkt1.end());
+  this->remoteWrite(buf1);
 
   BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 1);
-  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt.size());
-  BOOST_CHECK_EQUAL(this->receivedPackets->size(), 1);
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size());
+
+  auto pkt2 = ndn::encoding::makeStringBlock(301, "world!");
+  ndn::Buffer buf2(pkt2.begin(), pkt2.end());
+  this->remoteWrite(buf2);
+
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 2);
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size() + pkt2.size());
   BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
+
+  BOOST_REQUIRE_EQUAL(this->receivedPackets->size(), 2);
+  BOOST_CHECK(this->receivedPackets->at(0).packet == pkt1);
+  BOOST_CHECK(this->receivedPackets->at(1).packet == pkt2);
+  BOOST_CHECK_EQUAL(this->receivedPackets->at(0).endpoint, 0);
+  BOOST_CHECK_EQUAL(this->receivedPackets->at(1).endpoint, 0);
 }
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(ReceiveMultipleSegments, T, StreamTransportFixtures, T)
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt = ndn::encoding::makeStringBlock(300, "hello");
+  auto pkt = ndn::encoding::makeStringBlock(300, "hello");
   ndn::Buffer buf1(pkt.begin(), pkt.end() - 2);
   ndn::Buffer buf2(pkt.end() - 2, pkt.end());
 
@@ -111,8 +123,8 @@
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
-  Block pkt2 = ndn::encoding::makeStringBlock(301, "world");
+  auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  auto pkt2 = ndn::encoding::makeStringBlock(301, "world");
   ndn::Buffer buf(pkt1.size() + pkt2.size());
   std::copy(pkt1.begin(), pkt1.end(), buf.begin());
   std::copy(pkt2.begin(), pkt2.end(), buf.begin() + pkt1.size());
@@ -130,11 +142,11 @@
   TRANSPORT_TEST_INIT();
 
   std::vector<uint8_t> bytes(ndn::MAX_NDN_PACKET_SIZE, 0);
-  Block pkt1 = ndn::encoding::makeBinaryBlock(300, bytes.data(), bytes.size() - 6);
+  auto pkt1 = ndn::encoding::makeBinaryBlock(300, bytes.data(), bytes.size() - 6);
   ndn::Buffer buf1(pkt1.begin(), pkt1.end());
   BOOST_REQUIRE_EQUAL(buf1.size(), ndn::MAX_NDN_PACKET_SIZE);
 
-  Block pkt2 = ndn::encoding::makeBinaryBlock(301, bytes.data(), bytes.size());
+  auto pkt2 = ndn::encoding::makeBinaryBlock(301, bytes.data(), bytes.size());
   ndn::Buffer buf2(pkt2.begin(), pkt2.end());
   BOOST_REQUIRE_GT(buf2.size(), ndn::MAX_NDN_PACKET_SIZE);
 
@@ -147,7 +159,7 @@
 
   int nStateChanges = 0;
   this->transport->afterStateChange.connect(
-    [&nStateChanges] (TransportState oldState, TransportState newState) {
+    [&nStateChanges] (auto oldState, auto newState) {
       switch (nStateChanges) {
       case 0:
         BOOST_CHECK_EQUAL(oldState, TransportState::UP);
@@ -176,14 +188,14 @@
 {
   TRANSPORT_TEST_INIT();
 
-  this->transport->afterStateChange.connectSingleShot([] (TransportState oldState, TransportState newState) {
+  this->transport->afterStateChange.connectSingleShot([] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
   });
 
   this->transport->close();
 
-  this->transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  this->transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
     this->limitedIo.afterOp();
@@ -196,7 +208,7 @@
 {
   TRANSPORT_TEST_INIT();
 
-  this->transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  this->transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
     this->limitedIo.afterOp();
@@ -205,7 +217,7 @@
   this->remoteSocket.close();
   BOOST_REQUIRE_EQUAL(this->limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
 
-  this->transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  this->transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
     this->limitedIo.afterOp();
diff --git a/tests/daemon/face/tcp-transport-fixture.hpp b/tests/daemon/face/tcp-transport-fixture.hpp
index 77208e5..4b382a8 100644
--- a/tests/daemon/face/tcp-transport-fixture.hpp
+++ b/tests/daemon/face/tcp-transport-fixture.hpp
@@ -110,7 +110,7 @@
   remoteWrite(const std::vector<uint8_t>& buf, bool needToCheck = true)
   {
     boost::asio::async_write(remoteSocket, boost::asio::buffer(buf),
-      [needToCheck] (const boost::system::error_code& error, size_t) {
+      [needToCheck] (const auto& error, size_t) {
         if (needToCheck) {
           BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
         }
@@ -123,7 +123,7 @@
   TcpTransport* transport;
   tcp::endpoint localEp;
   tcp::socket remoteSocket;
-  std::vector<Transport::Packet>* receivedPackets;
+  std::vector<RxPacket>* receivedPackets;
 
 private:
   tcp::acceptor acceptor;
diff --git a/tests/daemon/face/tcp-transport.t.cpp b/tests/daemon/face/tcp-transport.t.cpp
index 81da009..1ad0b70 100644
--- a/tests/daemon/face/tcp-transport.t.cpp
+++ b/tests/daemon/face/tcp-transport.t.cpp
@@ -74,17 +74,17 @@
   TRANSPORT_TEST_INIT(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
 
   transport->afterStateChange.connectSingleShot(
-    [this] (TransportState oldState, TransportState newState) {
+    [this] (auto oldState, auto newState) {
       BOOST_CHECK_EQUAL(oldState, TransportState::UP);
       BOOST_CHECK_EQUAL(newState, TransportState::DOWN);
-      limitedIo.afterOp();
+      this->limitedIo.afterOp();
     });
   remoteSocket.close();
   BOOST_REQUIRE_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
 
   bool didStateChange = false;
   transport->afterStateChange.connectSingleShot(
-    [&didStateChange] (TransportState oldState, TransportState newState) {
+    [&didStateChange] (auto oldState, auto newState) {
       didStateChange = true;
       BOOST_CHECK_EQUAL(oldState, TransportState::DOWN);
       BOOST_CHECK_EQUAL(newState, TransportState::FAILED);
@@ -98,7 +98,7 @@
   TRANSPORT_TEST_INIT(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
 
   this->transport->afterStateChange.connectSingleShot(
-    [this] (TransportState oldState, TransportState newState) {
+    [this] (auto oldState, auto newState) {
       BOOST_CHECK_EQUAL(oldState, TransportState::UP);
       BOOST_CHECK_EQUAL(newState, TransportState::DOWN);
       this->limitedIo.afterOp();
@@ -107,7 +107,7 @@
   BOOST_REQUIRE_EQUAL(this->limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
 
   this->transport->afterStateChange.connectSingleShot(
-    [this] (TransportState oldState, TransportState newState) {
+    [this] (auto oldState, auto newState) {
       BOOST_CHECK_EQUAL(oldState, TransportState::DOWN);
       BOOST_CHECK_EQUAL(newState, TransportState::UP);
       this->limitedIo.afterOp();
@@ -156,7 +156,7 @@
 };
 
 static double
-asFloatMilliseconds(const time::nanoseconds& t)
+asFloatMilliseconds(time::nanoseconds t)
 {
   return static_cast<double>(t.count()) / 1000000.0;
 }
diff --git a/tests/daemon/face/transport.t.cpp b/tests/daemon/face/transport.t.cpp
index 348348d..6bb5896 100644
--- a/tests/daemon/face/transport.t.cpp
+++ b/tests/daemon/face/transport.t.cpp
@@ -181,15 +181,6 @@
 class DummyTransportFixture : public GlobalIoFixture
 {
 protected:
-  DummyTransportFixture()
-    : transport(nullptr)
-    , sentPackets(nullptr)
-    , receivedPackets(nullptr)
-  {
-    // Constructor does not initialize the fixture,
-    // so that test case may specify different parameters to DummyTransport constructor.
-  }
-
   void
   initialize(unique_ptr<DummyTransport> t = make_unique<DummyTransport>())
   {
@@ -201,9 +192,9 @@
 
 protected:
   unique_ptr<nfd::Face> face;
-  DummyTransport* transport;
-  std::vector<Transport::Packet>* sentPackets;
-  std::vector<Transport::Packet>* receivedPackets;
+  DummyTransport* transport = nullptr;
+  const std::vector<TxPacket>* sentPackets = nullptr;
+  const std::vector<RxPacket>* receivedPackets = nullptr;
 };
 
 BOOST_FIXTURE_TEST_CASE(Send, DummyTransportFixture)
@@ -211,18 +202,18 @@
   this->initialize();
 
   Block pkt1 = ndn::encoding::makeStringBlock(300, "Lorem ipsum dolor sit amet,");
-  transport->send(Transport::Packet(Block(pkt1)));
+  transport->send(pkt1);
 
   Block pkt2 = ndn::encoding::makeStringBlock(301, "consectetur adipiscing elit,");
-  transport->send(Transport::Packet(Block(pkt2)));
+  transport->send(pkt2);
 
   transport->setState(TransportState::DOWN);
   Block pkt3 = ndn::encoding::makeStringBlock(302, "sed do eiusmod tempor incididunt ");
-  transport->send(Transport::Packet(Block(pkt3)));
+  transport->send(pkt3);
 
   transport->setState(TransportState::CLOSING);
   Block pkt4 = ndn::encoding::makeStringBlock(303, "ut labore et dolore magna aliqua.");
-  transport->send(Transport::Packet(Block(pkt4)));
+  transport->send(pkt4);
 
   BOOST_CHECK_EQUAL(transport->getCounters().nOutPackets, 2);
   BOOST_CHECK_EQUAL(transport->getCounters().nOutBytes, pkt1.size() + pkt2.size());
diff --git a/tests/daemon/face/udp-channel-fixture.hpp b/tests/daemon/face/udp-channel-fixture.hpp
index 81d75f3..5192a97 100644
--- a/tests/daemon/face/udp-channel-fixture.hpp
+++ b/tests/daemon/face/udp-channel-fixture.hpp
@@ -56,8 +56,7 @@
           BOOST_REQUIRE(newFace != nullptr);
           connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
           clientFaces.push_back(newFace);
-          face::Transport::Packet pkt(ndn::encoding::makeStringBlock(300, "hello"));
-          newFace->getTransport()->send(std::move(pkt));
+          newFace->getTransport()->send(ndn::encoding::makeStringBlock(300, "hello"));
           limitedIo.afterOp();
         },
         ChannelFixture::unexpectedFailure);
diff --git a/tests/daemon/face/unicast-ethernet-transport.t.cpp b/tests/daemon/face/unicast-ethernet-transport.t.cpp
index 0a4885d..355a3ea 100644
--- a/tests/daemon/face/unicast-ethernet-transport.t.cpp
+++ b/tests/daemon/face/unicast-ethernet-transport.t.cpp
@@ -76,17 +76,17 @@
   SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
   initializeUnicast();
 
-  transport->afterStateChange.connectSingleShot([] (TransportState oldState, TransportState newState) {
+  transport->afterStateChange.connectSingleShot([] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSING);
   });
 
   transport->close();
 
-  transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::CLOSING);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
-    limitedIo.afterOp();
+    this->limitedIo.afterOp();
   });
 
   BOOST_REQUIRE_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
@@ -99,7 +99,7 @@
 
   int nStateChanges = 0;
   transport->afterStateChange.connect(
-    [this, &nStateChanges] (TransportState oldState, TransportState newState) {
+    [this, &nStateChanges] (auto oldState, auto newState) {
       switch (nStateChanges) {
       case 0:
         BOOST_CHECK_EQUAL(oldState, TransportState::UP);
@@ -113,7 +113,7 @@
         BOOST_CHECK(false);
       }
       nStateChanges++;
-      limitedIo.afterOp();
+      this->limitedIo.afterOp();
     });
 
   BOOST_REQUIRE_EQUAL(limitedIo.run(2, 5_s), LimitedIo::EXCEED_OPS);
diff --git a/tests/daemon/face/unicast-udp-transport-fixture.hpp b/tests/daemon/face/unicast-udp-transport-fixture.hpp
index f9c8728..ce9006d 100644
--- a/tests/daemon/face/unicast-udp-transport-fixture.hpp
+++ b/tests/daemon/face/unicast-udp-transport-fixture.hpp
@@ -96,7 +96,7 @@
   remoteWrite(const std::vector<uint8_t>& buf, bool needToCheck = true)
   {
     remoteSocket.async_send(boost::asio::buffer(buf),
-      [needToCheck] (const boost::system::error_code& error, size_t) {
+      [needToCheck] (const auto& error, size_t) {
         if (needToCheck) {
           BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
         }
@@ -109,7 +109,7 @@
   UnicastUdpTransport* transport;
   udp::endpoint localEp;
   udp::socket remoteSocket;
-  std::vector<Transport::Packet>* receivedPackets;
+  std::vector<RxPacket>* receivedPackets;
 
 private:
   unique_ptr<Face> face;
diff --git a/tests/daemon/face/unicast-udp-transport.t.cpp b/tests/daemon/face/unicast-udp-transport.t.cpp
index 9ef5b95..e5962db 100644
--- a/tests/daemon/face/unicast-udp-transport.t.cpp
+++ b/tests/daemon/face/unicast-udp-transport.t.cpp
@@ -84,7 +84,7 @@
 
   int nStateChanges = 0;
   transport->afterStateChange.connect(
-    [this, &nStateChanges] (TransportState oldState, TransportState newState) {
+    [this, &nStateChanges] (auto oldState, auto newState) {
       switch (nStateChanges) {
       case 0:
         BOOST_CHECK_EQUAL(oldState, TransportState::UP);
@@ -98,7 +98,7 @@
         BOOST_CHECK(false);
       }
       nStateChanges++;
-      limitedIo.afterOp();
+      this->limitedIo.afterOp();
     });
 
   BOOST_REQUIRE_EQUAL(limitedIo.run(2, 8_s), LimitedIo::EXCEED_OPS);
@@ -115,18 +115,17 @@
 {
   TRANSPORT_TEST_INIT(Persistency::value);
 
-  transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::UP);
     BOOST_CHECK_EQUAL(newState, TransportState::FAILED);
     this->limitedIo.afterOp();
   });
 
   remoteSocket.close();
-  Transport::Packet pkt(ndn::encoding::makeStringBlock(300, "hello"));
-  transport->send(std::move(pkt)); // trigger ICMP error
+  transport->send(ndn::encoding::makeStringBlock(300, "hello")); // trigger ICMP error
   BOOST_REQUIRE_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
 
-  transport->afterStateChange.connectSingleShot([this] (TransportState oldState, TransportState newState) {
+  transport->afterStateChange.connectSingleShot([this] (auto oldState, auto newState) {
     BOOST_CHECK_EQUAL(oldState, TransportState::FAILED);
     BOOST_CHECK_EQUAL(newState, TransportState::CLOSED);
     this->limitedIo.afterOp();
@@ -142,7 +141,7 @@
   remoteSocket.close();
 
   Block block1 = ndn::encoding::makeStringBlock(300, "hello");
-  transport->send(Transport::Packet{Block{block1}}); // make a copy of the block
+  transport->send(block1);
   BOOST_CHECK_EQUAL(transport->getCounters().nOutPackets, 1);
   BOOST_CHECK_EQUAL(transport->getCounters().nOutBytes, block1.size());
 
@@ -151,7 +150,7 @@
 
   remoteConnect();
 
-  transport->send(Transport::Packet{Block{block1}}); // make a copy of the block
+  transport->send(block1);
   BOOST_CHECK_EQUAL(transport->getCounters().nOutPackets, 2);
   BOOST_CHECK_EQUAL(transport->getCounters().nOutBytes, 2 * block1.size());
 
diff --git a/tests/daemon/face/unix-stream-transport-fixture.hpp b/tests/daemon/face/unix-stream-transport-fixture.hpp
index 17202f6..6724085 100644
--- a/tests/daemon/face/unix-stream-transport-fixture.hpp
+++ b/tests/daemon/face/unix-stream-transport-fixture.hpp
@@ -124,7 +124,7 @@
   remoteWrite(const ndn::Buffer& buf, bool needToCheck = true)
   {
     boost::asio::async_write(remoteSocket, boost::asio::buffer(buf),
-      [needToCheck] (const boost::system::error_code& error, size_t) {
+      [needToCheck] (const auto& error, size_t) {
         if (needToCheck) {
           BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
         }
@@ -137,7 +137,7 @@
   UnixStreamTransport* transport;
   unix_stream::endpoint localEp;
   unix_stream::socket remoteSocket;
-  std::vector<Transport::Packet>* receivedPackets;
+  std::vector<RxPacket>* receivedPackets;
 
 private:
   AcceptorWithCleanup acceptor;
diff --git a/tests/daemon/face/websocket-channel.t.cpp b/tests/daemon/face/websocket-channel.t.cpp
index d4d9c74..0631efa 100644
--- a/tests/daemon/face/websocket-channel.t.cpp
+++ b/tests/daemon/face/websocket-channel.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -27,6 +27,7 @@
 #include "face/websocket-transport.hpp"
 
 #include "test-ip.hpp"
+
 #include <boost/mpl/vector.hpp>
 
 namespace nfd {
@@ -101,12 +102,12 @@
   auto transport = listenerFaces.at(0)->getTransport();
 
   Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
-  transport->send(Transport::Packet(Block(pkt1)));
+  transport->send(pkt1);
   BOOST_CHECK_EQUAL(limitedIo.run(1, // clientHandleMessage
                                   1_s), LimitedIo::EXCEED_OPS);
 
   Block pkt2 = ndn::encoding::makeStringBlock(301, "world!");
-  transport->send(Transport::Packet(Block(pkt2)));
+  transport->send(pkt2);
   BOOST_CHECK_EQUAL(limitedIo.run(1, // clientHandleMessage
                                   1_s), LimitedIo::EXCEED_OPS);
 
diff --git a/tests/daemon/face/websocket-transport-fixture.hpp b/tests/daemon/face/websocket-transport-fixture.hpp
index e49d421..32934ab 100644
--- a/tests/daemon/face/websocket-transport-fixture.hpp
+++ b/tests/daemon/face/websocket-transport-fixture.hpp
@@ -203,7 +203,7 @@
   websocketpp::connection_hdl serverHdl;
   ip::tcp::endpoint remoteEp;
   WebSocketTransport* transport;
-  std::vector<Transport::Packet>* serverReceivedPackets;
+  std::vector<RxPacket>* serverReceivedPackets;
 
   websocket::Client client;
   websocketpp::connection_hdl clientHdl;
diff --git a/tests/daemon/face/websocket-transport.t.cpp b/tests/daemon/face/websocket-transport.t.cpp
index 657df71..c0b8367 100644
--- a/tests/daemon/face/websocket-transport.t.cpp
+++ b/tests/daemon/face/websocket-transport.t.cpp
@@ -117,14 +117,14 @@
   TRANSPORT_TEST_INIT();
 
   auto block1 = ndn::encoding::makeStringBlock(300, "hello");
-  this->transport->send(Transport::Packet{Block{block1}}); // make a copy of the block
+  this->transport->send(block1);
   BOOST_CHECK_EQUAL(this->limitedIo.run(1, // clientHandleMessage
                                         1_s), LimitedIo::EXCEED_OPS);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 1);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutBytes, block1.size());
 
   auto block2 = ndn::encoding::makeStringBlock(301, "world");
-  this->transport->send(Transport::Packet{Block{block2}}); // make a copy of the block
+  this->transport->send(block2);
   BOOST_CHECK_EQUAL(this->limitedIo.run(1, // clientHandleMessage
                                         1_s), LimitedIo::EXCEED_OPS);
   BOOST_CHECK_EQUAL(this->transport->getCounters().nOutPackets, 2);
@@ -146,12 +146,15 @@
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
   this->client.send(this->clientHdl, pkt1.wire(), pkt1.size(), websocketpp::frame::opcode::binary);
   BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
                                         1_s), LimitedIo::EXCEED_OPS);
 
-  Block pkt2 = ndn::encoding::makeStringBlock(301, "world!");
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 1);
+  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, pkt1.size());
+
+  auto pkt2 = ndn::encoding::makeStringBlock(301, "world!");
   this->client.send(this->clientHdl, pkt2.wire(), pkt2.size(), websocketpp::frame::opcode::binary);
   BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
                                         1_s), LimitedIo::EXCEED_OPS);
@@ -163,15 +166,15 @@
   BOOST_REQUIRE_EQUAL(this->serverReceivedPackets->size(), 2);
   BOOST_CHECK(this->serverReceivedPackets->at(0).packet == pkt1);
   BOOST_CHECK(this->serverReceivedPackets->at(1).packet == pkt2);
-  BOOST_CHECK_EQUAL(this->serverReceivedPackets->at(0).remoteEndpoint,
-                    this->serverReceivedPackets->at(1).remoteEndpoint);
+  BOOST_CHECK_EQUAL(this->serverReceivedPackets->at(0).endpoint, 0);
+  BOOST_CHECK_EQUAL(this->serverReceivedPackets->at(1).endpoint, 0);
 }
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(ReceiveMalformed, T, WebSocketTransportFixtures, T)
 {
   TRANSPORT_TEST_INIT();
 
-  Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  auto pkt1 = ndn::encoding::makeStringBlock(300, "hello");
   this->client.send(this->clientHdl, pkt1.wire(), pkt1.size() - 1, // truncated
                     websocketpp::frame::opcode::binary);
   BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
@@ -181,7 +184,7 @@
   BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);
   BOOST_CHECK_EQUAL(this->serverReceivedPackets->size(), 0);
 
-  Block pkt2 = ndn::encoding::makeStringBlock(301, "world!");
+  auto pkt2 = ndn::encoding::makeStringBlock(301, "world!");
   this->client.send(this->clientHdl, pkt2.wire(), pkt2.size(), websocketpp::frame::opcode::binary);
   BOOST_CHECK_EQUAL(this->limitedIo.run(1, // serverHandleMessage
                                         1_s), LimitedIo::EXCEED_OPS);
@@ -198,7 +201,7 @@
 
   int nStateChanges = 0;
   this->transport->afterStateChange.connect(
-    [&nStateChanges] (TransportState oldState, TransportState newState) {
+    [&nStateChanges] (auto oldState, auto newState) {
       switch (nStateChanges) {
       case 0:
         BOOST_CHECK_EQUAL(oldState, TransportState::UP);
@@ -224,7 +227,7 @@
 
   int nStateChanges = 0;
   this->transport->afterStateChange.connect(
-    [&nStateChanges] (TransportState oldState, TransportState newState) {
+    [&nStateChanges] (auto oldState, auto newState) {
       switch (nStateChanges) {
       case 0:
         BOOST_CHECK_EQUAL(oldState, TransportState::UP);
diff --git a/tests/daemon/fw/topology-tester.cpp b/tests/daemon/fw/topology-tester.cpp
index 2c077ba..067e2b7 100644
--- a/tests/daemon/fw/topology-tester.cpp
+++ b/tests/daemon/fw/topology-tester.cpp
@@ -73,7 +73,7 @@
 void
 TopologyLink::addFace(TopologyNode i, shared_ptr<Face> face)
 {
-  auto receiveCb = [this, i] (Block&& pkt) { transmit(i, std::move(pkt)); };
+  auto receiveCb = [this, i] (const Block& packet) { transmit(i, packet); };
 
   auto ret = m_transports.emplace(std::piecewise_construct,
                                   std::forward_as_tuple(i),
@@ -85,7 +85,7 @@
 }
 
 void
-TopologyLink::transmit(TopologyNode i, Block&& packet)
+TopologyLink::transmit(TopologyNode i, const Block& packet)
 {
   if (!m_isUp) {
     return;
@@ -98,18 +98,12 @@
       continue;
     }
 
-    this->scheduleReceive(p.second.transport, Block{packet});
+    getScheduler().schedule(m_delay, [packet, recipient = p.second.transport] {
+      recipient->receivePacket(packet);
+    });
   }
 }
 
-void
-TopologyLink::scheduleReceive(face::InternalTransportBase* recipient, Block&& packet)
-{
-  getScheduler().schedule(m_delay, [=, pkt = std::move(packet)] () mutable {
-    recipient->receivePacket(std::move(pkt));
-  });
-}
-
 TopologyAppLink::TopologyAppLink(shared_ptr<Face> forwarderFace)
   : m_face(std::move(forwarderFace))
   , m_forwarderTransport(static_cast<InternalForwarderTransport*>(m_face->getTransport()))
diff --git a/tests/daemon/fw/topology-tester.hpp b/tests/daemon/fw/topology-tester.hpp
index da4e488..233c216 100644
--- a/tests/daemon/fw/topology-tester.hpp
+++ b/tests/daemon/fw/topology-tester.hpp
@@ -108,10 +108,7 @@
 
 private:
   void
-  transmit(TopologyNode i, Block&& packet);
-
-  void
-  scheduleReceive(face::InternalTransportBase* recipient, Block&& packet);
+  transmit(TopologyNode i, const Block& packet);
 
 private:
   bool m_isUp = true;
@@ -120,7 +117,7 @@
   class ReceiveProxy : public face::InternalTransportBase
   {
   public:
-    using Callback = std::function<void(Block&&)>;
+    using Callback = std::function<void(const Block&)>;
 
     explicit
     ReceiveProxy(Callback cb)
@@ -129,9 +126,9 @@
     }
 
     void
-    receivePacket(Block&& packet) final
+    receivePacket(const Block& packet) final
     {
-      m_cb(std::move(packet));
+      m_cb(packet);
     }
 
   private: