face: UDP face/channel/factory
Change-Id: I4683b45378637133982efd23edd16a0c35148948
refs #1189
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