blob: e31723b545e7b421cbe80558a4081ed2e47bb7d5 [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
Junxiao Shi61e3cc52014-03-03 20:40:28 -070010#include "channel.hpp"
Junxiao Shic041ca32014-02-25 20:01:15 -070011#include <ndn-cpp-dev/util/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 {
Junxiao Shi61e3cc52014-03-03 20:40:28 -070017typedef boost::asio::ip::tcp::endpoint Endpoint;
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010018} // 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 */
Junxiao Shi61e3cc52014-03-03 20:40:28 -070027class TcpChannel : public Channel
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080028{
29public:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080030 /**
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080031 * \brief Create TCP channel for the local endpoint
32 *
33 * To enable creation faces upon incoming connections,
34 * one needs to explicitly call TcpChannel::listen method.
35 */
Junxiao Shi61e3cc52014-03-03 20:40:28 -070036 explicit
37 TcpChannel(const tcp::Endpoint& localEndpoint);
38
39 virtual
40 ~TcpChannel();
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080041
42 /**
43 * \brief Enable listening on the local endpoint, accept connections,
44 * and create faces when remote host makes a connection
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080045 * \param onFaceCreated Callback to notify successful creation of the face
46 * \param onAcceptFailed Callback to notify when channel fails (accept call
47 * returns an error)
48 * \param backlog The maximum length of the queue of pending incoming
49 * connections
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080050 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080051 void
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080052 listen(const FaceCreatedCallback& onFaceCreated,
53 const ConnectFailedCallback& onAcceptFailed,
54 int backlog = boost::asio::ip::tcp::acceptor::max_connections);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080055
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080056 /**
57 * \brief Create a face by establishing connection to remote endpoint
58 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080059 void
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080060 connect(const tcp::Endpoint& remoteEndpoint,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080061 const FaceCreatedCallback& onFaceCreated,
62 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070063 const time::seconds& timeout = time::seconds(4));
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080064
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080065 /**
66 * \brief Create a face by establishing connection to the specified
67 * remote host and remote port
68 *
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080069 * This method will never block and will return immediately. All
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080070 * necessary hostname and port resolution and connection will happen
71 * in asynchronous mode.
72 *
73 * If connection cannot be established within specified timeout, it
74 * will be aborted.
75 */
76 void
77 connect(const std::string& remoteHost, const std::string& remotePort,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080078 const FaceCreatedCallback& onFaceCreated,
79 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070080 const time::seconds& timeout = time::seconds(4));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080081
82 /**
83 * \brief Get number of faces in the channel
84 */
85 size_t
Junxiao Shi61e3cc52014-03-03 20:40:28 -070086 size() const;
87
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -070088 bool
89 isListening() const;
90
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080091private:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080092 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -080093 createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev355c0662014-03-20 18:08:17 -070094 const FaceCreatedCallback& onFaceCreated,
95 bool isOnDemand);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -080096
97 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080098 afterFaceFailed(tcp::Endpoint &endpoint);
99
100 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800101 handleSuccessfulAccept(const boost::system::error_code& error,
102 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
103 const FaceCreatedCallback& onFaceCreated,
104 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800105
106 void
107 handleSuccessfulConnect(const boost::system::error_code& error,
108 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700109 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800110 const FaceCreatedCallback& onFaceCreated,
111 const ConnectFailedCallback& onConnectFailed);
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700112
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800113 void
114 handleFailedConnect(const boost::system::error_code& error,
115 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700116 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800117 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800118
119 void
Davide Pesavento855bf292014-02-27 03:58:01 +0100120 handleEndpointResolution(const boost::system::error_code& error,
121 boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
122 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700123 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Davide Pesavento855bf292014-02-27 03:58:01 +0100124 const FaceCreatedCallback& onFaceCreated,
125 const ConnectFailedCallback& onConnectFailed,
126 const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800127
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800128private:
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800129 tcp::Endpoint m_localEndpoint;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800130
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800131 typedef std::map< tcp::Endpoint, shared_ptr<Face> > ChannelFaceMap;
Alexander Afanasyev334b7142014-01-28 12:59:39 -0800132 ChannelFaceMap m_channelFaces;
133
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700134 bool m_isListening;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800135 shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800136};
137
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700138inline bool
139TcpChannel::isListening() const
140{
141 return m_isListening;
142}
143
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800144} // namespace nfd
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700145
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800146#endif // NFD_FACE_TCP_CHANNEL_HPP