blob: 999f9c9d58cddc17c5808cc7869721071175c84f [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
14namespace tcp {
15typedef boost::asio::ip::tcp::endpoint Endpoint;
16} // namespace tcp
17
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080018namespace nfd {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080019
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 */
35 typedef function<void(const shared_ptr<TcpFace>& 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
55 * \param backlog The maximum length of the queue of pending incoming
56 * connections
57 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080058 void
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080059 listen(const FaceCreatedCallback& onFaceCreated,
60 const ConnectFailedCallback& onAcceptFailed,
61 int backlog = boost::asio::ip::tcp::acceptor::max_connections);
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080062
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080063 /**
64 * \brief Create a face by establishing connection to remote endpoint
65 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080066 void
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080067 connect(const tcp::Endpoint& remoteEndpoint,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080068 const FaceCreatedCallback& onFaceCreated,
69 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080070 const time::Duration& timeout = time::seconds(4));
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080071
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080072 /**
73 * \brief Create a face by establishing connection to the specified
74 * remote host and remote port
75 *
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080076 * This method will never block and will return immediately. All
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080077 * necessary hostname and port resolution and connection will happen
78 * in asynchronous mode.
79 *
80 * If connection cannot be established within specified timeout, it
81 * will be aborted.
82 */
83 void
84 connect(const std::string& remoteHost, const std::string& remotePort,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -080085 const FaceCreatedCallback& onFaceCreated,
86 const ConnectFailedCallback& onConnectFailed,
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080087 const time::Duration& timeout = time::seconds(4));
88
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080089private:
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080090 void
Alexander Afanasyeva16abd22014-01-31 18:12:29 -080091 createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
92 const FaceCreatedCallback& onFaceCreated);
93
94 void
95 handleSuccessfulAccept(const boost::system::error_code& error,
96 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
97 const FaceCreatedCallback& onFaceCreated,
98 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -080099
100 void
101 handleSuccessfulConnect(const boost::system::error_code& error,
102 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800103 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
104 const FaceCreatedCallback& onFaceCreated,
105 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800106
107 void
108 handleFailedConnect(const boost::system::error_code& error,
109 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800110 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
111 const ConnectFailedCallback& onConnectFailed);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800112
113 void
114 handleEndpointResoution(const boost::system::error_code& error,
115 boost::asio::ip::tcp::resolver::iterator remoteEndpoint,
116 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
Alexander Afanasyev855a53c2014-01-27 12:03:00 -0800117 const shared_ptr<boost::asio::monotonic_deadline_timer>& timer,
118 const FaceCreatedCallback& onFaceCreated,
Alexander Afanasyev3958b012014-01-31 15:06:13 -0800119 const ConnectFailedCallback& onConnectFailed,
120 const shared_ptr<boost::asio::ip::tcp::resolver>& resolver);
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800121
122private:
123 boost::asio::io_service& m_ioService;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800124 tcp::Endpoint m_localEndpoint;
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800125
Alexander Afanasyev334b7142014-01-28 12:59:39 -0800126 typedef std::map< tcp::Endpoint, shared_ptr<TcpFace> > ChannelFaceMap;
127 ChannelFaceMap m_channelFaces;
128
Alexander Afanasyev8ad71ba2014-01-27 00:07:14 -0800129 bool isListening;
130 shared_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800131};
132
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800133} // namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800134
135#endif // NFD_FACE_TCP_CHANNEL_HPP