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
diff --git a/tests/face/udp.cpp b/tests/face/udp.cpp
new file mode 100644
index 0000000..02c4319
--- /dev/null
+++ b/tests/face/udp.cpp
@@ -0,0 +1,869 @@
+/* -*- 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 "face/udp-factory.hpp"
+#include "core/scheduler.hpp"
+#include "core/face-uri.hpp"
+#include "tests/test-common.hpp"
+
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <boost/asio.hpp>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceUdp, BaseFixture)
+
+class FactoryErrorCheck : protected BaseFixture
+{
+public:
+  bool isTheSameMulticastEndpoint(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP unicast channel, local "
+                  "endpoint is already allocated for a UDP multicast face") == 0;
+  }
+  
+  bool isNotMulticastAddress(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, "
+                  "the multicast group given as input is not a multicast address") == 0;
+  }
+  
+  bool isTheSameUnicastEndpoint(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, local "
+                  "endpoint is already allocated for a UDP unicast channel") == 0;
+  }
+  
+  bool isLocalEndpointOnDifferentGroup(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, local "
+                  "endpoint is already allocated for a UDP multicast face "
+                  "on a different multicast group") == 0;
+  }
+};
+  
+BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
+{
+  using boost::asio::ip::udp;
+ 
+  UdpFactory factory = UdpFactory();
+  
+  //to instantiate multicast face on a specific ip address, change interfaceIp
+  std::string interfaceIp = "0.0.0.0";
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  BOOST_CHECK_NE(channel1, channel2);
+
+  shared_ptr<UdpChannel> channel3 = factory.createChannel(interfaceIp, "20070");
+    
+  //same endpoint of a unicast channel
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "224.0.0.1",
+                                                    "20070"),
+                        UdpFactory::Error,
+                        isTheSameUnicastEndpoint);
+    
+    
+  shared_ptr<MulticastUdpFace> multicastFace1 = factory.createMulticastFace(interfaceIp,
+                                                                            "224.0.0.1",
+                                                                            "20072");
+  shared_ptr<MulticastUdpFace> multicastFace1a = factory.createMulticastFace(interfaceIp,
+                                                                            "224.0.0.1",
+                                                                            "20072");
+  BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
+    
+    
+  //same endpoint of a multicast face
+  BOOST_CHECK_EXCEPTION(factory.createChannel(interfaceIp, "20072"),
+                        UdpFactory::Error,
+                        isTheSameMulticastEndpoint);
+    
+  //same multicast endpoint, different group
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "224.0.0.42",
+                                                    "20072"),
+                        UdpFactory::Error,
+                        isLocalEndpointOnDifferentGroup);
+
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "192.168.10.15",
+                                                    "20025"),
+                        UdpFactory::Error,
+                        isNotMulticastAddress);
+
+  
+  
+//  //Test commented because it required to be run in a machine that can resolve ipv6 query
+//  shared_ptr<UdpChannel> channel1v6 = factory.createChannel(//"::1",
+//                                                     "fe80::5e96:9dff:fe7d:9c8d%en1",
+//                                                     //"fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                     "20070");
+//
+//  //the creation of multicastFace2 works properly. It has been disable because it needs an IP address of
+//  //an available network interface (different from the first one used)
+//  shared_ptr<MulticastUdpFace> multicastFace2 = factory.createMulticastFace("192.168.1.17",
+//                                                                            "224.0.0.1",
+//                                                                            "20073");
+//  BOOST_CHECK_NE(multicastFace1, multicastFace2);
+//
+//
+//  //ipv6 - work in progress
+//  shared_ptr<MulticastUdpFace> multicastFace3 = factory.createMulticastFace("fe80::5e96:9dff:fe7d:9c8d%en1",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//  
+//  shared_ptr<MulticastUdpFace> multicastFace4 = factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//  
+//  BOOST_CHECK_EQUAL(multicastFace3, multicastFace4);
+//
+//  shared_ptr<MulticastUdpFace> multicastFace5 = factory.createMulticastFace("::1",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//  
+//  BOOST_CHECK_NE(multicastFace3, multicastFace5);
+//
+//  //same local ipv6 endpoint for a different multicast group
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                "FE01:0:0:0:0:0:0:2",
+//                                                "20073"),
+//                    UdpFactory::Error);
+//  
+//  //same local ipv6 (expect for th port number) endpoint for a different multicast group
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                "FE01:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+//
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
+//                                                "FE12:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+//
+//  //not a multicast ipv6
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
+//                                                "A112:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+
+
+
+}
+
+class EndToEndFixture : protected BaseFixture
+{
+public:
+  void
+  channel1_onFaceCreated(const shared_ptr<UdpFace>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(m_face1));
+    m_face1 = newFace;
+    m_face1->onReceiveInterest +=
+      bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
+    m_face1->onReceiveData +=
+      bind(&EndToEndFixture::face1_onReceiveData, this, _1);
+    m_face1->onFail += 
+      bind(&EndToEndFixture::face1_onFail, this);
+    BOOST_CHECK_MESSAGE(true, "channel 1 face created");
+
+    m_faces.push_back(m_face1);
+
+    this->afterIo();
+  }
+
+  void
+  channel1_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    this->afterIo();
+  }
+  
+  void
+  face1_onReceiveInterest(const Interest& interest)
+  {
+    m_face1_receivedInterests.push_back(interest);
+
+    this->afterIo();
+  }
+  
+  void
+  face1_onReceiveData(const Data& data)
+  {
+    m_face1_receivedDatas.push_back(data);
+
+    this->afterIo();
+  }
+
+  void
+  face1_onFail()
+  {
+    m_face1.reset();
+    this->afterIo();
+  }
+
+  void
+  channel2_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(m_face2));
+    m_face2 = newFace;
+    m_face2->onReceiveInterest +=
+      bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+    m_face2->onReceiveData +=
+      bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+    m_face2->onFail += 
+      bind(&EndToEndFixture::face2_onFail, this);
+
+    m_faces.push_back(m_face2);
+
+    BOOST_CHECK_MESSAGE(true, "channel 2 face created");
+    this->afterIo();
+  }
+  
+  void
+  channel2_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    this->afterIo();
+  }
+  
+  void
+  face2_onReceiveInterest(const Interest& interest)
+  {
+    m_face2_receivedInterests.push_back(interest);
+
+    this->afterIo();
+  }
+  
+  void
+  face2_onReceiveData(const Data& data)
+  {
+    m_face2_receivedDatas.push_back(data);
+
+    this->afterIo();
+  }
+
+  void
+  face2_onFail()
+  {
+    m_face2.reset();
+    this->afterIo();
+  }
+
+  void
+  channel3_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(m_face1));
+    m_face3 = newFace;
+    m_faces.push_back(newFace);
+    
+    this->afterIo();
+  }
+
+  
+  void
+  channel_onFaceCreated(const shared_ptr<UdpFace>& newFace)
+  {
+    m_faces.push_back(newFace);
+    this->afterIo();
+  }
+
+  void
+  channel_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    this->afterIo();
+  }
+
+  void
+  channel_onConnectFailedOk(const std::string& reason)
+  {
+    //it's ok, it was supposed to fail
+    this->afterIo();
+  }
+
+  void
+  checkFaceList(size_t shouldBe)
+  {
+    BOOST_CHECK_EQUAL(m_faces.size(), shouldBe);
+  }
+  
+  void
+  abortTestCase(const std::string& message)
+  {
+    g_io.stop();
+    BOOST_FAIL(message);
+  }
+  
+private:
+  void
+  afterIo()
+  {
+    if (--m_ioRemaining <= 0) g_io.stop();
+  }
+
+public:
+  int m_ioRemaining;
+
+  shared_ptr<Face> m_face1;
+  std::vector<Interest> m_face1_receivedInterests;
+  std::vector<Data> m_face1_receivedDatas;
+  shared_ptr<Face> m_face2;
+  std::vector<Interest> m_face2_receivedInterests;
+  std::vector<Data> m_face2_receivedDatas;
+  
+  shared_ptr<Face> m_face3;
+
+
+  std::list< shared_ptr<Face> > m_faces;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
+{
+  UdpFactory factory = UdpFactory();
+  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+
+  EventId abortEvent =
+    scheduler.scheduleEvent(time::seconds(1),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept connection"));
+  
+  m_ioRemaining = 1;
+
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  
+  
+  //channel2->connect("127.0.0.1", "20070",
+  //                  bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+  //                  bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+  
+  factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
+                     bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                     bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+  
+  
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_REQUIRE(static_cast<bool>(m_face2));
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+  
+  
+  abortEvent =
+    scheduler.scheduleEvent(time::seconds(1),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot send or receive Interest/Data packets"));
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+  Interest interest3("ndn:/QWiIhjgkj5sL");
+  Data     data3    ("ndn:/XNBV794f");
+  data3.setContent(0, 0);
+
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
+                                        reinterpret_cast<const uint8_t*>(0),
+                                        0));
+  
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+  data3.setSignature(fakeSignature);
+
+  m_face2->sendInterest(interest2);
+  m_face2->sendData    (data2    );
+
+  m_ioRemaining = 3; //2 send + 1 listen return
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_REQUIRE(static_cast<bool>(m_face1));
+  
+  m_face1->sendInterest(interest1);
+  m_face1->sendData    (data1    );
+  
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 2;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+
+  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+  BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(m_face2_receivedDatas    .size(), 1);
+  
+  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(m_face2_receivedDatas    [0].getName(), data1.getName());
+  
+  
+  
+  //checking if the connection accepting mechanism works properly.
+ 
+  m_face2->sendData    (data3    );
+  m_face2->sendInterest(interest3);
+
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 2;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+  
+  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 2);
+  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 2);
+  
+  BOOST_CHECK_EQUAL(m_face1_receivedInterests[1].getName(), interest3.getName());
+  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [1].getName(), data3.getName());
+
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
+{
+  Interest interest1("ndn:/TpnzGvW9R");
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Interest interest3("ndn:/QWiIhjgkj5sL");
+
+  UdpFactory factory = UdpFactory();
+  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+
+  EventId abortEvent =
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept connection"));
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  
+  
+  
+  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+  
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+  
+  
+  m_ioRemaining = 1;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_CHECK_EQUAL(m_faces.size(), 1);
+  
+  shared_ptr<UdpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
+  channel3->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+  
+  shared_ptr<UdpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
+
+  BOOST_CHECK_NE(channel3, channel4);
+  
+  scheduler
+    .scheduleEvent
+    (time::seconds(0.5),
+     bind(&UdpChannel::connect, channel4,
+          "127.0.0.1", "20070",
+          // does not work without static_cast
+          static_cast<UdpChannel::FaceCreatedCallback>(bind(&EndToEndFixture::
+                                                            channel_onFaceCreated,
+                                                            this,
+                                                            _1)),
+          static_cast<UdpChannel::ConnectFailedCallback>(bind(&EndToEndFixture::
+                                                              channel_onConnectFailed,
+                                                              this,
+                                                              _1))));
+  
+  m_ioRemaining = 2; // 2 connects
+  abortEvent = 
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept multiple connections"));
+
+  scheduler.scheduleEvent(time::seconds(0.4),
+                          bind(&EndToEndFixture::checkFaceList, this, 2));
+  
+  g_io.run();
+  g_io.reset();
+  
+  BOOST_CHECK_EQUAL(m_faces.size(), 3);
+  
+  
+  m_face2->sendInterest(interest1);
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 1;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+  
+  BOOST_CHECK_EQUAL(m_faces.size(), 4);
+  
+  m_face3->sendInterest(interest2);
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 1;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+  
+  //channel1 should have created 2 faces, one when m_face2 sent an interest, one when m_face3 sent an interest
+  BOOST_CHECK_EQUAL(m_faces.size(), 5);
+  BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,
+                                          this,
+                                          _1),
+                                    bind(&EndToEndFixture::channel_onConnectFailedOk,
+                                         this,
+                                         _1)),
+                    UdpChannel::Error);
+}
+  
+//Test commented because it required to be run in a machine that can resolve ipv6 query
+//BOOST_FIXTURE_TEST_CASE(EndToEndIpv6, EndToEndFixture)
+//{
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//    
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                              "UdpChannel error: cannot connect or cannot accept connection"));
+//    
+//  m_ioRemaining = 1;
+//    
+//  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+//  shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
+//    
+//  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+//                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+//    
+//  channel2->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_REQUIRE(static_cast<bool>(m_face2));
+//    
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//    
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Data     data1    ("ndn:/KfczhUqVix");
+//  data1.setContent(0, 0);
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Data     data2    ("ndn:/XNBV796f");
+//  data2.setContent(0, 0);
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//  Data     data3    ("ndn:/XNBV794f");
+//  data3.setContent(0, 0);
+//  
+//  ndn::SignatureSha256WithRsa fakeSignature;
+//  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+//    
+//  // set fake signature on data1 and data2
+//  data1.setSignature(fakeSignature);
+//  data2.setSignature(fakeSignature);
+//  data3.setSignature(fakeSignature);
+//    
+//  m_face2->sendInterest(interest2);
+//  m_face2->sendData    (data2    );
+//    
+//  m_ioRemaining = 3; //2 send + 1 listen return
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_REQUIRE(static_cast<bool>(m_face1));
+//    
+//  m_face1->sendInterest(interest1);
+//  m_face1->sendData    (data1    );
+//  
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//  
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face2_receivedDatas    .size(), 1);
+//    
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data2.getName());
+//  BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
+//  BOOST_CHECK_EQUAL(m_face2_receivedDatas    [0].getName(), data1.getName());
+//    
+//  //checking if the connection accepting mechanism works properly.
+//    
+//  m_face2->sendData    (data3    );
+//  m_face2->sendInterest(interest3);
+//    
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 2);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 2);
+//    
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[1].getName(), interest3.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [1].getName(), data3.getName());
+//    
+//}
+
+
+//Test commented because it required to be run in a machine that can resolve ipv6 query
+//BOOST_FIXTURE_TEST_CASE(MultipleAcceptsIpv6, EndToEndFixture)
+//{
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//    
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//    
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(4),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot connect or cannot accept connection"));
+//    
+//  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+//  shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
+//    
+//  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+//                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//    
+//  channel2->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//    
+//  m_ioRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_CHECK_EQUAL(m_faces.size(), 1);
+//    
+//  shared_ptr<UdpChannel> channel3 = factory.createChannel("::1", "20072");
+//  channel3->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//    
+//  shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20073");
+//    
+//  BOOST_CHECK_NE(channel3, channel4);
+//    
+//  scheduler
+//  .scheduleEvent(time::seconds(0.5),
+//                 bind(&UdpChannel::connect, channel4,
+//                      "::1", "20070",
+//                      static_cast<UdpChannel::FaceCreatedCallback>(bind(&EndToEndFixture::
+//                                                                        channel_onFaceCreated, this, _1)),
+//                      static_cast<UdpChannel::ConnectFailedCallback>(bind(&EndToEndFixture::
+//                                                                          channel_onConnectFailed, this, _1))));
+//    
+//  m_ioRemaining = 2; // 2 connects
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(4),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot connect or cannot accept multiple connections"));
+//    
+//  scheduler.scheduleEvent(time::seconds(0.4),
+//                          bind(&EndToEndFixture::checkFaceList, this, 2));
+//    
+//  g_io.run();
+//  g_io.reset();
+//    
+//  BOOST_CHECK_EQUAL(m_faces.size(), 3);
+//    
+//    
+//  m_face2->sendInterest(interest1);
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_CHECK_EQUAL(m_faces.size(), 4);
+//    
+//  m_face3->sendInterest(interest2);
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  //channel1 should have created 2 faces, one when m_face2 sent an interest, one when m_face3 sent an interest
+//  BOOST_CHECK_EQUAL(m_faces.size(), 5);
+//  BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,
+//                                          this,
+//                                          _1),
+//                                      bind(&EndToEndFixture::channel_onConnectFailedOk,
+//                                          this,
+//                                          _1)),
+//                    UdpChannel::Error);
+//}
+
+
+BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
+{
+  UdpFactory factory = UdpFactory();
+  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+
+  EventId abortEvent =
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept connection"));
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+  
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+  
+  m_ioRemaining = 1;
+  BOOST_REQUIRE_NO_THROW(g_io.run());
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+
+  abortEvent =
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "FaceClosing error: cannot properly close faces"));
+
+  BOOST_CHECK(static_cast<bool>(m_face2));
+
+  m_ioRemaining = 1;
+  // just double check that we are calling the virtual method
+  static_pointer_cast<Face>(m_face2)->close();
+  
+  BOOST_REQUIRE_NO_THROW(g_io.run());
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_CHECK(!static_cast<bool>(m_face2));
+  
+  BOOST_CHECK_EQUAL(channel2->size(), 0);
+}
+
+//BOOST_FIXTURE_TEST_CASE(MulticastFace, EndToEndFixture)
+//{
+//  //to instantiate multicast face on a specific ip address, change interfaceIp
+//  std::string interfaceIp = "0.0.0.0";
+//  
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//  
+//  shared_ptr<MulticastUdpFace> multicastFace1 =
+//    factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
+//  
+//  BOOST_REQUIRE(static_cast<bool>(multicastFace1));
+//  
+//  channel1_onFaceCreated(multicastFace1);
+//
+//  
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(10),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "MulticastFace error: cannot send or receive Interest/Data packets"));
+//  
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Data     data1    ("ndn:/KfczhUqVix");
+//  data1.setContent(0, 0);
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Data     data2    ("ndn:/XNBV796f");
+//  data2.setContent(0, 0);
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//  Data     data3    ("ndn:/XNBV794f");
+//  data3.setContent(0, 0);
+//  
+//  
+//  ndn::SignatureSha256WithRsa fakeSignature;
+//  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+//  
+//  // set fake signature on data1 and data2
+//  data1.setSignature(fakeSignature);
+//  data2.setSignature(fakeSignature);
+//  data3.setSignature(fakeSignature);
+//  
+//  multicastFace1->sendInterest(interest1);
+//  multicastFace1->sendData    (data1    );
+//  
+//  g_io.reset();
+//  m_ioRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//  
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+//  
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest1.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data1.getName());
+//}
+
+  
+  
+BOOST_AUTO_TEST_SUITE_END()
+} // namespace tests
+} // namespace nfd
