Mercurial > irccd
changeset 667:133353284280
Irccd: some transport cleanups
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 06 Apr 2018 19:26:13 +0200 |
parents | c99780476eb7 |
children | 8a79b5c0ddc7 |
files | libirccd/irccd/daemon/basic_transport_server.hpp libirccd/irccd/daemon/tls_transport_server.cpp libirccd/irccd/daemon/tls_transport_server.hpp libirccd/irccd/daemon/transport_server.cpp libirccd/irccd/daemon/transport_server.hpp |
diffstat | 5 files changed, 136 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/libirccd/irccd/daemon/basic_transport_server.hpp Fri Apr 06 13:44:20 2018 +0200 +++ b/libirccd/irccd/daemon/basic_transport_server.hpp Fri Apr 06 19:26:13 2018 +0200 @@ -60,7 +60,7 @@ /** * \copydoc transport_server::accept */ - void do_accept(accept_t handler) override; + void do_accept(accept_handler handler) override; public: /** @@ -82,7 +82,7 @@ } template <typename Protocol> -void basic_transport_server<Protocol>::do_accept(accept_t handler) +void basic_transport_server<Protocol>::do_accept(accept_handler handler) { auto client = std::make_shared<basic_transport_client<socket_t>>(*this, acceptor_.get_io_service());
--- a/libirccd/irccd/daemon/tls_transport_server.cpp Fri Apr 06 13:44:20 2018 +0200 +++ b/libirccd/irccd/daemon/tls_transport_server.cpp Fri Apr 06 19:26:13 2018 +0200 @@ -22,7 +22,7 @@ namespace irccd { -void tls_transport_server::do_handshake(std::shared_ptr<client_t> client, accept_t handler) +void tls_transport_server::do_handshake(std::shared_ptr<client_t> client, accept_handler handler) { using boost::asio::ssl::stream_base; @@ -37,7 +37,7 @@ { } -void tls_transport_server::do_accept(accept_t handler) +void tls_transport_server::do_accept(accept_handler handler) { auto client = std::make_shared<client_t>(*this, acceptor_.get_io_service(), context_);
--- a/libirccd/irccd/daemon/tls_transport_server.hpp Fri Apr 06 13:44:20 2018 +0200 +++ b/libirccd/irccd/daemon/tls_transport_server.hpp Fri Apr 06 19:26:13 2018 +0200 @@ -44,7 +44,7 @@ context_t context_; - void do_handshake(std::shared_ptr<client_t>, accept_t); + void do_handshake(std::shared_ptr<client_t>, accept_handler); protected: /** @@ -53,7 +53,7 @@ * This function does the same as tcp_transport_server::do_accept but it * also perform a SSL handshake after a successful accept operation. */ - void do_accept(accept_t handler) override; + void do_accept(accept_handler handler) override; public: /**
--- a/libirccd/irccd/daemon/transport_server.cpp Fri Apr 06 13:44:20 2018 +0200 +++ b/libirccd/irccd/daemon/transport_server.cpp Fri Apr 06 19:26:13 2018 +0200 @@ -28,7 +28,7 @@ namespace irccd { -void transport_server::do_auth(std::shared_ptr<transport_client> client, accept_t handler) +void transport_server::do_auth(std::shared_ptr<transport_client> client, accept_handler handler) { assert(client); assert(handler); @@ -59,7 +59,7 @@ }); } -void transport_server::do_greetings(std::shared_ptr<transport_client> client, accept_t handler) +void transport_server::do_greetings(std::shared_ptr<transport_client> client, accept_handler handler) { assert(client); assert(handler); @@ -89,7 +89,7 @@ }); } -void transport_server::accept(accept_t handler) +void transport_server::accept(accept_handler handler) { assert(handler);
--- a/libirccd/irccd/daemon/transport_server.hpp Fri Apr 06 13:44:20 2018 +0200 +++ b/libirccd/irccd/daemon/transport_server.hpp Fri Apr 06 19:26:13 2018 +0200 @@ -36,27 +36,114 @@ /** * \brief Abstract transport server class. * - * This class create asynchronous operation to accept new clients. + * # Synopsis + * + * The transport_server class is an abstract interface that waits for clients to + * connect and store them locally. It does not know the underlying + * implementation so derived classes may be implemented in any shape of form. + * + * As only constraint the implementation must provide an asynchronous operation + * to avoid blocking the daemon. + * + * The derived class only have to implement do_accept function which is only + * responsible of getting a client ready for I/O (receiving and sending), the + * transport_server does authentication and greeting by itself. + * + * # Accept procedure + * + * The connection procedure looks like this: + * + * ``` + * o (transport_server::accept is called) + * | + * v [error] + * +-----------------------------+ +---------------------+ + * | asynchronous accept process |----------------->| client is discarded | + * +-----------------------------+ +---------------------+ + * | ^ + * | [success] | + * v | + * +-----------------------------------------+ [error while sending] | + * | sending irccd information to the client |------------------------>+ + * +-----------------------------------------+ | + * | | | + * | | [authentication required] | + * | | | + * | v [error or invalid password] | + * | +-------------------------+ +------------+ | + * | | wait for authentication |-------->| send error |-------->+ + * | +-------------------------+ +------------+ ^ + * | | | + * | | [correct password] | + * v v | + * +---------------------------------------+ [incorrect] | + * | client is added to the list and ready ]-------------------------- + + * +---------------------------------------+ + * ``` + * + * # I/O procedures + * + * Each client has a reference to its parent, since operations are asynchronous, + * they maintain their lifetime by themselve to update the parent list on + * errors. + * + * See the following diagram: + * + * ``` + * o (transport_client::recv or send is called) o + * | | + * | [no operations in queue] | [operation in progress] + * | v + * | +---------------+ + * | | push in queue | + * | +---------------+ + * | + * | + * | [pending operations in queue] + * |<-----------------------------------------------+ + * | ^ + * | | + * v [success] | + * +-------------------------------+ +-------------------+ + * | asynchronous operation starts |---------->| handler is called | + * +-------------------------------+ +-------------------+ + * | + * v [error] + * +--------------------------------------+ + * | handler is called with an error code | + * +--------------------------------------+ + * | + * v + * +----------------------------------+ + * | client delete itself from parent | + * +----------------------------------+ + * ``` + * + * \see transport_client + * \see transport_service */ class transport_server { -protected: +public: /** * Set of clients. */ - using client_set_t = std::unordered_set<std::shared_ptr<transport_client>>; + using client_set = std::unordered_set<std::shared_ptr<transport_client>>; /** * Callback when a new client should be accepted. */ - using accept_t = std::function<void (boost::system::error_code, std::shared_ptr<transport_client>)>; + using accept_handler = std::function<void ( + boost::system::error_code, + std::shared_ptr<transport_client> + )>; private: boost::asio::io_service& service_; - client_set_t clients_; + client_set clients_; std::string password_; - void do_auth(std::shared_ptr<transport_client>, accept_t); - void do_greetings(std::shared_ptr<transport_client>, accept_t); + void do_auth(std::shared_ptr<transport_client>, accept_handler); + void do_greetings(std::shared_ptr<transport_client>, accept_handler); protected: /** @@ -66,7 +153,7 @@ * \pre handler must not be null * \param handler the handler function */ - virtual void do_accept(accept_t handler) = 0; + virtual void do_accept(accept_handler handler) = 0; public: /** @@ -83,20 +170,31 @@ virtual ~transport_server() noexcept = default; /** - * Wrapper that automatically add the new client into the list. + * Accept a new client into the transport server. * - * If handler is not null it is called on error or on successful accept - * operation. + * Also perform greetings and authentication under the hood. On success, the + * client is added into the server and is ready to use. * + * \pre accept != nullptr * \param handler the handler */ - void accept(accept_t handler); + void accept(accept_handler handler); + /** + * Get the io service. + * + * \return the service + */ inline const boost::asio::io_service& get_service() const noexcept { return service_; } + /** + * Overloaded function. + * + * \return the service + */ inline boost::asio::io_service& get_service() noexcept { return service_; @@ -107,7 +205,7 @@ * * \return the clients */ - inline const client_set_t& get_clients() const noexcept + inline const client_set& get_clients() const noexcept { return clients_; } @@ -117,7 +215,7 @@ * * \return the clients */ - inline client_set_t& get_clients() noexcept + inline client_set& get_clients() noexcept { return clients_; } @@ -143,9 +241,18 @@ } }; +/** + * \brief Transport error. + */ class transport_error : public boost::system::system_error { public: + /** + * \brief Transport related errors. + */ enum error { + //!< No error. + no_error = 0, + //!< Authentication is required. auth_required, @@ -180,7 +287,12 @@ not_supported }; - transport_error(error err) noexcept; + /** + * Constructor. + * + * \param code the error code + */ + transport_error(error code) noexcept; }; /**