blob: 3c56cb14add75ee50eb956a383382ad0779b0efc [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 Afanasyeva9034b02014-01-26 18:32:02 -080088private:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080089 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -080090 createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev355c0662014-03-20 18:08:17 -070091 const FaceCreatedCallback& onFaceCreated,
92 bool isOnDemand);
Alexander Afanasyeva16abd22014-01-31 18:12:29 -080093
94 void
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -080095 afterFaceFailed(tcp::Endpoint &endpoint);
96
97 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -080098 handleSuccessfulAccept(const boost::system::error_code& error,
99 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
100 const FaceCreatedCallback& onFaceCreated,
101 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800102
103 void
104 handleSuccessfulConnect(const boost::system::error_code& error,
105 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700106 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800107 const FaceCreatedCallback& onFaceCreated,
108 const ConnectFailedCallback& onConnectFailed);
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700109
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800110 void
111 handleFailedConnect(const boost::system::error_code& error,
112 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700113 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800114 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800115
116 void
Davide Pesavento855bf292014-02-27 03:58:01 +0100117 handleEndpointResolution(const boost::system::error_code& error,
118 boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
119 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700120 const shared_ptr<ndn::monotonic_deadline_timer>& timer,
Davide Pesavento855bf292014-02-27 03:58:01 +0100121 const FaceCreatedCallback& onFaceCreated,
122 const ConnectFailedCallback& onConnectFailed,
123 const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
Alexander Afanasyeva0a10fb2014-02-13 19:56:15 -0800124
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800125private:
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800126 tcp::Endpoint m_localEndpoint;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800127
Alexander Afanasyevbd220a02014-02-20 00:29:56 -0800128 typedef std::map< tcp::Endpoint, shared_ptr<Face> > ChannelFaceMap;
Alexander Afanasyev334b7142014-01-28 12:59:39 -0800129 ChannelFaceMap m_channelFaces;
130
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800131 bool isListening;
132 shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800133};
134
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800135} // namespace nfd
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700136
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800137#endif // NFD_FACE_TCP_CHANNEL_HPP