blob: ca05dee71471956bb01aedade94e1e6cb0b22a6a [file] [log] [blame]
Alexander Afanasyeva9034b02014-01-26 18:32:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NFD_FACE_TCP_CHANNEL_HPP
8#define NFD_FACE_TCP_CHANNEL_HPP
9
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080010#include "common.hpp"
Junxiao Shic041ca32014-02-25 20:01:15 -070011#include "core/time.hpp"
12#include <ndn-cpp-dev/util/monotonic_deadline_timer.hpp>
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080013#include "tcp-face.hpp"
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080014
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080015namespace nfd {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080016
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010017namespace tcp {
18 typedef boost::asio::ip::tcp::endpoint Endpoint;
19} // namespace tcp
20
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080021/**
22 * \brief Class implementing TCP-based channel to create faces
23 *
24 * Channel can create faces as a response to incoming TCP
25 * connections (TcpChannel::listen needs to be called for that
26 * to work) or explicitly after using TcpChannel::connect method.
27 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080028class TcpChannel // : protected SessionBasedChannel
29{
30public:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080031 /**
32 * \brief Prototype for the callback called when face is created
33 * (as a response to incoming connection or after connection
34 * is established)
35 */
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080036 typedef function<void(const shared_ptr<Face>& newFace)> FaceCreatedCallback;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080037
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080038 /**
39 * \brief Prototype for the callback that is called when face is failed to
40 * get created
41 */
42 typedef function<void(const std::string& reason)> ConnectFailedCallback;
43
44 /**
45 * \brief Create TCP channel for the local endpoint
46 *
47 * To enable creation faces upon incoming connections,
48 * one needs to explicitly call TcpChannel::listen method.
49 */
50 TcpChannel(boost::asio::io_service& ioService,
51 const tcp::Endpoint& localEndpoint);
52
53 /**
54 * \brief Enable listening on the local endpoint, accept connections,
55 * and create faces when remote host makes a connection
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080056 * \param onFaceCreated Callback to notify successful creation of the face
57 * \param onAcceptFailed Callback to notify when channel fails (accept call
58 * returns an error)
59 * \param backlog The maximum length of the queue of pending incoming
60 * connections
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080061 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080062 void
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080063 listen(const FaceCreatedCallback& onFaceCreated,
64 const ConnectFailedCallback& onAcceptFailed,
65 int backlog = boost::asio::ip::tcp::acceptor::max_connections);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080066
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080067 /**
68 * \brief Create a face by establishing connection to remote endpoint
69 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080070 void
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080071 connect(const tcp::Endpoint& remoteEndpoint,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080072 const FaceCreatedCallback& onFaceCreated,
73 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080074 const time::Duration& timeout = time::seconds(4));
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080075
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080076 /**
77 * \brief Create a face by establishing connection to the specified
78 * remote host and remote port
79 *
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080080 * This method will never block and will return immediately. All
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080081 * necessary hostname and port resolution and connection will happen
82 * in asynchronous mode.
83 *
84 * If connection cannot be established within specified timeout, it
85 * will be aborted.
86 */
87 void
88 connect(const std::string& remoteHost, const std::string& remotePort,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080089 const FaceCreatedCallback& onFaceCreated,
90 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080091 const time::Duration& timeout = time::seconds(4));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080092
93 /**
94 * \brief Get number of faces in the channel
95 */
96 size_t
97 size() const;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080098
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080099private:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800100 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800101 createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
102 const FaceCreatedCallback& onFaceCreated);
103
104 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800105 afterFaceFailed(tcp::Endpoint &endpoint);
106
107 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800108 handleSuccessfulAccept(const boost::system::error_code& error,
109 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
110 const FaceCreatedCallback& onFaceCreated,
111 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800112
113 void
114 handleSuccessfulConnect(const boost::system::error_code& error,
115 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800116 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
117 const FaceCreatedCallback& onFaceCreated,
118 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800119
120 void
121 handleFailedConnect(const boost::system::error_code& error,
122 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800123 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
124 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800125
126 void
Davide Pesavento855bf292014-02-27 03:58:01 +0100127 handleEndpointResolution(const boost::system::error_code& error,
128 boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
129 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
130 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
131 const FaceCreatedCallback& onFaceCreated,
132 const ConnectFailedCallback& onConnectFailed,
133 const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800134
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800135private:
136 boost::asio::io_service& m_ioService;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800137 tcp::Endpoint m_localEndpoint;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800138
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800139 typedef std::map< tcp::Endpoint, shared_ptr<Face> > ChannelFaceMap;
Alexander Afanasyev334b7142014-01-28 12:59:39 -0800140 ChannelFaceMap m_channelFaces;
141
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800142 bool isListening;
143 shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800144};
145
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800146} // namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800147
148#endif // NFD_FACE_TCP_CHANNEL_HPP