face: add EndpointId in Face and LinkService

refs: #4843

Change-Id: If1249015392ef904a56a0d0d97946e2b3024d7d4
diff --git a/daemon/fw/face-endpoint.hpp b/daemon/face/face-endpoint.hpp
similarity index 92%
rename from daemon/fw/face-endpoint.hpp
rename to daemon/face/face-endpoint.hpp
index acfbc2e..cf2c466 100644
--- a/daemon/fw/face-endpoint.hpp
+++ b/daemon/face/face-endpoint.hpp
@@ -23,10 +23,10 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef NFD_DAEMON_FW_FACE_ENDPOINT_HPP
-#define NFD_DAEMON_FW_FACE_ENDPOINT_HPP
+#ifndef NFD_DAEMON_FACE_FACE_ENDPOINT_HPP
+#define NFD_DAEMON_FACE_FACE_ENDPOINT_HPP
 
-#include "face/face.hpp"
+#include "face.hpp"
 
 namespace nfd {
 
@@ -54,4 +54,4 @@
 
 } // namespace nfd
 
-#endif // NFD_DAEMON_FW_FACE_ENDPOINT_HPP
\ No newline at end of file
+#endif // NFD_DAEMON_FACE_FACE_ENDPOINT_HPP
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index 440bb4d..e96bc31 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -76,32 +76,32 @@
   getTransport() const;
 
 public: // upper interface connected to forwarding
-  /** \brief sends Interest on Face
+  /** \brief send Interest to \p endpointId
    */
   void
-  sendInterest(const Interest& interest);
+  sendInterest(const Interest& interest, const EndpointId& endpointId);
 
-  /** \brief sends Data on Face
+  /** \brief send Data to \p endpointId
    */
   void
-  sendData(const Data& data);
+  sendData(const Data& data, const EndpointId& endpointId);
 
-  /** \brief sends Nack on Face
+  /** \brief send Nack to \p endpointId
    */
   void
-  sendNack(const lp::Nack& nack);
+  sendNack(const lp::Nack& nack, const EndpointId& endpointId);
 
   /** \brief signals on Interest received
    */
-  signal::Signal<LinkService, Interest>& afterReceiveInterest;
+  signal::Signal<LinkService, Interest, EndpointId>& afterReceiveInterest;
 
   /** \brief signals on Data received
    */
-  signal::Signal<LinkService, Data>& afterReceiveData;
+  signal::Signal<LinkService, Data, EndpointId>& afterReceiveData;
 
   /** \brief signals on Nack received
    */
-  signal::Signal<LinkService, lp::Nack>& afterReceiveNack;
+  signal::Signal<LinkService, lp::Nack, EndpointId>& afterReceiveNack;
 
   /** \brief signals on Interest dropped by reliability system for exceeding allowed number of retx
    */
@@ -201,21 +201,21 @@
 }
 
 inline void
-Face::sendInterest(const Interest& interest)
+Face::sendInterest(const Interest& interest, const EndpointId& endpointId)
 {
-  m_service->sendInterest(interest);
+  m_service->sendInterest(interest, endpointId);
 }
 
 inline void
-Face::sendData(const Data& data)
+Face::sendData(const Data& data, const EndpointId& endpointId)
 {
-  m_service->sendData(data);
+  m_service->sendData(data, endpointId);
 }
 
 inline void
-Face::sendNack(const lp::Nack& nack)
+Face::sendNack(const lp::Nack& nack, const EndpointId& endpointId)
 {
-  m_service->sendNack(nack);
+  m_service->sendNack(nack, endpointId);
 }
 
 inline FaceId
diff --git a/daemon/face/generic-link-service.cpp b/daemon/face/generic-link-service.cpp
index 55ec6ee..09b874c 100644
--- a/daemon/face/generic-link-service.cpp
+++ b/daemon/face/generic-link-service.cpp
@@ -65,15 +65,15 @@
 }
 
 void
-GenericLinkService::requestIdlePacket()
+GenericLinkService::requestIdlePacket(const EndpointId& endpointId)
 {
   // No need to request Acks to attach to this packet from LpReliability, as they are already
   // attached in sendLpPacket
-  this->sendLpPacket({});
+  this->sendLpPacket({}, endpointId);
 }
 
 void
-GenericLinkService::sendLpPacket(lp::Packet&& pkt)
+GenericLinkService::sendLpPacket(lp::Packet&& pkt, const EndpointId& endpointId)
 {
   const ssize_t mtu = this->getTransport()->getMtu();
 
@@ -91,38 +91,38 @@
     NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
     return;
   }
-  this->sendPacket(std::move(tp));
+  this->sendPacket(std::move(tp), endpointId);
 }
 
 void
-GenericLinkService::doSendInterest(const Interest& interest)
+GenericLinkService::doSendInterest(const Interest& interest, const EndpointId& endpointId)
 {
   lp::Packet lpPacket(interest.wireEncode());
 
   encodeLpFields(interest, lpPacket);
 
-  this->sendNetPacket(std::move(lpPacket), true);
+  this->sendNetPacket(std::move(lpPacket), endpointId, true);
 }
 
 void
-GenericLinkService::doSendData(const Data& data)
+GenericLinkService::doSendData(const Data& data, const EndpointId& endpointId)
 {
   lp::Packet lpPacket(data.wireEncode());
 
   encodeLpFields(data, lpPacket);
 
-  this->sendNetPacket(std::move(lpPacket), false);
+  this->sendNetPacket(std::move(lpPacket), endpointId, false);
 }
 
 void
-GenericLinkService::doSendNack(const lp::Nack& nack)
+GenericLinkService::doSendNack(const lp::Nack& nack, const EndpointId& endpointId)
 {
   lp::Packet lpPacket(nack.getInterest().wireEncode());
   lpPacket.add<lp::NackField>(nack.getHeader());
 
   encodeLpFields(nack, lpPacket);
 
-  this->sendNetPacket(std::move(lpPacket), false);
+  this->sendNetPacket(std::move(lpPacket), endpointId, false);
 }
 
 void
@@ -154,7 +154,7 @@
 }
 
 void
-GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
+GenericLinkService::sendNetPacket(lp::Packet&& pkt, const EndpointId& endpointId, bool isInterest)
 {
   std::vector<lp::Packet> frags;
   ssize_t mtu = this->getTransport()->getMtu();
@@ -206,7 +206,7 @@
   }
 
   for (lp::Packet& frag : frags) {
-    this->sendLpPacket(std::move(frag));
+    this->sendLpPacket(std::move(frag), endpointId);
   }
 }
 
@@ -302,7 +302,7 @@
     std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(packet.remoteEndpoint,
                                                                               pkt);
     if (isReassembled) {
-      this->decodeNetPacket(netPkt, firstPkt);
+      this->decodeNetPacket(netPkt, firstPkt, packet.remoteEndpoint);
     }
   }
   catch (const tlv::Error& e) {
@@ -312,20 +312,21 @@
 }
 
 void
-GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt)
+GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt,
+                                    const EndpointId& endpointId)
 {
   try {
     switch (netPkt.type()) {
       case tlv::Interest:
         if (firstPkt.has<lp::NackField>()) {
-          this->decodeNack(netPkt, firstPkt);
+          this->decodeNack(netPkt, firstPkt, endpointId);
         }
         else {
-          this->decodeInterest(netPkt, firstPkt);
+          this->decodeInterest(netPkt, firstPkt, endpointId);
         }
         break;
       case tlv::Data:
-        this->decodeData(netPkt, firstPkt);
+        this->decodeData(netPkt, firstPkt, endpointId);
         break;
       default:
         ++this->nInNetInvalid;
@@ -340,7 +341,8 @@
 }
 
 void
-GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt)
+GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt,
+                                   const EndpointId& endpointId)
 {
   BOOST_ASSERT(netPkt.type() == tlv::Interest);
   BOOST_ASSERT(!firstPkt.has<lp::NackField>());
@@ -387,11 +389,12 @@
     return;
   }
 
-  this->receiveInterest(*interest);
+  this->receiveInterest(*interest, endpointId);
 }
 
 void
-GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
+GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt,
+                               const EndpointId& endpointId)
 {
   BOOST_ASSERT(netPkt.type() == tlv::Data);
 
@@ -440,11 +443,12 @@
     }
   }
 
-  this->receiveData(*data);
+  this->receiveData(*data, endpointId);
 }
 
 void
-GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt)
+GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
+                               const EndpointId& endpointId)
 {
   BOOST_ASSERT(netPkt.type() == tlv::Interest);
   BOOST_ASSERT(firstPkt.has<lp::NackField>());
@@ -484,7 +488,7 @@
     return;
   }
 
-  this->receiveNack(nack);
+  this->receiveNack(nack, endpointId);
 }
 
 } // namespace face
diff --git a/daemon/face/generic-link-service.hpp b/daemon/face/generic-link-service.hpp
index c440932..c28b9ef 100644
--- a/daemon/face/generic-link-service.hpp
+++ b/daemon/face/generic-link-service.hpp
@@ -173,28 +173,27 @@
   /** \brief request an IDLE packet to transmit pending service fields
    */
   void
-  requestIdlePacket();
+  requestIdlePacket(const EndpointId& endpointId);
 
-  /** \brief send an LpPacket fragment
-   *  \param pkt LpPacket to send
+  /** \brief send an LpPacket to \p endpointId
    */
   void
-  sendLpPacket(lp::Packet&& pkt);
+  sendLpPacket(lp::Packet&& pkt, const EndpointId& endpointId);
 
   /** \brief send Interest
    */
   void
-  doSendInterest(const Interest& interest) OVERRIDE_WITH_TESTS_ELSE_FINAL;
+  doSendInterest(const Interest& interest, const EndpointId& endpointId) OVERRIDE_WITH_TESTS_ELSE_FINAL;
 
   /** \brief send Data
    */
   void
-  doSendData(const Data& data) OVERRIDE_WITH_TESTS_ELSE_FINAL;
+  doSendData(const Data& data, const EndpointId& endpointId) OVERRIDE_WITH_TESTS_ELSE_FINAL;
 
   /** \brief send Nack
    */
   void
-  doSendNack(const ndn::lp::Nack& nack) OVERRIDE_WITH_TESTS_ELSE_FINAL;
+  doSendNack(const ndn::lp::Nack& nack, const EndpointId& endpointId) OVERRIDE_WITH_TESTS_ELSE_FINAL;
 
 private: // send path
   /** \brief encode link protocol fields from tags onto an outgoing LpPacket
@@ -206,10 +205,11 @@
 
   /** \brief send a complete network layer packet
    *  \param pkt LpPacket containing a complete network layer packet
+   *  \param endpointId destination endpoint to which LpPacket will be sent
    *  \param isInterest whether the network layer packet is an Interest
    */
   void
-  sendNetPacket(lp::Packet&& pkt, bool isInterest);
+  sendNetPacket(lp::Packet&& pkt, const EndpointId& endpointId, bool isInterest);
 
   /** \brief assign a sequence number to an LpPacket
    */
@@ -237,16 +237,18 @@
   /** \brief decode incoming network-layer packet
    *  \param netPkt reassembled network-layer packet
    *  \param firstPkt LpPacket of first fragment
+   *  \param endpointId endpoint of peer who sent the packet
    *
    *  If decoding is successful, a receive signal is emitted;
    *  otherwise, a warning is logged.
    */
   void
-  decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt);
+  decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
 
   /** \brief decode incoming Interest
    *  \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
    *  \param firstPkt LpPacket of first fragment; must not have Nack field
+   *  \param endpointId endpoint of peer who sent the Interest
    *
    *  If decoding is successful, receiveInterest signal is emitted;
    *  otherwise, a warning is logged.
@@ -254,11 +256,12 @@
    *  \throw tlv::Error parse error in an LpHeader field
    */
   void
-  decodeInterest(const Block& netPkt, const lp::Packet& firstPkt);
+  decodeInterest(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
 
   /** \brief decode incoming Interest
    *  \param netPkt reassembled network-layer packet; TLV-TYPE must be Data
    *  \param firstPkt LpPacket of first fragment
+   *  \param endpointId endpoint of peer who sent the Data
    *
    *  If decoding is successful, receiveData signal is emitted;
    *  otherwise, a warning is logged.
@@ -266,11 +269,12 @@
    *  \throw tlv::Error parse error in an LpHeader field
    */
   void
-  decodeData(const Block& netPkt, const lp::Packet& firstPkt);
+  decodeData(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
 
   /** \brief decode incoming Interest
    *  \param netPkt reassembled network-layer packet; TLV-TYPE must be Interest
    *  \param firstPkt LpPacket of first fragment; must have Nack field
+   *  \param endpointId endpoint of peer who sent the Nack
    *
    *  If decoding is successful, receiveNack signal is emitted;
    *  otherwise, a warning is logged.
@@ -278,7 +282,7 @@
    *  \throw tlv::Error parse error in an LpHeader field
    */
   void
-  decodeNack(const Block& netPkt, const lp::Packet& firstPkt);
+  decodeNack(const Block& netPkt, const lp::Packet& firstPkt, const EndpointId& endpointId);
 
 PROTECTED_WITH_TESTS_ELSE_PRIVATE:
   Options m_options;
diff --git a/daemon/face/link-service.cpp b/daemon/face/link-service.cpp
index c5dcdfc..34abd58 100644
--- a/daemon/face/link-service.cpp
+++ b/daemon/face/link-service.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,
@@ -52,66 +52,66 @@
 }
 
 void
-LinkService::sendInterest(const Interest& interest)
+LinkService::sendInterest(const Interest& interest, const EndpointId& endpointId)
 {
   BOOST_ASSERT(m_transport != nullptr);
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nOutInterests;
 
-  doSendInterest(interest);
+  doSendInterest(interest, endpointId);
 }
 
 void
-LinkService::sendData(const Data& data)
+LinkService::sendData(const Data& data, const EndpointId& endpointId)
 {
   BOOST_ASSERT(m_transport != nullptr);
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nOutData;
 
-  doSendData(data);
+  doSendData(data, endpointId);
 }
 
 void
-LinkService::sendNack(const ndn::lp::Nack& nack)
+LinkService::sendNack(const ndn::lp::Nack& nack, const EndpointId& endpointId)
 {
   BOOST_ASSERT(m_transport != nullptr);
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nOutNacks;
 
-  doSendNack(nack);
+  doSendNack(nack, endpointId);
 }
 
 void
-LinkService::receiveInterest(const Interest& interest)
+LinkService::receiveInterest(const Interest& interest, const EndpointId& endpointId)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nInInterests;
 
-  afterReceiveInterest(interest);
+  afterReceiveInterest(interest, endpointId);
 }
 
 void
-LinkService::receiveData(const Data& data)
+LinkService::receiveData(const Data& data, const EndpointId& endpointId)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nInData;
 
-  afterReceiveData(data);
+  afterReceiveData(data, endpointId);
 }
 
 void
-LinkService::receiveNack(const ndn::lp::Nack& nack)
+LinkService::receiveNack(const ndn::lp::Nack& nack, const EndpointId& endpointId)
 {
   NFD_LOG_FACE_TRACE(__func__);
 
   ++this->nInNacks;
 
-  afterReceiveNack(nack);
+  afterReceiveNack(nack, endpointId);
 }
 
 void
diff --git a/daemon/face/link-service.hpp b/daemon/face/link-service.hpp
index 0caa857..fd77391 100644
--- a/daemon/face/link-service.hpp
+++ b/daemon/face/link-service.hpp
@@ -112,35 +112,35 @@
   getCounters() const;
 
 public: // upper interface to be used by forwarding
-  /** \brief send Interest
+  /** \brief send Interest to \p endpointId
    *  \pre setTransport has been called
    */
   void
-  sendInterest(const Interest& interest);
+  sendInterest(const Interest& interest, const EndpointId& endpointId);
 
-  /** \brief send Data
+  /** \brief send Data to \p endpointId
    *  \pre setTransport has been called
    */
   void
-  sendData(const Data& data);
+  sendData(const Data& data, const EndpointId& endpointId);
 
-  /** \brief send Nack
+  /** \brief send Nack to \p endpointId
    *  \pre setTransport has been called
    */
   void
-  sendNack(const ndn::lp::Nack& nack);
+  sendNack(const ndn::lp::Nack& nack, const EndpointId& endpointId);
 
   /** \brief signals on Interest received
    */
-  signal::Signal<LinkService, Interest> afterReceiveInterest;
+  signal::Signal<LinkService, Interest, EndpointId> afterReceiveInterest;
 
   /** \brief signals on Data received
    */
-  signal::Signal<LinkService, Data> afterReceiveData;
+  signal::Signal<LinkService, Data, EndpointId> afterReceiveData;
 
   /** \brief signals on Nack received
    */
-  signal::Signal<LinkService, lp::Nack> afterReceiveNack;
+  signal::Signal<LinkService, lp::Nack, EndpointId> afterReceiveNack;
 
   /** \brief signals on Interest dropped by reliability system for exceeding allowed number of retx
    */
@@ -156,43 +156,43 @@
   /** \brief delivers received Interest to forwarding
    */
   void
-  receiveInterest(const Interest& interest);
+  receiveInterest(const Interest& interest, const EndpointId& endpointId);
 
   /** \brief delivers received Data to forwarding
    */
   void
-  receiveData(const Data& data);
+  receiveData(const Data& data, const EndpointId& endpointId);
 
   /** \brief delivers received Nack to forwarding
    */
   void
-  receiveNack(const lp::Nack& nack);
+  receiveNack(const lp::Nack& nack, const EndpointId& endpointId);
 
 protected: // lower interface to be invoked in subclass (send path termination)
-  /** \brief sends a lower-layer packet via Transport
+  /** \brief send a lower-layer packet via Transport to \p endpointId
    */
   void
-  sendPacket(Transport::Packet&& packet);
+  sendPacket(Transport::Packet&& packet, const EndpointId& endpointId);
 
 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
+  /** \brief performs LinkService specific operations to send an Interest to \p endpointId
    */
   virtual void
-  doSendInterest(const Interest& interest) = 0;
+  doSendInterest(const Interest& interest, const EndpointId& endpointId) = 0;
 
-  /** \brief performs LinkService specific operations to send a Data
+  /** \brief performs LinkService specific operations to send a Data to \p endpointId
    */
   virtual void
-  doSendData(const Data& data) = 0;
+  doSendData(const Data& data, const EndpointId& endpointId) = 0;
 
-  /** \brief performs LinkService specific operations to send a Nack
+  /** \brief performs LinkService specific operations to send a Nack to \p endpointId
    */
   virtual void
-  doSendNack(const lp::Nack& nack) = 0;
+  doSendNack(const lp::Nack& nack, const EndpointId& endpointId) = 0;
 
 private: // lower interface to be overridden in subclass
   virtual void
@@ -234,8 +234,9 @@
 }
 
 inline void
-LinkService::sendPacket(Transport::Packet&& packet)
+LinkService::sendPacket(Transport::Packet&& packet, const EndpointId& endpointId)
 {
+  packet.remoteEndpoint = endpointId;
   m_transport->send(std::move(packet));
 }
 
diff --git a/daemon/face/lp-reliability.cpp b/daemon/face/lp-reliability.cpp
index 7f7ee14..f19f713 100644
--- a/daemon/face/lp-reliability.cpp
+++ b/daemon/face/lp-reliability.cpp
@@ -202,7 +202,7 @@
 
   m_idleAckTimer = getScheduler().schedule(m_options.idleAckTimerPeriod, [this] {
     while (!m_ackQueue.empty()) {
-      m_linkService->requestIdlePacket();
+      m_linkService->requestIdlePacket(0);
     }
 
     m_isIdleAckTimerRunning = false;
@@ -302,7 +302,7 @@
     deleteUnackedFrag(txSeqIt);
 
     // Retransmit fragment
-    m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt));
+    m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt), 0);
 
     // Start RTO timer for this sequence
     newTxFrag.rtoTimer = getScheduler().schedule(m_rto.computeRto(), [=] { onLpPacketLost(newTxSeq); });
diff --git a/daemon/face/null-link-service.hpp b/daemon/face/null-link-service.hpp
index 7a8e8ba..d31304b 100644
--- a/daemon/face/null-link-service.hpp
+++ b/daemon/face/null-link-service.hpp
@@ -37,17 +37,17 @@
 {
 private:
   void
-  doSendInterest(const Interest&) final
+  doSendInterest(const Interest&, const EndpointId&) final
   {
   }
 
   void
-  doSendData(const Data&) final
+  doSendData(const Data&, const EndpointId&) final
   {
   }
 
   void
-  doSendNack(const lp::Nack&) final
+  doSendNack(const lp::Nack&, const EndpointId&) final
   {
   }
 
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 17751bf..b2cb4b0 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -53,16 +53,16 @@
 {
   m_faceTable.afterAdd.connect([this] (Face& face) {
     face.afterReceiveInterest.connect(
-      [this, &face] (const Interest& interest) {
-        this->startProcessInterest(FaceEndpoint(face, 0), interest);
+      [this, &face] (const Interest& interest, const EndpointId& endpointId) {
+        this->startProcessInterest(FaceEndpoint(face, endpointId), interest);
       });
     face.afterReceiveData.connect(
-      [this, &face] (const Data& data) {
-        this->startProcessData(FaceEndpoint(face, 0), data);
+      [this, &face] (const Data& data, const EndpointId& endpointId) {
+        this->startProcessData(FaceEndpoint(face, endpointId), data);
       });
     face.afterReceiveNack.connect(
-      [this, &face] (const lp::Nack& nack) {
-        this->startProcessNack(FaceEndpoint(face, 0), nack);
+      [this, &face] (const lp::Nack& nack, const EndpointId& endpointId) {
+        this->startProcessNack(FaceEndpoint(face, endpointId), nack);
       });
     face.onDroppedInterest.connect(
       [this, &face] (const Interest& interest) {
@@ -157,7 +157,7 @@
   // note: Don't enter outgoing Nack pipeline because it needs an in-record.
   lp::Nack nack(interest);
   nack.setReason(lp::NackReason::DUPLICATE);
-  ingress.face.sendNack(nack);
+  ingress.face.sendNack(nack, ingress.endpoint);
 }
 
 void
@@ -232,7 +232,7 @@
   pitEntry->insertOrUpdateOutRecord(egress.face, egress.endpoint, interest);
 
   // send Interest
-  egress.face.sendInterest(interest);
+  egress.face.sendInterest(interest, egress.endpoint);
   ++m_counters.nOutInterests;
 }
 
@@ -371,7 +371,7 @@
 }
 
 void
-Forwarder::onOutgoingData(const Data& data, FaceEndpoint egress)
+Forwarder::onOutgoingData(const Data& data, const FaceEndpoint& egress)
 {
   if (egress.face.getId() == face::INVALID_FACEID) {
     NFD_LOG_WARN("onOutgoingData out=(invalid) data=" << data.getName());
@@ -391,7 +391,7 @@
   // TODO traffic manager
 
   // send Data
-  egress.face.sendData(data);
+  egress.face.sendData(data, egress.endpoint);
   ++m_counters.nOutData;
 }
 
@@ -493,7 +493,7 @@
   pitEntry->deleteInRecord(egress.face, egress.endpoint);
 
   // send Nack on face
-  egress.face.sendNack(nackPkt);
+  egress.face.sendNack(nackPkt, egress.endpoint);
   ++m_counters.nOutNacks;
 }
 
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index 18ca483..cc1d048 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -26,10 +26,10 @@
 #ifndef NFD_DAEMON_FW_FORWARDER_HPP
 #define NFD_DAEMON_FW_FORWARDER_HPP
 
-#include "face-endpoint.hpp"
 #include "face-table.hpp"
 #include "forwarder-counters.hpp"
 #include "unsolicited-data-policy.hpp"
+#include "face/face-endpoint.hpp"
 #include "table/fib.hpp"
 #include "table/pit.hpp"
 #include "table/cs.hpp"
@@ -228,7 +228,7 @@
   /** \brief outgoing Data pipeline
    */
   VIRTUAL_WITH_TESTS void
-  onOutgoingData(const Data& data, FaceEndpoint egress);
+  onOutgoingData(const Data& data, const FaceEndpoint& egress);
 
   /** \brief incoming Nack pipeline
    */