From 3d053b7a733576d9dd5f297bfd5a62acb2426067 Mon Sep 17 00:00:00 2001 From: deniskovalchuk Date: Fri, 29 Sep 2023 02:03:23 +0300 Subject: [PATCH] perf: use Boost.Asio endpoints where is possible Get rid of extra address construction from strings. --- include/ftp/detail/control_connection.hpp | 2 +- include/ftp/detail/data_connection.hpp | 2 ++ src/client.cpp | 5 ++++- src/control_connection.cpp | 13 +++---------- src/data_connection.cpp | 21 +++++++++++++++++++++ 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/include/ftp/detail/control_connection.hpp b/include/ftp/detail/control_connection.hpp index 8dcd3aa..d9d8e37 100644 --- a/include/ftp/detail/control_connection.hpp +++ b/include/ftp/detail/control_connection.hpp @@ -48,7 +48,7 @@ class control_connection [[nodiscard]] boost::asio::ip::tcp::endpoint get_local_endpoint() const; - [[nodiscard]] std::string get_remote_ip() const; + [[nodiscard]] boost::asio::ip::tcp::endpoint get_remote_endpoint() const; void send(std::string_view command); diff --git a/include/ftp/detail/data_connection.hpp b/include/ftp/detail/data_connection.hpp index 4716250..50a1078 100644 --- a/include/ftp/detail/data_connection.hpp +++ b/include/ftp/detail/data_connection.hpp @@ -46,6 +46,8 @@ class data_connection void open(std::string_view ip, std::uint16_t port); + void open(const boost::asio::ip::tcp::endpoint & remote_endpoint); + void listen(const boost::asio::ip::tcp::endpoint & endpoint); void accept(); diff --git a/src/client.cpp b/src/client.cpp index 71f0e25..2867752 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -604,8 +604,11 @@ data_connection_ptr client::process_epsv_command(std::string_view command, repli reply.get_status_string()); } + boost::asio::ip::tcp::endpoint remote_endpoint = control_connection_.get_remote_endpoint(); + boost::asio::ip::tcp::endpoint endpoint(remote_endpoint.address(), remote_port); + data_connection_ptr connection = std::make_unique(); - connection->open(control_connection_.get_remote_ip(), remote_port); + connection->open(endpoint); reply = process_command(command, replies); diff --git a/src/control_connection.cpp b/src/control_connection.cpp index f751599..2efc72d 100644 --- a/src/control_connection.cpp +++ b/src/control_connection.cpp @@ -123,7 +123,7 @@ boost::asio::ip::tcp::endpoint control_connection::get_local_endpoint() const return local_endpoint; } -std::string control_connection::get_remote_ip() const +boost::asio::ip::tcp::endpoint control_connection::get_remote_endpoint() const { boost::system::error_code ec; @@ -131,17 +131,10 @@ std::string control_connection::get_remote_ip() const if (ec) { - throw ftp_exception(ec, "Cannot get IP address"); + throw ftp_exception(ec, "Cannot get remote endpoint"); } - std::string ip = remote_endpoint.address().to_string(ec); - - if (ec) - { - throw ftp_exception(ec, "Cannot get IP address"); - } - - return ip; + return remote_endpoint; } reply control_connection::recv() diff --git a/src/data_connection.cpp b/src/data_connection.cpp index 0ada5c9..d5ed907 100644 --- a/src/data_connection.cpp +++ b/src/data_connection.cpp @@ -67,6 +67,27 @@ void data_connection::open(std::string_view ip, std::uint16_t port) } } +void data_connection::open(const boost::asio::ip::tcp::endpoint & remote_endpoint) +{ + boost::system::error_code ec; + + socket_.connect(remote_endpoint, ec); + + if (ec) + { + boost::system::error_code ignored; + + /* If the connect fails, and the socket was automatically opened, + * the socket is not returned to the closed state. + * + * https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/reference/basic_stream_socket/connect/overload2.html + */ + socket_.close(ignored); + + throw ftp_exception(ec, "Cannot open data connection"); + } +} + void data_connection::listen(const boost::asio::ip::tcp::endpoint & endpoint) { boost::system::error_code ec;