blob: 869bf9bc9bc2a1da513e371d7d645c45e6a4f78b [file] [log] [blame]
Alexander Afanasyeva9034b02014-01-26 18:32:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology
9 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080024
25#ifndef NFD_FACE_TCP_CHANNEL_HPP
26#define NFD_FACE_TCP_CHANNEL_HPP
27
Junxiao Shi61e3cc52014-03-03 20:40:28 -070028#include "channel.hpp"
Junxiao Shic041ca32014-02-25 20:01:15 -070029#include <ndn-cpp-dev/util/monotonic_deadline_timer.hpp>
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080030#include "tcp-face.hpp"
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080031
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080032namespace nfd {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080033
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010034namespace tcp {
Junxiao Shi61e3cc52014-03-03 20:40:28 -070035typedef boost::asio::ip::tcp::endpoint Endpoint;
Davide Pesaventobc4dd8c2014-02-14 20:01:01 +010036} // namespace tcp
37
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080038/**
39 * \brief Class implementing TCP-based channel to create faces
40 *
41 * Channel can create faces as a response to incoming TCP
42 * connections (TcpChannel::listen needs to be called for that
43 * to work) or explicitly after using TcpChannel::connect method.
44 */
Junxiao Shi61e3cc52014-03-03 20:40:28 -070045class TcpChannel : public Channel
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080046{
47public:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080048 /**
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080049 * \brief Create TCP channel for the local endpoint
50 *
51 * To enable creation faces upon incoming connections,
52 * one needs to explicitly call TcpChannel::listen method.
53 */
Junxiao Shi61e3cc52014-03-03 20:40:28 -070054 explicit
55 TcpChannel(const tcp::Endpoint& localEndpoint);
56
57 virtual
58 ~TcpChannel();
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080059
60 /**
61 * \brief Enable listening on the local endpoint, accept connections,
62 * and create faces when remote host makes a connection
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080063 * \param onFaceCreated Callback to notify successful creation of the face
64 * \param onAcceptFailed Callback to notify when channel fails (accept call
65 * returns an error)
66 * \param backlog The maximum length of the queue of pending incoming
67 * connections
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080068 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080069 void
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080070 listen(const FaceCreatedCallback& onFaceCreated,
71 const ConnectFailedCallback& onAcceptFailed,
72 int backlog = boost::asio::ip::tcp::acceptor::max_connections);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080073
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080074 /**
75 * \brief Create a face by establishing connection to remote endpoint
76 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080077 void
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080078 connect(const tcp::Endpoint& remoteEndpoint,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080079 const FaceCreatedCallback& onFaceCreated,
80 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070081 const time::seconds& timeout = time::seconds(4));
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080082
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080083 /**
84 * \brief Create a face by establishing connection to the specified
85 * remote host and remote port
86 *
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080087 * This method will never block and will return immediately. All
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080088 * necessary hostname and port resolution and connection will happen
89 * in asynchronous mode.
90 *
91 * If connection cannot be established within specified timeout, it
92 * will be aborted.
93 */
94 void
95 connect(const std::string& remoteHost, const std::string& remotePort,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080096 const FaceCreatedCallback& onFaceCreated,
97 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070098 const time::seconds& timeout = time::seconds(4));
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080099
100 /**
101 * \brief Get number of faces in the channel
102 */
103 size_t
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700104 size() const;
105
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700106 bool
107 isListening() const;
108
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800109private:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800110 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800111 createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev355c0662014-03-20 18:08:17 -0700112 const FaceCreatedCallback& onFaceCreated,
113 bool isOnDemand);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800114
115 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800116 afterFaceFailed(tcp::Endpoint &endpoint);
117
118 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -0800119 handleSuccessfulAccept(const boost::system::error_code& error,
120 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
121 const FaceCreatedCallback& onFaceCreated,
122 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800123
124 void
125 handleSuccessfulConnect(const boost::system::error_code& error,
126 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700127 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800128 const FaceCreatedCallback& onFaceCreated,
129 const ConnectFailedCallback& onConnectFailed);
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700130
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800131 void
132 handleFailedConnect(const boost::system::error_code& error,
133 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700134 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800135 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800136
137 void
Davide Pesavento855bf292014-02-27 03:58:01 +0100138 handleEndpointResolution(const boost::system::error_code& error,
139 boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
140 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700141 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Davide Pesavento855bf292014-02-27 03:58:01 +0100142 const FaceCreatedCallback& onFaceCreated,
143 const ConnectFailedCallback& onConnectFailed,
144 const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800145
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800146private:
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800147 tcp::Endpoint m_localEndpoint;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800148
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800149 typedef std::map< tcp::Endpoint, shared_ptr<Face> > ChannelFaceMap;
Alexander Afanasyev334b7142014-01-28 12:59:39 -0800150 ChannelFaceMap m_channelFaces;
151
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700152 bool m_isListening;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800153 shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800154};
155
Alexander Afanasyev53a6fd32014-03-23 00:00:04 -0700156inline bool
157TcpChannel::isListening() const
158{
159 return m_isListening;
160}
161
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800162} // namespace nfd
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700163
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800164#endif // NFD_FACE_TCP_CHANNEL_HPP