From aeea524ac960ba18fe3a8ef483a01e39139803d9 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 18 Jan 2019 09:42:44 -0800 Subject: [PATCH] ircd::net: Improve listener interface w/ instance reference in callbacks. --- include/ircd/client.h | 2 +- include/ircd/net/acceptor.h | 7 +++-- include/ircd/net/listener.h | 6 ++-- ircd/client.cc | 3 +- ircd/net.cc | 60 +++++++++++++++++++++++-------------- modules/s_listen.cc | 3 +- 6 files changed, 51 insertions(+), 30 deletions(-) diff --git a/include/ircd/client.h b/include/ircd/client.h index ad6c497fc..16e0e378d 100644 --- a/include/ircd/client.h +++ b/include/ircd/client.h @@ -38,7 +38,7 @@ struct ircd::client static ctx::dock dock; static uint64_t ctr; // monotonic - static void create(const std::shared_ptr &); + static void create(net::listener &, const std::shared_ptr &); static size_t count(const net::ipport &remote); // cmp is by IP only, not port static void terminate_all(); static void interrupt_all(); diff --git a/include/ircd/net/acceptor.h b/include/ircd/net/acceptor.h index 9f56cc2f4..79dcd42a9 100644 --- a/include/ircd/net/acceptor.h +++ b/include/ircd/net/acceptor.h @@ -24,6 +24,7 @@ struct ircd::net::listener::acceptor static log::log log; static conf::item timeout; + net::listener *listener; std::string name; std::string opts; size_t backlog; @@ -35,6 +36,7 @@ struct ircd::net::listener::acceptor size_t accepting {0}; size_t handshaking {0}; bool interrupting {false}; + bool handle_set {false}; ctx::dock joining; void configure(const json::object &opts); @@ -48,13 +50,14 @@ struct ircd::net::listener::acceptor void accept(const error_code &ec, std::shared_ptr, std::weak_ptr) noexcept; // Accept next - void next(); + bool set_handle(); // Acceptor shutdown bool interrupt() noexcept; void join() noexcept; - acceptor(const string_view &name, + acceptor(net::listener &, + const string_view &name, const json::object &opts, listener::callback, listener::proffer); diff --git a/include/ircd/net/listener.h b/include/ircd/net/listener.h index b8d52a622..ceb9f8f57 100644 --- a/include/ircd/net/listener.h +++ b/include/ircd/net/listener.h @@ -22,8 +22,8 @@ namespace ircd::net struct ircd::net::listener { struct acceptor; - using callback = std::function &)>; - using proffer = std::function; + using callback = std::function &)>; + using proffer = std::function; IRCD_EXCEPTION(net::error, error) @@ -34,6 +34,8 @@ struct ircd::net::listener explicit operator json::object() const; string_view name() const; + bool start(); + listener(const string_view &name, const json::object &options, callback, diff --git a/ircd/client.cc b/ircd/client.cc index d5f849c1c..7d19ce388 100644 --- a/ircd/client.cc +++ b/ircd/client.cc @@ -254,7 +254,8 @@ ircd::client::terminate_all() } void -ircd::client::create(const std::shared_ptr &sock) +ircd::client::create(net::listener &, + const std::shared_ptr &sock) { const auto client { diff --git a/ircd/net.cc b/ircd/net.cc index 0d689b2b8..d5666eb36 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -952,12 +952,9 @@ ircd::net::listener::listener(const string_view &name, proffer pcb) :acceptor { - std::make_shared(name, opts, std::move(cb), std::move(pcb)) + std::make_shared(*this, name, opts, std::move(cb), std::move(pcb)) } { - // Starts the first asynchronous accept. This has to be done out here after - // the acceptor's shared object is constructed. - acceptor->next(); } /// Cancels all pending accepts and handshakes and waits (yields ircd::ctx) @@ -970,6 +967,14 @@ noexcept acceptor->join(); } +bool +ircd::net::listener::start() +{ + return acceptor && !acceptor->handle_set? + acceptor->set_handle(): + false; +} + ircd::string_view ircd::net::listener::name() const @@ -1088,12 +1093,17 @@ ircd::net::operator<<(std::ostream &s, const struct listener::acceptor &a) // listener::acceptor::acceptor // -ircd::net::listener::acceptor::acceptor(const string_view &name, +ircd::net::listener::acceptor::acceptor(net::listener &listener, + const string_view &name, const json::object &opts, listener::callback cb, listener::proffer pcb) try -:name +:listener +{ + &listener +} +,name { name } @@ -1223,24 +1233,27 @@ catch(const boost::system::system_error &e) /// Sets the next asynchronous handler to start the next accept sequence. /// Each call to next() sets one handler which handles the connect for one /// socket. After the connect, an asynchronous SSL handshake handler is set -/// for the socket, and next() is called again to setup for the next socket -/// too. -void -ircd::net::listener::acceptor::next() +/// for the socket. +bool +ircd::net::listener::acceptor::set_handle() try { - auto sock(std::make_shared(ssl)); -/* - log::debug + assert(!handle_set); + handle_set = true; + const unwind::exceptional unset{[this] { - log, "%s: socket(%p) is the next socket to accept", - string(logheadbuf, *this), - sock.get() + handle_set = false; + }}; + + auto sock + { + std::make_shared(ssl) }; -*/ + ++accepting; ip::tcp::socket &sd(*sock); a.async_accept(sd, std::bind(&acceptor::accept, this, ph::_1, sock, weak_from(*this))); + return true; } catch(const std::exception &e) { @@ -1262,8 +1275,12 @@ noexcept try if(unlikely(a.expired())) return; - --accepting; assert(bool(sock)); + assert(handle_set); + assert(accepting > 0); + + handle_set = false; + --accepting; log::debug { log, "%s: accepted(%zu) %s %s", @@ -1278,7 +1295,7 @@ noexcept try // Call the proffer-callback if available. This allows the application // to check whether to allow or deny this remote before the handshake. - if(pcb && !pcb(remote_ipport(*sock))) + if(pcb && !pcb(*listener, remote_ipport(*sock))) { net::close(*sock, dc::RST, close_ignore); return; @@ -1362,10 +1379,7 @@ ircd::net::listener::acceptor::check_accept_error(const error_code &ec, throw ctx::interrupted(); if(likely(!ec)) - { - this->next(); return true; - } if(system_category(ec)) switch(ec.value()) { @@ -1401,7 +1415,7 @@ noexcept try check_handshake_error(ec, *sock); sock->cancel_timeout(); assert(bool(cb)); - cb(sock); + cb(*listener, sock); } catch(const ctx::interrupted &e) { diff --git a/modules/s_listen.cc b/modules/s_listen.cc index d8dac68af..92fd3370e 100644 --- a/modules/s_listen.cc +++ b/modules/s_listen.cc @@ -159,7 +159,8 @@ load_listener(const m::event &event) } static bool -_listener_proffer(const net::ipport &ipport) +_listener_proffer(net::listener &, + const net::ipport &ipport) { if(unlikely(ircd::run::level != ircd::run::level::RUN)) {