From 61d2c8c1f57b4750b5ff33508c098ac3813bd489 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 10 Apr 2020 11:29:46 +0200 Subject: [PATCH] add built-in time-out to async_shutdown --- src/socket_type.cpp | 46 ++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/socket_type.cpp b/src/socket_type.cpp index 3078f94cf..f65b1fd86 100644 --- a/src/socket_type.cpp +++ b/src/socket_type.cpp @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/aux_/socket_type.hpp" #include "libtorrent/aux_/openssl.hpp" +#include "libtorrent/deadline_timer.hpp" #ifdef TORRENT_USE_OPENSSL #include @@ -139,18 +140,32 @@ namespace aux { } #ifdef TORRENT_USE_OPENSSL - namespace { - void nop(std::shared_ptr) {} - - void on_close_socket(socket_type* s, std::shared_ptr) + struct socket_closer { - COMPLETE_ASYNC("on_close_socket"); - error_code ec; - s->close(ec); - } + socket_closer(io_service& e + , std::shared_ptr holder + , socket_type* s) + : h(std::move(holder)) + , t(std::make_shared(e)) + , sock(s) + { + t->expires_after(seconds(3)); + t->async_wait(*this); + } - } // anonymous namespace + void operator()(error_code const&) + { + COMPLETE_ASYNC("on_close_socket"); + error_code ec; + sock->close(ec); + t->cancel(); + } + + std::shared_ptr h; + std::shared_ptr t; + socket_type* sock; + }; #endif // the second argument is a shared pointer to an object that @@ -167,16 +182,13 @@ namespace aux { #define MAYBE_ASIO_DEBUGGING #endif - static char const buffer[] = ""; - // chasing the async_shutdown by a write is a trick to close the socket as - // soon as we've sent the close_notify, without having to wait to receive a - // response from the other end - // https://stackoverflow.com/questions/32046034/what-is-the-proper-way-to-securely-disconnect-an-asio-ssl-socket - +// we call ASIO_DEBUGGING twice, because the socket_closer callback will be +// called twice #define CASE(t) case socket_type_int_impl>::value: \ MAYBE_ASIO_DEBUGGING \ - s.get>()->async_shutdown(std::bind(&nop, holder)); \ - s.get>()->async_write_some(boost::asio::buffer(buffer), std::bind(&on_close_socket, &s, holder)); \ + MAYBE_ASIO_DEBUGGING \ + s.get>()->async_shutdown( \ + socket_closer(s.get_io_service(), std::move(holder), &s)); \ break; switch (s.type())