Skip to content

Commit

Permalink
core: perform a proper shutdown for ssl connections
Browse files Browse the repository at this point in the history
  • Loading branch information
deniskovalchuk committed Apr 15, 2024
1 parent 58dcf20 commit af293f3
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 28 deletions.
2 changes: 2 additions & 0 deletions include/ftp/detail/socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class socket : public socket_base

void ssl_handshake(boost::asio::ssl::stream_base::handshake_type type, boost::system::error_code & ec) override;

void ssl_shutdown(boost::system::error_code & ec) override;

std::size_t write(const char *buf, std::size_t size, boost::system::error_code & ec) override;

std::size_t write(std::string_view buf, boost::system::error_code & ec) override;
Expand Down
2 changes: 2 additions & 0 deletions include/ftp/detail/socket_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class socket_base

virtual void ssl_handshake(boost::asio::ssl::stream_base::handshake_type type, boost::system::error_code & ec) = 0;

virtual void ssl_shutdown(boost::system::error_code & ec) = 0;

virtual std::size_t write(const char *buf, std::size_t size, boost::system::error_code & ec) = 0;

virtual std::size_t write(std::string_view buf, boost::system::error_code & ec) = 0;
Expand Down
2 changes: 2 additions & 0 deletions include/ftp/detail/ssl_socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class ssl_socket : public socket_base

void ssl_handshake(boost::asio::ssl::stream_base::handshake_type type, boost::system::error_code & ec) override;

void ssl_shutdown(boost::system::error_code & ec) override;

std::size_t write(const char *buf, std::size_t size, boost::system::error_code & ec) override;

std::size_t write(std::string_view buf, boost::system::error_code & ec) override;
Expand Down
16 changes: 9 additions & 7 deletions src/control_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,9 @@ void control_connection::ssl_handshake()

void control_connection::ssl_shutdown()
{
if (socket_->has_ssl_support())
{
return;
}

boost::system::error_code ec;

socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
socket_->ssl_shutdown(ec);

if (ec)
{
Expand Down Expand Up @@ -266,7 +261,14 @@ void control_connection::disconnect()
{
boost::system::error_code ec;

socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
if (socket_->has_ssl_support())
{
socket_->ssl_shutdown(ec);
}
else
{
socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
}

if (ec == boost::asio::error::not_connected)
{
Expand Down
40 changes: 22 additions & 18 deletions src/data_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,27 +247,31 @@ void data_connection::disconnect(bool graceful)
{
boost::system::error_code ec;

if (graceful)
if (socket_->has_ssl_support())
{
socket_->ssl_shutdown(ec);
}
else if (graceful)
{
socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
}

if (ec == boost::asio::error::not_connected)
{
/* Ignore 'not_connected' error. We could get ENOTCONN if a server side
* has already closed the data connection. This suits us, just close
* the socket.
*/
}
else if (ec == boost::asio::error::eof)
{
/* Rationale:
* http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
*/
}
else if (ec)
{
throw ftp_exception(ec, "Cannot close data connection");
}
if (ec == boost::asio::error::not_connected)
{
/* Ignore 'not_connected' error. We could get ENOTCONN if a server side
* has already closed the data connection. This suits us, just close
* the socket.
*/
}
else if (ec == boost::asio::error::eof)
{
/* Rationale:
* http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
*/
}
else if (ec)
{
throw ftp_exception(ec, "Cannot close data connection");
}

socket_->close(ec);
Expand Down
7 changes: 6 additions & 1 deletion src/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ bool socket::has_ssl_support() const

void socket::ssl_handshake(boost::asio::ssl::stream_base::handshake_type type, boost::system::error_code & ec)
{
/* Handshake makes sense only for SSL-sockets. */
/* Make sense only for SSL-sockets. */
}

void socket::ssl_shutdown(boost::system::error_code & ec)
{
/* Make sense only for SSL-sockets. */
}

std::size_t socket::write(const char *buf, std::size_t size, boost::system::error_code & ec)
Expand Down
8 changes: 6 additions & 2 deletions src/ssl_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ void ssl_socket::ssl_handshake(boost::asio::ssl::stream_base::handshake_type typ
socket_.handshake(type, ec);
}

void ssl_socket::ssl_shutdown(boost::system::error_code & ec)
{
socket_.shutdown(ec);
}

std::size_t ssl_socket::write(const char *buf, std::size_t size, boost::system::error_code & ec)
{
return socket_base::write(socket_, buf, size, ec);
Expand All @@ -79,8 +84,7 @@ std::size_t ssl_socket::read_line(std::string & buf, std::size_t max_size, boost

void ssl_socket::shutdown(boost::asio::ip::tcp::socket::shutdown_type type, boost::system::error_code & ec)
{
/* Perform SSL shutdown, ignore the 'type' param. */
socket_.shutdown(ec);
socket_.lowest_layer().shutdown(type, ec);
}

void ssl_socket::close(boost::system::error_code & ec)
Expand Down

0 comments on commit af293f3

Please sign in to comment.