shutdown( ) blocks forever
I have a server that accepts ssl connections on port 443. I am using the boost libraries for the server implementation. Below is the code snippet: ssl_socket socket_; { // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). boost::asio::ip::tcp::resolver resolver(io_service_); boost::asio::ip::tcp::resolver::query query(address, port); boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); acceptor_.open(endpoint.protocol()); acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); acceptor_.bind(endpoint); acceptor_.listen(1000); start_accept(); } void server::start_accept() { new_connection_.reset( new connection(io_service_, connection_manager_, request_handler_, context_)); acceptor_.async_accept(new_connection_->socket(), boost::bind(&server::handle_accept, this, boost::asio::placeholders::error)); } void server::handle_accept(const boost::system::error_code& e) { // Check whether the server was stopped by a signal before this completion // handler had a chance to run. if (!acceptor_.is_open()) { return; } else { start(); } start_accept(); } void server::start() { socket_.async_handshake(boost::asio::ssl::stream_base::server, boost::bind(&connection::handle_handshake, this, boost::asio::placeholders::error)); if (boost::asio::placeholders::error) { // printf("Error is there. Check it\n"); } } void connection::handle_handshake(const boost::system::error_code& error) { if (!error) { DEBUG("async read some"); socket_.async_read_some(boost::asio::buffer(buffer_), boost::bind(&connection::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { std::cout << "Error number: " << error.value(); std::cout << " Error message: " << error.message(); std::cout << " Error category: " << error.category().name() << std::endl; delete this; } } When I initiate multiple clients to connect to the server, most of the time the connection succeeds i.e TCP handshake followed by SSL handshake succeeds and I am able to do data transfer. However, there are times when the TCP handshake succeeds (as seen by wireshark) but the SSL request isn't responded to by my server. I am able to see the SSL handshake request coming from the client onto my server, but the server doesn't respond, neither is my handle_accept() function gets called. When I check the output of netstat, I see a lot of data pending in the Recv-Q. Below is the output of netstat -atn command on the server during one such scenario: Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 15 0 0.0.0.0:443 0.0.0.0:* LISTEN tcp 0 213 10.110.112.1:443 10.110.112.2:52363 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52624 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52581 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52646 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52749 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52824 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52805 ESTABLISHED tcp 180 0 10.110.112.1:443 10.110.112.2:52645 ESTABLISHED tcp 0 471 10.110.112.1:443 10.110.112.2:52362 ESTABLISHED tcp 1 0 10.110.112.1:443 10.110.112.3:39129 CLOSE_WAIT tcp 183 0 10.110.112.1:443 10.110.112.3:39130 CLOSE_WAIT tcp 180 0 10.110.112.1:443 10.110.112.2:52595 ESTABLISHED tcp 183 0 10.110.112.1:443 10.110.112.3:39131 CLOSE_WAIT Upon further debugging, I see that the call to ssl socket member function shutdown() blocks sometimes forever and sometimes for at least 5 - 10 minutes due to which no further data is taken in and the recv-q indicates pending bytes. This is how my write handler is. Any help on where I am going wrong would be greatly appreciated: void connection::handle_write(const boost::system::error_code& e) { if (!e) { boost::system::error_code ec; socket_.shutdown(ec); //Code blocks here indefinitely } } Any reasons why the socket_.shutdown( ) blocks. How could I specify a timeout such that the shutdown( ) returns back after some time? Any other way of handling this? ( I know there is async_shutdown( ) but I prefer using shutdown( ) blocking handler) Any help would be greatly appreciated. Regards, Fariya
On Wed, Dec 30, 2020 at 6:27 AM Fariya F via Boost-users
I see that the call to ssl socket member function shutdown() blocks sometimes forever
You are mixing synchronous and asynchronous operations on the same socket, which is generally disallowed. Use async_shutdown instead, and also use a timer to close the socket after some time period (say, 30 seconds). Regards
Hi,
Thanks. A couple of more questions:
a) Could you help me with a sample code which handles shutdown gracefully
(async shutdown + timer) for iterative servers?
b) I have also seen issues where the code hangs just like the shutdown()
when I invoke socket_.lowest_layer().cancel(). Is this expected?
c) Is this what is the code to be put in the async shutdown handler?
socket_.lowest_layer().close(ignored_ec);
Regards,
Fariya
On Wed, Dec 30, 2020 at 8:04 PM Vinnie Falco
On Wed, Dec 30, 2020 at 6:27 AM Fariya F via Boost-users
wrote: I see that the call to ssl socket member function shutdown() blocks sometimes forever
You are mixing synchronous and asynchronous operations on the same socket, which is generally disallowed. Use async_shutdown instead, and also use a timer to close the socket after some time period (say, 30 seconds).
Regards
On Wed, 30 Dec 2020 at 15:47, Fariya F via Boost-users < boost-users@lists.boost.org> wrote:
Hi,
Thanks. A couple of more questions: a) Could you help me with a sample code which handles shutdown gracefully (async shutdown + timer) for iterative servers? b) I have also seen issues where the code hangs just like the shutdown() when I invoke socket_.lowest_layer().cancel(). Is this expected? c) Is this what is the code to be put in the async shutdown handler? socket_.lowest_layer().close(ignored_ec);
a) Funnily enough I answered a similar question today on timed asio udp reception, but it's the same principle. That answer is here: https://godbolt.org/z/x7hsd5 In this case you'd substitute the async_receive with stream.async_shutdown and you'd cancel() the lowest_layer b) It depends what was pending on the lowest layer. In general I would not expect to see anything hang in an asynchronous system. Could it be that you are mixing sync and async in more than one place? c) yes, that should do it.
Regards, Fariya
On Wed, Dec 30, 2020 at 8:04 PM Vinnie Falco
wrote: On Wed, Dec 30, 2020 at 6:27 AM Fariya F via Boost-users
wrote: I see that the call to ssl socket member function shutdown() blocks sometimes forever
You are mixing synchronous and asynchronous operations on the same socket, which is generally disallowed. Use async_shutdown instead, and also use a timer to close the socket after some time period (say, 30 seconds).
Regards
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Richard Hodges hodges.r@gmail.com office: +442032898513 home: +376841522 mobile: +376380212
participants (3)
-
Fariya F
-
Richard Hodges
-
Vinnie Falco