face: simplify and optimize Internal{Forwarder,Client}Transport

Refs: #4528
Change-Id: Ie3246382965640e0d2cb71116b6526e68925887c
diff --git a/daemon/face/internal-transport.cpp b/daemon/face/internal-transport.cpp
index 3e9552c..5b3fcac 100644
--- a/daemon/face/internal-transport.cpp
+++ b/daemon/face/internal-transport.cpp
@@ -46,21 +46,21 @@
 }
 
 void
-InternalForwarderTransport::receiveFromLink(const Block& packet)
+InternalForwarderTransport::receivePacket(Block&& packet)
 {
-  NFD_LOG_FACE_TRACE(__func__);
-
-  Packet p;
-  p.packet = packet;
-  this->receive(std::move(p));
+  getGlobalIoService().post([this, pkt = std::move(packet)] () mutable {
+    NFD_LOG_FACE_TRACE("Received: " << pkt.size() << " bytes");
+    receive(Packet{std::move(pkt)});
+  });
 }
 
 void
 InternalForwarderTransport::doSend(Packet&& packet)
 {
-  NFD_LOG_FACE_TRACE(__func__);
+  NFD_LOG_FACE_TRACE("Sending to " << m_peer);
 
-  this->emitSignal(afterSend, packet.packet);
+  if (m_peer)
+    m_peer->receivePacket(std::move(packet.packet));
 }
 
 void
@@ -68,50 +68,59 @@
 {
   NFD_LOG_FACE_TRACE(__func__);
 
-  this->setState(TransportState::CLOSED);
+  setState(TransportState::CLOSED);
 }
 
-static void
-asyncReceive(InternalTransportBase* recipient, const Block& packet)
+InternalClientTransport::~InternalClientTransport()
 {
-  getGlobalIoService().post([packet, recipient] {
-    recipient->receiveFromLink(packet);
-  });
+  if (m_forwarder != nullptr) {
+    m_forwarder->setPeer(nullptr);
+  }
 }
 
 void
-InternalClientTransport::connectToForwarder(InternalForwarderTransport* forwarderTransport)
+InternalClientTransport::connectToForwarder(InternalForwarderTransport* forwarder)
 {
-  NFD_LOG_DEBUG(__func__ << " " << forwarderTransport);
+  NFD_LOG_DEBUG(__func__ << " " << forwarder);
 
-  m_fwToClientTransmitConn.disconnect();
-  m_clientToFwTransmitConn.disconnect();
-  m_fwTransportStateConn.disconnect();
+  if (m_forwarder != nullptr) {
+    // disconnect from the old forwarder transport
+    m_forwarder->setPeer(nullptr);
+    m_fwTransportStateConn.disconnect();
+  }
 
-  if (forwarderTransport != nullptr) {
-    m_fwToClientTransmitConn = forwarderTransport->afterSend.connect(bind(&asyncReceive, this, _1));
-    m_clientToFwTransmitConn = this->afterSend.connect(bind(&asyncReceive, forwarderTransport, _1));
-    m_fwTransportStateConn = forwarderTransport->afterStateChange.connect(
+  m_forwarder = forwarder;
+
+  if (m_forwarder != nullptr) {
+    // connect to the new forwarder transport
+    m_forwarder->setPeer(this);
+    m_fwTransportStateConn = m_forwarder->afterStateChange.connect(
       [this] (TransportState oldState, TransportState newState) {
         if (newState == TransportState::CLOSED) {
-          this->connectToForwarder(nullptr);
+          connectToForwarder(nullptr);
         }
       });
   }
 }
 
 void
-InternalClientTransport::receiveFromLink(const Block& packet)
+InternalClientTransport::receivePacket(Block&& packet)
 {
-  if (m_receiveCallback) {
-    m_receiveCallback(packet);
-  }
+  getGlobalIoService().post([this, pkt = std::move(packet)] {
+    NFD_LOG_TRACE("Received: " << pkt.size() << " bytes");
+    if (m_receiveCallback) {
+      m_receiveCallback(pkt);
+    }
+  });
 }
 
 void
 InternalClientTransport::send(const Block& wire)
 {
-  this->emitSignal(afterSend, wire);
+  NFD_LOG_TRACE("Sending to " << m_forwarder);
+
+  if (m_forwarder)
+    m_forwarder->receivePacket(Block{wire});
 }
 
 void
@@ -121,7 +130,7 @@
   encoder.appendByteArray(header.wire(), header.size());
   encoder.appendByteArray(payload.wire(), payload.size());
 
-  this->send(encoder.block());
+  send(encoder.block());
 }
 
 } // namespace face
diff --git a/daemon/face/internal-transport.hpp b/daemon/face/internal-transport.hpp
index 9f834d7..f859099 100644
--- a/daemon/face/internal-transport.hpp
+++ b/daemon/face/internal-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,
@@ -33,7 +33,7 @@
 namespace nfd {
 namespace face {
 
-/** \brief abstracts a transport that can be paired with another
+/** \brief Abstracts a transport that can be paired with another.
  */
 class InternalTransportBase
 {
@@ -41,49 +41,53 @@
   virtual
   ~InternalTransportBase() = default;
 
-  /** \brief causes the transport to receive a link-layer packet
-   */
   virtual void
-  receiveFromLink(const Block& packet) = 0;
-
-  signal::Signal<InternalTransportBase, Block> afterSend;
-
-protected:
-  DECLARE_SIGNAL_EMIT(afterSend)
+  receivePacket(Block&& packet) = 0;
 };
 
-/** \brief implements a forwarder-side transport that can be paired with another
+/** \brief Implements a forwarder-side transport that can be paired with another transport.
  */
-class InternalForwarderTransport : public Transport, public InternalTransportBase
+class InternalForwarderTransport final : public Transport, public InternalTransportBase
 {
 public:
+  explicit
   InternalForwarderTransport(const FaceUri& localUri = FaceUri("internal://"),
                              const FaceUri& remoteUri = FaceUri("internal://"),
                              ndn::nfd::FaceScope scope = ndn::nfd::FACE_SCOPE_LOCAL,
                              ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_POINT_TO_POINT);
 
   void
-  receiveFromLink(const Block& packet) override;
+  setPeer(InternalTransportBase* peer)
+  {
+    m_peer = peer;
+  }
+
+  void
+  receivePacket(Block&& packet) final;
 
 protected:
   void
-  doClose() override;
+  doClose() final;
 
 private:
   void
-  doSend(Packet&& packet) override;
+  doSend(Packet&& packet) final;
 
 private:
   NFD_LOG_MEMBER_DECL();
+
+  InternalTransportBase* m_peer = nullptr;
 };
 
-/** \brief implements a client-side transport that can be paired with another
+/** \brief Implements a client-side transport that can be paired with an InternalForwarderTransport.
  */
-class InternalClientTransport : public ndn::Transport, public InternalTransportBase
+class InternalClientTransport final : public ndn::Transport, public InternalTransportBase
 {
 public:
-  /** \brief connect to a forwarder-side transport
-   *  \param forwarderTransport the forwarder-side transport to connect to; may be nullptr
+  ~InternalClientTransport() final;
+
+  /** \brief Connect to a forwarder-side transport.
+   *  \param forwarder the forwarder-side transport to connect to; may be nullptr
    *
    *  The connected forwarder-side transport will be disconnected automatically if this method
    *  is called again, or if that transport is closed.
@@ -91,37 +95,36 @@
    *  all sent packets would be lost, and nothing would be received.
    */
   void
-  connectToForwarder(InternalForwarderTransport* forwarderTransport);
+  connectToForwarder(InternalForwarderTransport* forwarder);
 
   void
-  receiveFromLink(const Block& packet) override;
+  receivePacket(Block&& packet) final;
 
   void
-  close() override
+  send(const Block& wire) final;
+
+  void
+  send(const Block& header, const Block& payload) final;
+
+  void
+  close() final
   {
   }
 
   void
-  pause() override
+  pause() final
   {
   }
 
   void
-  resume() override
+  resume() final
   {
   }
 
-  void
-  send(const Block& wire) override;
-
-  void
-  send(const Block& header, const Block& payload) override;
-
 private:
   NFD_LOG_MEMBER_DECL();
 
-  signal::ScopedConnection m_fwToClientTransmitConn;
-  signal::ScopedConnection m_clientToFwTransmitConn;
+  InternalForwarderTransport* m_forwarder = nullptr;
   signal::ScopedConnection m_fwTransportStateConn;
 };