blob: db6521f0bd4f85b28d4b373947db08fdf33e0fde [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"
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080011#include "core/monotonic_deadline_timer.hpp"
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080012#include "tcp-face.hpp"
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080013
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080014namespace nfd {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080015
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010016namespace tcp {
17 typedef boost::asio::ip::tcp::endpoint Endpoint;
18} // namespace tcp
19
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080020/**
21 * \brief Class implementing TCP-based channel to create faces
22 *
23 * Channel can create faces as a response to incoming TCP
24 * connections (TcpChannel::listen needs to be called for that
25 * to work) or explicitly after using TcpChannel::connect method.
26 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080027class TcpChannel // : protected SessionBasedChannel
28{
29public:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080030 /**
31 * \brief Prototype for the callback called when face is created
32 * (as a response to incoming connection or after connection
33 * is established)
34 */
Alexander Afanasyevbd220a02014-02-20 00:29:56 -080035 typedef function<void(const shared_ptr<Face>& newFace)> FaceCreatedCallback;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080036
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080037 /**
38 * \brief Prototype for the callback that is called when face is failed to
39 * get created
40 */
41 typedef function<void(const std::string& reason)> ConnectFailedCallback;
42
43 /**
44 * \brief Create TCP channel for the local endpoint
45 *
46 * To enable creation faces upon incoming connections,
47 * one needs to explicitly call TcpChannel::listen method.
48 */
49 TcpChannel(boost::asio::io_service& ioService,
50 const tcp::Endpoint& localEndpoint);
51
52 /**
53 * \brief Enable listening on the local endpoint, accept connections,
54 * and create faces when remote host makes a connection
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080055 * \param onFaceCreated Callback to notify successful creation of the face
56 * \param onAcceptFailed Callback to notify when channel fails (accept call
57 * returns an error)
58 * \param backlog The maximum length of the queue of pending incoming
59 * connections
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080060 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080061 void
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080062 listen(const FaceCreatedCallback& onFaceCreated,
63 const ConnectFailedCallback& onAcceptFailed,
64 int backlog = boost::asio::ip::tcp::acceptor::max_connections);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080065
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080066 /**
67 * \brief Create a face by establishing connection to remote endpoint
68 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080069 void
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080070 connect(const tcp::Endpoint& remoteEndpoint,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080071 const FaceCreatedCallback& onFaceCreated,
72 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080073 const time::Duration& timeout = time::seconds(4));
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080074
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080075 /**
76 * \brief Create a face by establishing connection to the specified
77 * remote host and remote port
78 *
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080079 * This method will never block and will return immediately. All
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080080 * necessary hostname and port resolution and connection will happen
81 * in asynchronous mode.
82 *
83 * If connection cannot be established within specified timeout, it
84 * will be aborted.
85 */
86 void
87 connect(const std::string& remoteHost, const std::string& remotePort,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080088 const FaceCreatedCallback& onFaceCreated,
89 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080090 const time::Duration& timeout = time::seconds(4));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080091
92 /**
93 * \brief Get number of faces in the channel
94 */
95 size_t
96 size() const;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080097
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080098private:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080099 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800100 createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
101 const FaceCreatedCallback& onFaceCreated);
102
103 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800104 afterFaceFailed(tcp::Endpoint &endpoint);
105
106 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800107 handleSuccessfulAccept(const boost::system::error_code& error,
108 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
109 const FaceCreatedCallback& onFaceCreated,
110 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800111
112 void
113 handleSuccessfulConnect(const boost::system::error_code& error,
114 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800115 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
116 const FaceCreatedCallback& onFaceCreated,
117 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800118
119 void
120 handleFailedConnect(const boost::system::error_code& error,
121 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800122 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
123 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800124
125 void
126 handleEndpointResoution(const boost::system::error_code& error,
127 boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
128 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800129 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
130 const FaceCreatedCallback& onFaceCreated,
Alexander Afanasyev3958b012014-01-31 15:06:13 -0800131 const ConnectFailedCallback& onConnectFailed,
132 const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800133
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800134private:
135 boost::asio::io_service& m_ioService;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800136 tcp::Endpoint m_localEndpoint;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800137
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800138 typedef std::map< tcp::Endpoint, shared_ptr<Face> > ChannelFaceMap;
Alexander Afanasyev334b7142014-01-28 12:59:39 -0800139 ChannelFaceMap m_channelFaces;
140
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800141 bool isListening;
142 shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800143};
144
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800145} // namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800146
147#endif // NFD_FACE_TCP_CHANNEL_HPP