diff --git a/daemon/face/datagram-face.hpp b/daemon/face/datagram-face.hpp
new file mode 100644
index 0000000..f4f9a18
--- /dev/null
+++ b/daemon/face/datagram-face.hpp
@@ -0,0 +1,267 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_DATAGRAM_FACE_HPP
+#define NFD_FACE_DATAGRAM_FACE_HPP
+
+#include "face.hpp"
+
+namespace nfd {
+
+template <class T>
+class DatagramFace : public Face
+{
+public:
+  typedef T protocol;
+  
+  explicit
+  DatagramFace(const shared_ptr<typename protocol::socket>& socket);
+
+  virtual
+  ~DatagramFace();
+  
+  // from Face
+  virtual void
+  sendInterest(const Interest& interest);
+  
+  virtual void
+  sendData(const Data& data);
+  
+  virtual void
+  close();
+
+  void
+  handleSend(const boost::system::error_code& error,
+             const Block& wire);
+
+  void
+  handleReceive(const boost::system::error_code& error,
+                size_t nBytesReceived);
+
+protected:
+
+  void
+  receiveDatagram(const uint8_t* buffer,
+                  size_t nBytesReceived,
+                  const boost::system::error_code& error);
+
+  void
+  keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face);
+  
+  void
+  closeSocket();
+  
+protected:
+  shared_ptr<typename protocol::socket> m_socket;
+  uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
+
+  NFD_LOG_INCLASS_DECLARE();
+
+};
+
+template <class T>
+inline
+DatagramFace<T>::DatagramFace(const shared_ptr<typename DatagramFace::protocol::socket>& socket)
+  : m_socket(socket)
+{
+  m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
+                          bind(&DatagramFace<T>::handleReceive, this, _1, _2));
+}
+
+template <class T>
+inline
+DatagramFace<T>::~DatagramFace()
+{
+}
+  
+template <class T>
+inline void
+DatagramFace<T>::sendInterest(const Interest& interest)
+{
+  m_socket->async_send(boost::asio::buffer(interest.wireEncode().wire(),
+                                           interest.wireEncode().size()),
+                       bind(&DatagramFace<T>::handleSend, this, _1, interest.wireEncode()));
+    
+  // anything else should be done here?
+}
+  
+template <class T>
+inline void
+DatagramFace<T>::sendData(const Data& data)
+{
+  m_socket->async_send(boost::asio::buffer(data.wireEncode().wire(),
+                                           data.wireEncode().size()),
+                       bind(&DatagramFace<T>::handleSend, this, _1, data.wireEncode()));
+    
+  // anything else should be done here?
+}
+
+template <class T>
+inline void
+DatagramFace<T>::handleSend(const boost::system::error_code& error,
+                            const Block& wire)
+{
+  if (error != 0) {
+    if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
+      return;
+    
+    if (!m_socket->is_open())
+    {
+      onFail("Tunnel closed");
+      return;
+    }
+    
+    NFD_LOG_WARN("[id:" << this->getId()
+                  << ",endpoint:" << m_socket->local_endpoint()
+                  << "] Send operation failed, closing socket: "
+                  << error.category().message(error.value()));
+    
+    closeSocket();
+    
+    if (error == boost::asio::error::eof)
+    {
+      onFail("Tunnel closed");
+    }
+    else
+    {
+      onFail("Send operation failed, closing socket: " +
+             error.category().message(error.value()));
+    }
+    return;
+  }
+  
+  NFD_LOG_TRACE("[id:" << this->getId()
+                << ",endpoint:" << m_socket->local_endpoint()
+                << "] Successfully sent: " << wire.size() << " bytes");
+  // do nothing (needed to retain validity of wire memory block
+}
+  
+template <class T>
+inline void
+DatagramFace<T>::close()
+{
+  if (!m_socket->is_open())
+    return;
+    
+  NFD_LOG_INFO("[id:" << this->getId()
+               << ",endpoint:" << m_socket->local_endpoint()
+               << "] Close tunnel");
+    
+  closeSocket();
+  onFail("Close tunnel");
+}
+
+template <class T>
+inline void
+DatagramFace<T>::handleReceive(const boost::system::error_code& error,
+                               size_t nBytesReceived)
+{
+  receiveDatagram(m_inputBuffer, nBytesReceived, error);
+  m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
+                          bind(&DatagramFace<T>::handleReceive, this, _1, _2));
+}
+
+template <class T>
+inline void
+DatagramFace<T>::receiveDatagram(const uint8_t* buffer,
+                                 size_t nBytesReceived,
+                                 const boost::system::error_code& error)
+{
+  if (error != 0 || nBytesReceived == 0) {
+    if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
+      return;
+
+    // this should be unnecessary, but just in case
+    if (!m_socket->is_open())
+    {
+      onFail("Tunnel closed");
+      return;
+    }
+
+    NFD_LOG_WARN("[id:" << this->getId()
+                 << ",endpoint:" << m_socket->local_endpoint()
+                 << "] Receive operation failed: "
+                 << error.category().message(error.value()));
+
+    closeSocket();
+
+    if (error == boost::asio::error::eof)
+    {
+      onFail("Tunnel closed");
+    }
+    else
+    {
+      onFail("Receive operation failed, closing socket: " +
+             error.category().message(error.value()));
+    }
+    return;
+  }
+
+  NFD_LOG_TRACE("[id:" << this->getId()
+                << ",endpoint:" << m_socket->local_endpoint()
+                << "] Received: " << nBytesReceived << " bytes");
+
+  /// @todo Eliminate reliance on exceptions in this path
+  try {
+    Block element(buffer, nBytesReceived);
+
+    if (element.size() != nBytesReceived)
+      {
+        NFD_LOG_WARN("[id:" << this->getId()
+                     << ",endpoint:" << m_socket->local_endpoint()
+                     << "] Received datagram size and decoded "
+                     << "element size don't match");
+        /// @todo this message should not extend the face lifetime
+        return;
+      }
+    if (!this->decodeAndDispatchInput(element))
+      {
+        NFD_LOG_WARN("[id:" << this->getId()
+                     << ",endpoint:" << m_socket->local_endpoint()
+                     << "] Received unrecognized block of type ["
+                     << element.type() << "]");
+        // ignore unknown packet and proceed
+        /// @todo this message should not extend the face lifetime
+        return;
+      }
+  }
+  catch(const tlv::Error& e) {
+    NFD_LOG_WARN("[id:" << this->getId()
+                 << ",endpoint:" << m_socket->local_endpoint()
+                 << "] Received input is invalid");
+    /// @todo this message should not extend the face lifetime
+    return;
+  }
+}
+
+
+template <class T>
+inline void
+DatagramFace<T>::keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face)
+{
+}
+  
+template <class T>
+inline void
+DatagramFace<T>::closeSocket()
+{
+  boost::asio::io_service& io = m_socket->get_io_service();
+    
+  // use the non-throwing variants and ignore errors, if any
+  boost::system::error_code error;
+  m_socket->shutdown(protocol::socket::shutdown_both, error);
+  m_socket->close(error);
+  // after this, handlers will be called with an error code
+    
+  // ensure that the Face object is alive at least until all pending
+  // handlers are dispatched
+  io.post(bind(&DatagramFace<T>::keepFaceAliveUntilAllHandlersExecuted,
+               this, this->shared_from_this()));
+}
+
+} // namespace nfd
+
+#endif // NFD_FACE_DATAGRAM_FACE_HPP
diff --git a/daemon/face/multicast-udp-face.cpp b/daemon/face/multicast-udp-face.cpp
new file mode 100644
index 0000000..edd2ff4
--- /dev/null
+++ b/daemon/face/multicast-udp-face.cpp
@@ -0,0 +1,58 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "multicast-udp-face.hpp"
+
+namespace nfd {
+
+NFD_LOG_INIT("MulticastUdpFace");
+
+
+MulticastUdpFace::MulticastUdpFace(const shared_ptr<MulticastUdpFace::protocol::socket>& socket)
+  : UdpFace(socket)
+{
+  NFD_LOG_DEBUG("Face creation. Multicast group: "
+                << m_socket->local_endpoint());
+  m_multicastGroup = m_socket->local_endpoint();
+}
+
+const boost::asio::ip::udp::endpoint&
+MulticastUdpFace::getMulticastGroup() const
+{
+  return m_multicastGroup;
+}
+
+void
+MulticastUdpFace::sendInterest(const Interest& interest)
+{
+  NFD_LOG_DEBUG("Sending interest");
+  m_socket->async_send_to(boost::asio::buffer(interest.wireEncode().wire(),
+                                              interest.wireEncode().size()),
+                          m_multicastGroup,
+                          bind(&DatagramFace<protocol>::handleSend, this, _1, interest.wireEncode()));
+    
+  // anything else should be done here?
+}
+
+void
+MulticastUdpFace::sendData(const Data& data)
+{
+  NFD_LOG_DEBUG("Sending data");
+  m_socket->async_send_to(boost::asio::buffer(data.wireEncode().wire(),
+                                           data.wireEncode().size()),
+                          m_multicastGroup,
+                          bind(&DatagramFace<protocol>::handleSend, this, _1, data.wireEncode()));
+    
+  // anything else should be done here?
+}
+  
+bool
+MulticastUdpFace::isMultiAccess() const
+{
+  return true;
+}
+
+} // namespace nfd
diff --git a/daemon/face/multicast-udp-face.hpp b/daemon/face/multicast-udp-face.hpp
new file mode 100644
index 0000000..46404da
--- /dev/null
+++ b/daemon/face/multicast-udp-face.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_MULTICAST_UDP_FACE_HPP
+#define NFD_FACE_MULTICAST_UDP_FACE_HPP
+
+#include "udp-face.hpp"
+
+namespace nfd
+{
+
+/**
+ * \brief Implementation of Face abstraction that uses 
+ *        multicast UDP as underlying transport mechanism
+ */
+class MulticastUdpFace : public UdpFace
+{
+public:
+  typedef boost::asio::ip::udp protocol;
+
+  /**
+   * \brief Creates a Udp face for multicast communication
+   */
+  explicit
+  MulticastUdpFace(const shared_ptr<protocol::socket>& socket);
+
+  const boost::asio::ip::udp::endpoint&
+  getMulticastGroup() const;
+
+  // from Face
+  virtual void
+  sendInterest(const Interest& interest);
+
+  virtual void
+  sendData(const Data& data);
+  
+  virtual bool
+  isMultiAccess() const;
+  
+private:
+  boost::asio::ip::udp::endpoint m_multicastGroup;
+};
+
+} // namespace nfd
+
+#endif // NFD_FACE_MULTICAST_UDP_FACE_HPP
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
new file mode 100644
index 0000000..2127cd6
--- /dev/null
+++ b/daemon/face/udp-channel.cpp
@@ -0,0 +1,202 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "udp-channel.hpp"
+#include "core/global-io.hpp"
+
+namespace nfd {
+
+NFD_LOG_INIT("UdpChannel");
+
+using namespace boost::asio;
+
+UdpChannel::UdpChannel(const udp::Endpoint& localEndpoint,
+                       const time::Duration& timeout)
+  : m_localEndpoint(localEndpoint)
+  , m_isListening(false)
+{
+  /// \todo the reuse_address works as we want in Linux, but in other system could be different.
+  ///       We need to check this
+  ///       (SO_REUSEADDR doesn't behave uniformly in different OS)
+
+  m_socket = make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
+  m_socket->open(m_localEndpoint.protocol());
+  m_socket->set_option(boost::asio::ip::udp::socket::reuse_address(true));
+  
+  try {
+    m_socket->bind(m_localEndpoint);
+  }
+  catch (boost::system::system_error& e) {
+    //The bind failed, so the socket is useless now
+    m_socket->close();
+    throw Error("Failed to properly configure the socket. "
+                "UdpChannel creation aborted, check the address (" + std::string(e.what()) + ")");
+  }
+}
+
+void
+UdpChannel::listen(const FaceCreatedCallback& onFaceCreated,
+                   const ConnectFailedCallback& onListenFailed)
+{
+  if (m_isListening) {
+    throw Error("Listen already called on this channel");
+  }
+  m_isListening = true;
+  
+  onFaceCreatedNewPeerCallback = onFaceCreated;
+  onConnectFailedNewPeerCallback = onListenFailed;
+
+  m_socket->async_receive_from(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE),
+                               m_newRemoteEndpoint,
+                               bind(&UdpChannel::newPeer, this,
+                                    boost::asio::placeholders::error,
+                                    boost::asio::placeholders::bytes_transferred));
+}
+
+
+void
+UdpChannel::connect(const udp::Endpoint& remoteEndpoint,
+                    const FaceCreatedCallback& onFaceCreated)
+{
+  ChannelFaceMap::iterator i = m_channelFaces.find(remoteEndpoint);
+  if (i != m_channelFaces.end()) {
+    onFaceCreated(i->second);
+    return;
+  }
+
+  //creating a new socket for the face that will be created soon
+  shared_ptr<ip::udp::socket> clientSocket =
+    make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
+  
+  clientSocket->open(m_localEndpoint.protocol());
+  clientSocket->set_option(ip::udp::socket::reuse_address(true));
+  
+  try {
+    clientSocket->bind(m_localEndpoint);
+    clientSocket->connect(remoteEndpoint); //@todo connect or async_connect
+    //(since there is no handshake the connect shouldn't block). If we go for
+    //async_connect, make sure that if in the meantime we receive a UDP pkt from
+    //that endpoint nothing bad happen (it's difficult, but it could happen)
+  }
+  catch (boost::system::system_error& e) {
+    clientSocket->close();
+    throw Error("Failed to properly configure the socket. Check the address ("
+                + std::string(e.what()) + ")");
+  }
+  createFace(clientSocket, onFaceCreated);
+}
+
+void
+UdpChannel::connect(const std::string& remoteHost,
+                    const std::string& remotePort,
+                    const FaceCreatedCallback& onFaceCreated,
+                    const ConnectFailedCallback& onConnectFailed)
+{
+  ip::udp::resolver::query query(remoteHost, remotePort);
+  shared_ptr<ip::udp::resolver> resolver =
+  make_shared<ip::udp::resolver>(boost::ref(getGlobalIoService()));
+
+  resolver->async_resolve(query,
+                          bind(&UdpChannel::handleEndpointResolution, this, _1, _2,
+                               onFaceCreated, onConnectFailed,
+                               resolver));
+}
+
+void
+UdpChannel::handleEndpointResolution(const boost::system::error_code& error,
+                                      ip::udp::resolver::iterator remoteEndpoint,
+                                      const FaceCreatedCallback& onFaceCreated,
+                                      const ConnectFailedCallback& onConnectFailed,
+                                      const shared_ptr<ip::udp::resolver>& resolver)
+{
+  if (error != 0 ||
+      remoteEndpoint == ip::udp::resolver::iterator())
+  {
+    if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
+      return;
+
+    NFD_LOG_DEBUG("Remote endpoint hostname or port cannot be resolved: "
+                    << error.category().message(error.value()));
+
+    onConnectFailed("Remote endpoint hostname or port cannot be resolved: " +
+                      error.category().message(error.value()));
+      return;
+  }
+
+  connect(*remoteEndpoint, onFaceCreated);
+}
+
+size_t
+UdpChannel::size() const
+{
+  return m_channelFaces.size();
+}
+
+
+shared_ptr<UdpFace>
+UdpChannel::createFace(const shared_ptr<ip::udp::socket>& socket,
+                       const FaceCreatedCallback& onFaceCreated)
+{
+  udp::Endpoint remoteEndpoint = socket->remote_endpoint();
+
+  shared_ptr<UdpFace> face = make_shared<UdpFace>(boost::cref(socket));
+  face->onFail += bind(&UdpChannel::afterFaceFailed, this, remoteEndpoint);
+
+  onFaceCreated(face);
+  m_channelFaces[remoteEndpoint] = face;
+  return face;
+}
+
+void
+UdpChannel::newPeer(const boost::system::error_code& error,
+                    std::size_t nBytesReceived)
+{
+  NFD_LOG_DEBUG("UdpChannel::newPeer from " << m_newRemoteEndpoint);
+  ChannelFaceMap::iterator i = m_channelFaces.find(m_newRemoteEndpoint);
+  if (i != m_channelFaces.end()) {
+    //The face already exists.
+    //Usually this shouldn't happen, because the channel creates a Udpface
+    //as soon as it receives a pkt from a new endpoint and then the
+    //traffic is dispatched by the kernel directly to the face.
+    //However, if the node receives multiple packets from the same endpoint
+    //"at the same time", while the channel is creating the face the kernel
+    //could dispatch the other pkts to the channel because the face is not yet
+    //ready. In this case, the channel has to pass the pkt to the face
+    NFD_LOG_DEBUG("The creation of the face for the remote endpoint "
+                  << m_newRemoteEndpoint
+                  << " is in progress");
+    //Passing the message to the correspondent face
+    i->second->handleFirstReceive(m_inputBuffer, nBytesReceived, error);
+    return;
+  }
+
+  shared_ptr<ip::udp::socket> clientSocket =
+    make_shared<ip::udp::socket>(boost::ref(getGlobalIoService()));
+  clientSocket->open(m_localEndpoint.protocol());
+  clientSocket->set_option(ip::udp::socket::reuse_address(true));
+  clientSocket->bind(m_localEndpoint);
+  clientSocket->connect(m_newRemoteEndpoint);
+
+  shared_ptr<UdpFace> newFace = createFace(clientSocket, onFaceCreatedNewPeerCallback);
+
+  //Passing the message to the correspondent face
+  newFace->handleFirstReceive(m_inputBuffer, nBytesReceived, error);
+
+  m_socket->async_receive_from(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE),
+                               m_newRemoteEndpoint,
+                               bind(&UdpChannel::newPeer, this,
+                                    boost::asio::placeholders::error,
+                                    boost::asio::placeholders::bytes_transferred));
+}
+
+
+void UdpChannel::afterFaceFailed(udp::Endpoint &endpoint)
+{
+  NFD_LOG_DEBUG("afterFaceFailed: " << endpoint);
+  m_channelFaces.erase(endpoint);
+}
+
+} // namespace nfd
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
new file mode 100644
index 0000000..b987b5e
--- /dev/null
+++ b/daemon/face/udp-channel.hpp
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_UDP_CHANNEL_HPP
+#define NFD_FACE_UDP_CHANNEL_HPP
+
+#include "common.hpp"
+#include "core/time.hpp"
+#include "udp-face.hpp"
+
+namespace nfd {
+
+namespace udp {
+  typedef boost::asio::ip::udp::endpoint Endpoint;
+} // namespace udp
+
+/**
+ * \brief Class implementing UDP-based channel to create faces
+ *
+ *
+ */
+class UdpChannel
+{
+public:
+  
+  /**
+   * \brief Exception of UdpChannel
+   */
+  struct Error : public std::runtime_error
+  {
+    Error(const std::string& what) : runtime_error(what) {}
+  };
+  
+  /**
+   * \brief Prototype for the callback called when face is created
+   *        (as a response to new incoming communication not managed
+   *        by any faces yet or after the connect function is created)
+   */
+  typedef function<void(const shared_ptr<UdpFace>& newFace)> FaceCreatedCallback;
+
+  /**
+   * \brief Prototype for the callback that is called when face is failed to
+   *        get created
+   */
+  typedef function<void(const std::string& reason)> ConnectFailedCallback;
+
+  /**
+   * \brief Create UDP channel for the local endpoint
+   *
+   * To enable creation of faces upon incoming connections,
+   * one needs to explicitly call UdpChannel::listen method.
+   * The created socket is bound to the localEndpoint.
+   * reuse_address option is set
+   *
+   * \throw UdpChannel::Error if bind on the socket fails
+   */
+  UdpChannel(const udp::Endpoint& localEndpoint,
+             const time::Duration& timeout);
+
+  /**
+   * \brief Enable listening on the local endpoint, accept connections,
+   *        and create faces when remote host makes a connection
+   * \param onFaceCreated  Callback to notify successful creation of the face
+   * \param onAcceptFailed Callback to notify when channel fails
+   *
+   * \throws UdpChannel::Error if called multiple times
+   */
+  void
+  listen(const FaceCreatedCallback& onFaceCreated,
+         const ConnectFailedCallback& onAcceptFailed);
+
+  /**
+   * \brief Create a face by establishing connection to remote endpoint
+   *
+   * \throw UdpChannel::Error if bind or connect on the socket fail
+   */
+  void
+  connect(const udp::Endpoint& remoteEndpoint,
+          const FaceCreatedCallback& onFaceCreated);
+  /**
+   * \brief Create a face by establishing connection to the specified
+   *        remote host and remote port
+   *
+   * This method will never block and will return immediately. All
+   * necessary hostname and port resolution and connection will happen
+   * in asynchronous mode.
+   *
+   * If connection cannot be established within specified timeout, it
+   * will be aborted.
+   */
+  void
+  connect(const std::string& remoteHost, const std::string& remotePort,
+          const FaceCreatedCallback& onFaceCreated,
+          const ConnectFailedCallback& onConnectFailed);
+
+  /**
+   * \brief Get number of faces in the channel
+   */
+  size_t
+  size() const;
+
+private:
+  shared_ptr<UdpFace>
+  createFace(const shared_ptr<boost::asio::ip::udp::socket>& socket,
+             const FaceCreatedCallback& onFaceCreated);
+  void
+  afterFaceFailed(udp::Endpoint& endpoint);
+
+  /**
+   * \brief The UdpChannel has received a new pkt from a remote endpoint not yet 
+   *        associated with any UdpFace
+   */
+  void
+  newPeer(const boost::system::error_code& error,
+                   std::size_t nBytesReceived);
+
+  void
+  handleEndpointResolution(const boost::system::error_code& error,
+                           boost::asio::ip::udp::resolver::iterator remoteEndpoint,
+                           const FaceCreatedCallback& onFaceCreated,
+                           const ConnectFailedCallback& onConnectFailed,
+                           const shared_ptr<boost::asio::ip::udp::resolver>& resolver);
+
+private:
+  udp::Endpoint m_localEndpoint;
+
+  /**
+   * \brief Endpoint used to store the information about the last new remote endpoint
+   */
+  udp::Endpoint m_newRemoteEndpoint;
+
+  /**
+   * Callbacks for face creation.
+   * New communications are detected using async_receive_from.
+   * Its handler has a fixed signature. No space for the face callback
+   */
+  FaceCreatedCallback onFaceCreatedNewPeerCallback;
+  
+  // @todo remove the onConnectFailedNewPeerCallback if it remains unused
+  ConnectFailedCallback onConnectFailedNewPeerCallback;
+
+  /**
+   * \brief Socket used to "accept" new communication
+   **/
+  shared_ptr<boost::asio::ip::udp::socket> m_socket;
+
+  uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
+
+  typedef std::map< udp::Endpoint, shared_ptr<UdpFace> > ChannelFaceMap;
+  ChannelFaceMap m_channelFaces;
+
+  /**
+   * \brief If true, it means the function listen has already been called
+   */
+  bool m_isListening;
+
+};
+
+} // namespace nfd
+
+#endif // NFD_FACE_UDP_CHANNEL_HPP
diff --git a/daemon/face/udp-face.cpp b/daemon/face/udp-face.cpp
new file mode 100644
index 0000000..0ee40cc
--- /dev/null
+++ b/daemon/face/udp-face.cpp
@@ -0,0 +1,38 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "udp-face.hpp"
+
+namespace nfd {
+
+NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace, UdpFace::protocol, "UdpFace");
+
+UdpFace::UdpFace(const shared_ptr<UdpFace::protocol::socket>& socket)
+  : DatagramFace<protocol>(socket)
+{
+}
+
+void
+UdpFace::handleFirstReceive(const uint8_t* buffer,
+                            std::size_t nBytesReceived,
+                            const boost::system::error_code& error)
+{
+  //checking if the received message size is too big.
+  //This check is redundant, since in the actual implementation a packet
+  //cannot be bigger than MAX_NDN_PACKET_SIZE
+  if (!error && (nBytesReceived > MAX_NDN_PACKET_SIZE))
+    {
+      NFD_LOG_WARN("[id:" << this->getId()
+                   << ",endpoint:" << m_socket->local_endpoint()
+                   << "] Received message too big. Maximum size is "
+                   << MAX_NDN_PACKET_SIZE );
+      return;
+    }
+  receiveDatagram(buffer, nBytesReceived, error);
+}
+
+
+} // namespace nfd
diff --git a/daemon/face/udp-face.hpp b/daemon/face/udp-face.hpp
new file mode 100644
index 0000000..126419f
--- /dev/null
+++ b/daemon/face/udp-face.hpp
@@ -0,0 +1,40 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_UDP_FACE_HPP
+#define NFD_FACE_UDP_FACE_HPP
+
+#include "datagram-face.hpp"
+
+namespace nfd
+{
+
+/**
+ * \brief Implementation of Face abstraction that uses UDP
+ *        as underlying transport mechanism
+ */
+class UdpFace : public DatagramFace<boost::asio::ip::udp>
+{
+public:
+  typedef boost::asio::ip::udp protocol;
+
+  explicit
+  UdpFace(const shared_ptr<protocol::socket>& socket);
+
+  //@todo if needed by other datagramFaces, it could be moved to datagram-face.hpp
+  /**
+   * \brief Manages the first datagram received by the UdpChannel socket set on listening
+   */
+  void
+  handleFirstReceive(const uint8_t* buffer,
+                     std::size_t nBytesReceived,
+                     const boost::system::error_code& error);
+
+};
+
+} // namespace nfd
+
+#endif // NFD_FACE_UDP_FACE_HPP
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
new file mode 100644
index 0000000..8dafb57
--- /dev/null
+++ b/daemon/face/udp-factory.cpp
@@ -0,0 +1,216 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "udp-factory.hpp"
+#include "core/global-io.hpp"
+#include "core/resolver.hpp"
+
+namespace nfd {
+
+using namespace boost::asio;
+  
+NFD_LOG_INIT("UdpFactory");
+
+UdpFactory::UdpFactory(const std::string& defaultPort/* = "6363"*/)
+  : m_defaultPort(defaultPort)
+{
+}
+
+shared_ptr<UdpChannel>
+UdpFactory::createChannel(const udp::Endpoint& endpoint,
+                          const time::Duration& 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 
+  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 "
+                "create a multicast face");
+  }
+
+  channel = make_shared<UdpChannel>(boost::cref(endpoint),
+                                    timeout);
+  m_channels[endpoint] = channel;
+
+  return channel;
+}
+
+shared_ptr<UdpChannel>
+UdpFactory::createChannel(const std::string& localHost,
+                          const std::string& localPort,
+                          const time::Duration& timeout)
+{
+  return createChannel(UdpResolver::syncResolve(localHost, localPort),
+                       timeout);
+}
+
+shared_ptr<MulticastUdpFace>
+UdpFactory::createMulticastFace(const udp::Endpoint& localEndpoint,
+                                       const udp::Endpoint& multicastEndpoint)
+{
+  //checking if the local and musticast endpoint are already in use for a multicast face
+  shared_ptr<MulticastUdpFace> multicastFace = findMulticastFace(localEndpoint);
+  if (static_cast<bool>(multicastFace)) {
+    if (multicastFace->getMulticastGroup() == multicastEndpoint)
+      return multicastFace;
+    else
+      throw Error("Cannot create the requested UDP multicast face, local "
+                  "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)) {
+    throw Error("Cannot create the requested UDP multicast face, local "
+                "endpoint is already allocated for a UDP unicast channel");
+  }
+
+  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. ");
+  }
+
+  if (!multicastEndpoint.address().is_multicast()) {
+    throw Error("Cannot create the requested UDP multicast face, "
+                "the multicast group given as input is not a multicast address");
+  }
+
+  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));
+
+  try {
+    clientSocket->bind(multicastEndpoint);
+
+    if (localEndpoint.address() != ip::address::from_string("0.0.0.0")) {
+      clientSocket->set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
+    }
+    clientSocket->set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
+                                                       localEndpoint.address().to_v4()));
+  }
+  catch (boost::system::system_error& e) {
+    std::stringstream msg;
+    msg << "Failed to properly configure the socket, check the address (" << e.what() << ")";
+    throw Error(msg.str());
+  }
+
+  clientSocket->set_option(ip::multicast::enable_loopback(false));
+
+  multicastFace = make_shared<MulticastUdpFace>(boost::cref(clientSocket));
+  multicastFace->onFail += bind(&UdpFactory::afterFaceFailed, this, localEndpoint);
+
+  m_multicastFaces[localEndpoint] = multicastFace;
+
+  return multicastFace;
+}
+
+shared_ptr<MulticastUdpFace>
+UdpFactory::createMulticastFace(const std::string& localIp,
+                                const std::string& multicastIp,
+                                const std::string& multicastPort)
+{
+  
+  return createMulticastFace(UdpResolver::syncResolve(localIp,
+                                                      multicastPort),
+                             UdpResolver::syncResolve(multicastIp,
+                                                      multicastPort));
+}
+
+void
+UdpFactory::createFace(const FaceUri& uri,
+                       const FaceCreatedCallback& onCreated,
+                       const FaceConnectFailedCallback& onConnectFailed)
+{
+  resolver::AddressSelector addressSelector = resolver::AnyAddress();
+  if (uri.getScheme() == "udp4")
+    addressSelector = resolver::Ipv4Address();
+  else if (uri.getScheme() == "udp6")
+    addressSelector = resolver::Ipv6Address();
+  
+  UdpResolver::asyncResolve(uri.getDomain(),
+                            uri.getPort().empty() ? m_defaultPort : uri.getPort(),
+                            bind(&UdpFactory::continueCreateFaceAfterResolve, this, _1,
+                                 onCreated, onConnectFailed),
+                            onConnectFailed,
+                            addressSelector);
+
+}
+
+void
+UdpFactory::continueCreateFaceAfterResolve(const udp::Endpoint& endpoint,
+                                           const FaceCreatedCallback& onCreated,
+                                           const FaceConnectFailedCallback& onConnectFailed)
+{
+  if (endpoint.address().is_multicast()) {
+    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)
+  {
+    if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
+        (channel->first.address().is_v6() && endpoint.address().is_v6()))
+    {
+      channel->second->connect(endpoint, onCreated);
+      return;
+    }
+  }
+  onConnectFailed("No channels available to connect to "
+                  + boost::lexical_cast<std::string>(endpoint));
+}
+
+shared_ptr<UdpChannel>
+UdpFactory::findChannel(const udp::Endpoint& localEndpoint)
+{
+  ChannelMap::iterator i = m_channels.find(localEndpoint);
+  if (i != m_channels.end())
+    return i->second;
+  else
+    return shared_ptr<UdpChannel>();
+}
+
+shared_ptr<MulticastUdpFace>
+UdpFactory::findMulticastFace(const udp::Endpoint& localEndpoint)
+{
+  MulticastFaceMap::iterator i = m_multicastFaces.find(localEndpoint);
+  if (i != m_multicastFaces.end())
+    return i->second;
+  else
+    return shared_ptr<MulticastUdpFace>();
+}
+
+void
+UdpFactory::afterFaceFailed(udp::Endpoint& endpoint)
+{
+  NFD_LOG_DEBUG("afterFaceFailed: " << endpoint);
+  m_multicastFaces.erase(endpoint);
+}
+
+
+} // namespace nfd
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
new file mode 100644
index 0000000..695d1e5
--- /dev/null
+++ b/daemon/face/udp-factory.hpp
@@ -0,0 +1,171 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_FACE_UDP_FACTORY_HPP
+#define NFD_FACE_UDP_FACTORY_HPP
+
+#include "protocol-factory.hpp"
+#include "udp-channel.hpp"
+#include "multicast-udp-face.hpp"
+
+
+namespace nfd {
+
+// @todo The multicast support for ipv6 must be implemented
+
+class UdpFactory : public ProtocolFactory
+{
+public:
+  /**
+   * \brief Exception of UdpFactory
+   */
+  struct Error : public ProtocolFactory::Error
+  {
+    Error(const std::string& what) : ProtocolFactory::Error(what) {}
+  };
+  
+  explicit
+  UdpFactory(const std::string& defaultPort = "6363");
+
+  /**
+   * \brief Create UDP-based channel using udp::Endpoint
+   *
+   * udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
+   *
+   * If this method called twice with the same endpoint, only one channel
+   * will be created.  The second call will just retrieve the existing
+   * channel.
+   *
+   * If a multicast face is already active on the same local endpoint,
+   * the creation fails and an exception is thrown
+   *
+   * Once a face is created, if it doesn't send/receive anything for
+   * a period of time equal to timeout, it will be destroyed
+   * @todo this funcionality has to be implemented
+   *
+   * \returns always a valid pointer to a UdpChannel object, an exception
+   *          is thrown if it cannot be created.
+   *
+   * \throws UdpFactory::Error
+   *
+   * \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__udp/endpoint.html
+   *      for details on ways to create udp::Endpoint
+   */
+  shared_ptr<UdpChannel>
+  createChannel(const udp::Endpoint& localEndpoint,
+         const time::Duration& timeout = time::seconds(600));
+
+  /**
+   * \brief Create UDP-based channel using specified host and port number
+   *
+   * This method will attempt to resolve the provided host and port numbers
+   * and will throw UdpFactory::Error when channel cannot be created.
+   *
+   * Note that this call will **BLOCK** until resolution is done or failed.
+   *
+   * If localHost is a IPv6 address of a specific device, it must be in the form: 
+   * ip address%interface name
+   * Example: fe80::5e96:9dff:fe7d:9c8d%en1
+   * Otherwise, you can use :: 
+   *
+   * Once a face is created, if it doesn't send/receive anything for
+   * a period of time equal to timeout, it will be destroyed
+   * @todo this funcionality has to be implemented
+   *
+   * \throws UdpChannel::Error if the bind on the socket fails
+   * \throws UdpFactory::Error
+   */
+  shared_ptr<UdpChannel>
+  createChannel(const std::string& localHost,
+         const std::string& localPort,
+         const time::Duration& timeout = time::seconds(600));
+
+  /**
+   * \brief Create MulticastUdpFace using udp::Endpoint
+   *
+   * udp::Endpoint is really an alias for boost::asio::ip::udp::endpoint.
+   *
+   * The face will join the multicast group
+   *
+   * If this method called twice with the same endpoint and group, only one face
+   * will be created.  The second call will just retrieve the existing
+   * channel.
+   *
+   * If an unicast face is already active on the same local NIC and port, the
+   * creation fails and an exception is thrown
+   *
+   * \returns always a valid pointer to a MulticastUdpFace object, an exception
+   *          is thrown if it cannot be created. 
+   *
+   * \throws UdpFactory::Error
+   *
+   * \see http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__udp/endpoint.html
+   *      for details on ways to create udp::Endpoint
+   */
+  shared_ptr<MulticastUdpFace>
+  createMulticastFace(const udp::Endpoint& localEndpoint,
+                      const udp::Endpoint& multicastEndpoint);
+  
+  shared_ptr<MulticastUdpFace>
+  createMulticastFace(const std::string& localIp,
+                      const std::string& multicastIp,
+                      const std::string& multicastPort);
+  
+  // from Factory
+  virtual void
+  createFace(const FaceUri& uri,
+             const FaceCreatedCallback& onCreated,
+             const FaceConnectFailedCallback& onConnectFailed);
+
+protected:
+  typedef std::map< udp::Endpoint, shared_ptr<MulticastUdpFace> > MulticastFaceMap;
+
+  /**
+   * \brief Keeps tracking of the MulticastUdpFace created
+   */
+  MulticastFaceMap m_multicastFaces;
+
+private:
+  void
+  afterFaceFailed(udp::Endpoint& endpoint);
+    
+  /**
+   * \brief Look up UdpChannel using specified local endpoint
+   *
+   * \returns shared pointer to the existing UdpChannel object
+   *          or empty shared pointer when such channel does not exist
+   *
+   * \throws never
+   */
+  shared_ptr<UdpChannel>
+  findChannel(const udp::Endpoint& localEndpoint);
+  
+  
+  /**
+   * \brief Look up multicast UdpFace using specified local endpoint
+   *
+   * \returns shared pointer to the existing multicast MulticastUdpFace object
+   *          or empty shared pointer when such face does not exist
+   *
+   * \throws never
+   */
+  shared_ptr<MulticastUdpFace>
+  findMulticastFace(const udp::Endpoint& localEndpoint);
+  
+  void
+  continueCreateFaceAfterResolve(const udp::Endpoint& endpoint,
+                                 const FaceCreatedCallback& onCreated,
+                                 const FaceConnectFailedCallback& onConnectFailed);
+  
+  typedef std::map< udp::Endpoint, shared_ptr<UdpChannel> > ChannelMap;
+  ChannelMap m_channels;
+  
+  std::string m_defaultPort;
+};
+
+} // namespace nfd
+
+#endif // NFD_FACE_UDP_FACTORY_HPP
