face: MulticastUdpTransport: set remoteEndpoint for received packets

Change-Id: I0d600d94e41a67c2d58ec10cde3cb6c13f619771
Refs: #3262
diff --git a/daemon/face/datagram-transport.hpp b/daemon/face/datagram-transport.hpp
index b435a18..bf11011 100644
--- a/daemon/face/datagram-transport.hpp
+++ b/daemon/face/datagram-transport.hpp
@@ -84,8 +84,12 @@
   void
   resetRecentUsage();
 
+  static EndpointId
+  makeEndpointId(const typename protocol::endpoint& ep);
+
 protected:
   typename protocol::socket m_socket;
+  typename protocol::endpoint m_sender;
 
   NFD_LOG_INCLASS_DECLARE();
 
@@ -99,10 +103,10 @@
 DatagramTransport<T, U>::DatagramTransport(typename DatagramTransport::protocol::socket&& socket)
   : m_socket(std::move(socket))
 {
-  m_socket.async_receive(boost::asio::buffer(m_receiveBuffer),
-                         bind(&DatagramTransport<T, U>::handleReceive, this,
-                              boost::asio::placeholders::error,
-                              boost::asio::placeholders::bytes_transferred));
+  m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
+                              bind(&DatagramTransport<T, U>::handleReceive, this,
+                                   boost::asio::placeholders::error,
+                                   boost::asio::placeholders::bytes_transferred));
 }
 
 template<class T, class U>
@@ -162,9 +166,11 @@
     // This packet won't extend the face lifetime
     return;
   }
-
   m_hasBeenUsedRecently = true;
-  this->receive(Transport::Packet(std::move(element)));
+
+  Transport::Packet tp(std::move(element));
+  tp.remoteEndpoint = makeEndpointId(m_sender);
+  this->receive(std::move(tp));
 }
 
 template<class T, class U>
@@ -175,10 +181,10 @@
   receiveDatagram(m_receiveBuffer.data(), nBytesReceived, error);
 
   if (m_socket.is_open())
-    m_socket.async_receive(boost::asio::buffer(m_receiveBuffer),
-                           bind(&DatagramTransport<T, U>::handleReceive, this,
-                                boost::asio::placeholders::error,
-                                boost::asio::placeholders::bytes_transferred));
+    m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
+                                bind(&DatagramTransport<T, U>::handleReceive, this,
+                                     boost::asio::placeholders::error,
+                                     boost::asio::placeholders::bytes_transferred));
 }
 
 template<class T, class U>
@@ -232,6 +238,13 @@
   m_hasBeenUsedRecently = false;
 }
 
+template<class T, class U>
+inline Transport::EndpointId
+DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint& ep)
+{
+  return 0;
+}
+
 } // namespace face
 } // namespace nfd
 
diff --git a/daemon/face/multicast-udp-transport.cpp b/daemon/face/multicast-udp-transport.cpp
index 544b4ff..9503c35 100644
--- a/daemon/face/multicast-udp-transport.cpp
+++ b/daemon/face/multicast-udp-transport.cpp
@@ -87,5 +87,16 @@
   DatagramTransport::doClose();
 }
 
+template<>
+Transport::EndpointId
+DatagramTransport<boost::asio::ip::udp, Multicast>::makeEndpointId(const protocol::endpoint& ep)
+{
+  // IPv6 multicast is not supported
+  BOOST_ASSERT(ep.address().is_v4());
+
+  return (static_cast<uint64_t>(ep.port()) << 32) |
+          static_cast<uint64_t>(ep.address().to_v4().to_ulong());
+}
+
 } // namespace face
 } // namespace nfd
diff --git a/daemon/face/multicast-udp-transport.hpp b/daemon/face/multicast-udp-transport.hpp
index 6da8fe6..7cd5dfe 100644
--- a/daemon/face/multicast-udp-transport.hpp
+++ b/daemon/face/multicast-udp-transport.hpp
@@ -31,6 +31,14 @@
 namespace nfd {
 namespace face {
 
+// Explicit specialization of makeEndpointId for the UDP multicast case.
+// Note that this "shall be declared before the first use of the specialization
+// that would cause an implicit instantiation to take place, in every translation
+// unit in which such a use occurs".
+template<>
+Transport::EndpointId
+DatagramTransport<boost::asio::ip::udp, Multicast>::makeEndpointId(const protocol::endpoint& ep);
+
 /**
  * \brief A Transport that communicates on a UDP multicast group
  */