in src/TcpAdapterProxy.cpp [313:366]
void tcp_adapter_proxy::tcp_socket_reset(tcp_adapter_context &tac, string service_id, std::function<void()> post_reset_operation)
{
tcp_connection::pointer connection = get_tcp_connection(tac, service_id);
if (!connection->socket_.is_open())
{
BOOST_LOG_SEV(log, debug) << "Ignoring explicit reset because TCP socket is already closed";
return;
}
BOOST_LOG_SEV(log, debug) << "Handling explicit reset by closing TCP for service id: " << service_id;
connection->socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_receive);
std::shared_ptr<bool> web_socket_write_buffer_drain_complete = std::make_shared<bool>(false);
std::shared_ptr<bool> tcp_write_buffer_drain_complete = std::make_shared<bool>(false);
//ignore next tcp read error if a read operation is happening when TCP gets closed
connection->on_tcp_error =
[=](boost::system::error_code const &ec)
{
//We *may* want to confirm that the error code is actually operation canceled or aborted due to TCP close as
//any unexpected errors in this situation perhaps signals something else. But also we may want to ignore all errors
//anyways given we know we are closing the tcp socket to create a new one anyways
BOOST_LOG_SEV(this->log, trace) << "Received expected TCP socket error and ignoring it. TCP socket read loop has been canceled for service id: " << service_id;
};
connection->on_data_message = std::bind(&tcp_adapter_proxy::ignore_message_and_stop, this, std::ref(tac), std::placeholders::_1);
connection->on_control_message = std::bind(&tcp_adapter_proxy::ignore_message_and_stop, this, std::ref(tac), std::placeholders::_1);
connection->on_web_socket_write_buffer_drain_complete =
[=]()
{
BOOST_LOG_SEV(this->log, trace) << "Post-reset web socket drain complete";
*web_socket_write_buffer_drain_complete = true;
if (*tcp_write_buffer_drain_complete)
{
BOOST_LOG_SEV(this->log, trace) << "Both socket drains complete.";
post_reset_operation();
}
};
connection->on_tcp_write_buffer_drain_complete =
[=, &tac]()
{
tcp_connection::pointer connection_to_reset = get_tcp_connection(tac, service_id);
BOOST_LOG_SEV(this->log, trace) << "Post-reset TCP drain complete. Closing TCP socket for service id " << service_id;
BOOST_LOG_SEV(this->log, info) << "Disconnected from: " << connection_to_reset->socket().remote_endpoint();
connection_to_reset->socket_.close();
*tcp_write_buffer_drain_complete = true;
if (*web_socket_write_buffer_drain_complete)
{
BOOST_LOG_SEV(this->log, trace) << "Both socket drains complete. Setting up TCP socket again";
post_reset_operation();
}
};
async_setup_web_socket_write_buffer_drain(tac, service_id);
async_tcp_write_buffer_drain(tac, service_id);
}