face: Face::getLocalUri

refs #1396

Change-Id: Icf02ae0a4136b6da3f6388cdce2f861bec44e940
diff --git a/daemon/face/datagram-face.hpp b/daemon/face/datagram-face.hpp
index f59374f..0da339c 100644
--- a/daemon/face/datagram-face.hpp
+++ b/daemon/face/datagram-face.hpp
@@ -20,12 +20,11 @@
 
   /** \brief Construct datagram face
    *
-   * \param uri         FaceUri for the face
    * \param socket      Protocol-specific socket for the created face
    * \param isOnDemand  If true, the face can be closed after it remains
    *                    unused for a certain amount of time
    */
-  DatagramFace(const FaceUri& uri,
+  DatagramFace(const FaceUri& remoteUri, const FaceUri& localUri,
                const shared_ptr<typename protocol::socket>& socket,
                bool isOnDemand);
 
@@ -85,10 +84,10 @@
 
 template <class T>
 inline
-DatagramFace<T>::DatagramFace(const FaceUri& uri,
+DatagramFace<T>::DatagramFace(const FaceUri& remoteUri, const FaceUri& localUri,
                               const shared_ptr<typename DatagramFace::protocol::socket>& socket,
                               bool isOnDemand)
-  : Face(uri)
+  : Face(remoteUri, localUri)
   , m_socket(socket)
 {
   setOnDemand(isOnDemand);
diff --git a/daemon/face/ethernet-face.cpp b/daemon/face/ethernet-face.cpp
index 66dcf08..4f70e43 100644
--- a/daemon/face/ethernet-face.cpp
+++ b/daemon/face/ethernet-face.cpp
@@ -25,7 +25,7 @@
 EthernetFace::EthernetFace(const shared_ptr<boost::asio::posix::stream_descriptor>& socket,
                            const shared_ptr<NetworkInterfaceInfo>& interface,
                            const ethernet::Address& address)
-  : Face(FaceUri("ether://" + interface->name + "/" + address.toString(':')))
+  : Face(FaceUri(address), FaceUri::fromDev(interface->name))
   , m_socket(socket)
   , m_interfaceName(interface->name)
   , m_srcAddress(interface->etherAddress)
diff --git a/daemon/face/face.cpp b/daemon/face/face.cpp
index 08853aa..c0241fc 100644
--- a/daemon/face/face.cpp
+++ b/daemon/face/face.cpp
@@ -11,23 +11,23 @@
 
 NFD_LOG_INIT("Face")
 
-template<class Packet>
 static inline void
-increaseCounter(const Packet& packet, FaceCounter& counter)
+increaseCounter(FaceCounter& counter)
 {
   ++counter;
 }
 
-Face::Face(const FaceUri& uri, bool isLocal)
+Face::Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal)
   : m_id(INVALID_FACEID)
   , m_isLocal(isLocal)
-  , m_uri(uri)
+  , m_remoteUri(remoteUri)
+  , m_localUri(localUri)
   , m_isOnDemand(false)
 {
-  onReceiveInterest += bind(&increaseCounter<Interest>, _1, boost::ref(m_counters.getInInterest()));
-  onReceiveData     += bind(&increaseCounter<Data>,     _1, boost::ref(m_counters.getInData()));
-  onSendInterest    += bind(&increaseCounter<Interest>, _1, boost::ref(m_counters.getOutInterest()));
-  onSendData        += bind(&increaseCounter<Data>,     _1, boost::ref(m_counters.getOutData()));
+  onReceiveInterest += bind(&increaseCounter, boost::ref(m_counters.getInInterest()));
+  onReceiveData     += bind(&increaseCounter, boost::ref(m_counters.getInData()));
+  onSendInterest    += bind(&increaseCounter, boost::ref(m_counters.getOutInterest()));
+  onSendData        += bind(&increaseCounter, boost::ref(m_counters.getOutData()));
 }
 
 Face::~Face()
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index e1ef2f8..3cb7160 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -32,19 +32,21 @@
   /**
    * \brief Face-related error
    */
-  struct Error : public std::runtime_error
+  class Error : public std::runtime_error
   {
-    Error(const std::string& what) : std::runtime_error(what) {}
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
   };
 
-  Face(const FaceUri& uri, bool isLocal = false);
+  Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal = false);
 
   virtual
   ~Face();
 
-  FaceId
-  getId() const;
-
   /// fires when an Interest is received
   EventEmitter<Interest> onReceiveInterest;
 
@@ -76,6 +78,10 @@
   virtual void
   close() = 0;
 
+public: // attributes
+  FaceId
+  getId() const;
+
   /** \brief Set the description
    *
    *  This is typically invoked by mgmt on set description command
@@ -114,9 +120,21 @@
   const FaceCounters&
   getCounters() const;
 
+  /** \deprecated use getRemoteUri instead
+   */
   const FaceUri&
   getUri() const;
 
+  /** \return a FaceUri that represents the remote endpoint
+   */
+  const FaceUri&
+  getRemoteUri() const;
+
+  /** \return a FaceUri that represents the local endpoint (NFD side)
+   */
+  const FaceUri&
+  getLocalUri() const;
+
 protected:
   // this is a non-virtual method
   bool
@@ -137,7 +155,8 @@
   std::string m_description;
   bool m_isLocal; // for scoping purposes
   FaceCounters m_counters;
-  FaceUri m_uri;
+  FaceUri m_remoteUri;
+  FaceUri m_localUri;
   bool m_isOnDemand;
 
   // allow setting FaceId
@@ -166,7 +185,19 @@
 inline const FaceUri&
 Face::getUri() const
 {
-  return m_uri;
+  return this->getRemoteUri();
+}
+
+inline const FaceUri&
+Face::getRemoteUri() const
+{
+  return m_remoteUri;
+}
+
+inline const FaceUri&
+Face::getLocalUri() const
+{
+  return m_localUri;
 }
 
 inline void
diff --git a/daemon/face/local-face.hpp b/daemon/face/local-face.hpp
index d16a64f..b3ccc43 100644
--- a/daemon/face/local-face.hpp
+++ b/daemon/face/local-face.hpp
@@ -21,9 +21,7 @@
 class LocalFace : public Face
 {
 public:
-
-  explicit
-  LocalFace(const FaceUri& uri);
+  LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
 
   /** \brief get whether any LocalControlHeader feature is enabled
    *
@@ -84,8 +82,8 @@
 };
 
 inline
-LocalFace::LocalFace(const FaceUri& uri)
-  : Face(uri, true)
+LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
+  : Face(remoteUri, localUri, true)
   , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
 {
 }
diff --git a/daemon/face/multicast-udp-face.cpp b/daemon/face/multicast-udp-face.cpp
index 34d40f0..7866603 100644
--- a/daemon/face/multicast-udp-face.cpp
+++ b/daemon/face/multicast-udp-face.cpp
@@ -10,8 +10,11 @@
 
 NFD_LOG_INIT("MulticastUdpFace");
 
-MulticastUdpFace::MulticastUdpFace(const shared_ptr<MulticastUdpFace::protocol::socket>& socket)
-  : DatagramFace<protocol>(FaceUri(socket->local_endpoint()), socket, false)
+MulticastUdpFace::MulticastUdpFace(const shared_ptr<protocol::socket>& socket,
+                                   const protocol::endpoint& localEndpoint)
+  : DatagramFace<protocol>(FaceUri(socket->local_endpoint()),
+                           FaceUri(localEndpoint),
+                           socket, false)
   , m_multicastGroup(m_socket->local_endpoint())
 {
   NFD_LOG_INFO("Creating multicast UDP face for group " << m_multicastGroup);
diff --git a/daemon/face/multicast-udp-face.hpp b/daemon/face/multicast-udp-face.hpp
index 774c567..f2245e5 100644
--- a/daemon/face/multicast-udp-face.hpp
+++ b/daemon/face/multicast-udp-face.hpp
@@ -21,8 +21,8 @@
   /**
    * \brief Creates a UDP-based face for multicast communication
    */
-  explicit
-  MulticastUdpFace(const shared_ptr<protocol::socket>& socket);
+  MulticastUdpFace(const shared_ptr<protocol::socket>& socket,
+                   const protocol::endpoint& localEndpoint);
 
   const protocol::endpoint&
   getMulticastGroup() const;
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
index 1b5b124..f60e87a 100644
--- a/daemon/face/stream-face.hpp
+++ b/daemon/face/stream-face.hpp
@@ -25,8 +25,7 @@
   /**
    * \brief Create instance of StreamFace
    */
-  explicit
-  StreamFace(const FaceUri& uri,
+  StreamFace(const FaceUri& remoteUri, const FaceUri& localUri,
              const shared_ptr<typename protocol::socket>& socket,
              bool isOnDemand);
 
@@ -100,10 +99,10 @@
 
 template<class T, class FaceBase>
 inline
-StreamFace<T, FaceBase>::StreamFace(const FaceUri& uri,
-                                    const shared_ptr<typename StreamFace::protocol::socket>& socket,
-                                    bool isOnDemand)
-  : FaceBase(uri)
+StreamFace<T, FaceBase>::StreamFace(const FaceUri& remoteUri, const FaceUri& localUri,
+                const shared_ptr<typename StreamFace::protocol::socket>& socket,
+                bool isOnDemand)
+  : FaceBase(remoteUri, localUri)
   , m_socket(socket)
   , m_inputBufferSize(0)
 {
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
index 4655641..7462030 100644
--- a/daemon/face/tcp-face.cpp
+++ b/daemon/face/tcp-face.cpp
@@ -8,9 +8,6 @@
 
 namespace nfd {
 
-// The whole purpose of this file is to specialize the logger,
-// otherwise, everything could be put into the header file.
-
 NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamFace, TcpFace::protocol, "TcpFace");
 
 NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(StreamFace,
@@ -18,14 +15,17 @@
                                                 "TcpLocalFace");
 
 TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket, bool isOnDemand)
-  : StreamFace<protocol>(FaceUri(socket->remote_endpoint()), socket, isOnDemand)
+  : StreamFace<protocol>(FaceUri(socket->remote_endpoint()),
+                         FaceUri(socket->local_endpoint()),
+                         socket, isOnDemand)
 {
 }
 
-//
-
-TcpLocalFace::TcpLocalFace(const shared_ptr<TcpLocalFace::protocol::socket>& socket, bool isOnDemand)
-  : StreamFace<protocol, LocalFace>(FaceUri(socket->remote_endpoint()), socket, isOnDemand)
+TcpLocalFace::TcpLocalFace(const shared_ptr<TcpLocalFace::protocol::socket>& socket,
+                           bool isOnDemand)
+  : StreamFace<protocol, LocalFace>(FaceUri(socket->remote_endpoint()),
+                                    FaceUri(socket->local_endpoint()),
+                                    socket, isOnDemand)
 {
 }
 
diff --git a/daemon/face/udp-face.cpp b/daemon/face/udp-face.cpp
index 1cc0bc8..1a4eb9c 100644
--- a/daemon/face/udp-face.cpp
+++ b/daemon/face/udp-face.cpp
@@ -11,7 +11,9 @@
 NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace, UdpFace::protocol, "UdpFace");
 
 UdpFace::UdpFace(const shared_ptr<UdpFace::protocol::socket>& socket, bool isOnDemand)
-  : DatagramFace<protocol>(FaceUri(socket->remote_endpoint()), socket, isOnDemand)
+  : DatagramFace<protocol>(FaceUri(socket->remote_endpoint()),
+                           FaceUri(socket->local_endpoint()),
+                           socket, isOnDemand)
 {
 }
 
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 7352a99..36b1fcd 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -11,7 +11,7 @@
 namespace nfd {
 
 using namespace boost::asio;
-  
+
 NFD_LOG_INIT("UdpFactory");
 
 UdpFactory::UdpFactory(const std::string& defaultPort/* = "6363"*/)
@@ -24,18 +24,18 @@
                           const time::seconds& timeout)
 {
   NFD_LOG_DEBUG("Creating unicast " << endpoint);
-  
+
   shared_ptr<UdpChannel> channel = findChannel(endpoint);
   if (static_cast<bool>(channel))
     return channel;
 
-  
-  //checking if the endpoint is already in use for multicast face 
+
+  //checking if the endpoint is already in use for multicast face
   shared_ptr<MulticastUdpFace> multicast = findMulticastFace(endpoint);
   if (static_cast<bool>(multicast))
     throw Error("Cannot create the requested UDP unicast channel, local "
                 "endpoint is already allocated for a UDP multicast face");
-  
+
   if (endpoint.address().is_multicast()) {
     throw Error("This method is only for unicast channel. The provided "
                 "endpoint is multicast. Use createMulticastFace to "
@@ -72,7 +72,7 @@
                   "endpoint is already allocated for a UDP multicast face "
                   "on a different multicast group");
   }
-  
+
   //checking if the local endpoint is already in use for an unicast channel
   shared_ptr<UdpChannel> unicast = findChannel(localEndpoint);
   if (static_cast<bool>(unicast)) {
@@ -83,7 +83,7 @@
   if (localEndpoint.address().is_v6() || multicastEndpoint.address().is_v6()) {
     throw Error("IPv6 multicast is not supported yet. Please provide an IPv4 address");
   }
-  
+
   if (localEndpoint.port() != multicastEndpoint.port()) {
     throw Error("Cannot create the requested UDP multicast face, "
                 "both endpoints should have the same port number. ");
@@ -96,7 +96,7 @@
 
   shared_ptr<ip::udp::socket> clientSocket =
     make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
- 
+
   clientSocket->open(multicastEndpoint.protocol());
 
   clientSocket->set_option(ip::udp::socket::reuse_address(true));
@@ -118,7 +118,7 @@
 
   clientSocket->set_option(ip::multicast::enable_loopback(false));
 
-  multicastFace = make_shared<MulticastUdpFace>(boost::cref(clientSocket));
+  multicastFace = make_shared<MulticastUdpFace>(boost::cref(clientSocket), localEndpoint);
   multicastFace->onFail += bind(&UdpFactory::afterFaceFailed, this, localEndpoint);
 
   m_multicastFaces[localEndpoint] = multicastFace;
@@ -131,7 +131,7 @@
                                 const std::string& multicastIp,
                                 const std::string& multicastPort)
 {
-  
+
   return createMulticastFace(UdpResolver::syncResolve(localIp,
                                                       multicastPort),
                              UdpResolver::syncResolve(multicastIp,
@@ -148,7 +148,7 @@
     addressSelector = resolver::Ipv4Address();
   else if (uri.getScheme() == "udp6")
     addressSelector = resolver::Ipv6Address();
-  
+
   UdpResolver::asyncResolve(uri.getHost(),
                             uri.getPort().empty() ? m_defaultPort : uri.getPort(),
                             bind(&UdpFactory::continueCreateFaceAfterResolve, this, _1,
@@ -167,9 +167,9 @@
     onConnectFailed("The provided address is multicast. Please use createMulticastFace method");
     return;
   }
-  
+
   // very simple logic for now
-  
+
   for (ChannelMap::iterator channel = m_channels.begin();
        channel != m_channels.end();
        ++channel)
diff --git a/daemon/face/unix-stream-face.cpp b/daemon/face/unix-stream-face.cpp
index 2753f57..1343729 100644
--- a/daemon/face/unix-stream-face.cpp
+++ b/daemon/face/unix-stream-face.cpp
@@ -15,8 +15,13 @@
                                                 UnixStreamFace::protocol, LocalFace,
                                                 "UnixStreamFace");
 
+BOOST_STATIC_ASSERT((boost::is_same<UnixStreamFace::protocol::socket::native_handle_type,
+                     int>::value));
+
 UnixStreamFace::UnixStreamFace(const shared_ptr<UnixStreamFace::protocol::socket>& socket)
-  : StreamFace<protocol, LocalFace>(FaceUri(socket->local_endpoint()), socket, true)
+  : StreamFace<protocol, LocalFace>(FaceUri::fromFd(socket->native_handle()),
+                                    FaceUri(socket->local_endpoint()),
+                                    socket, true)
 {
 }