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