diff options
Diffstat (limited to 'contrib/epee/src/net_helper.cpp')
| -rw-r--r-- | contrib/epee/src/net_helper.cpp | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/contrib/epee/src/net_helper.cpp b/contrib/epee/src/net_helper.cpp index 719f1c8e0..de0f1211b 100644 --- a/contrib/epee/src/net_helper.cpp +++ b/contrib/epee/src/net_helper.cpp @@ -4,22 +4,38 @@ namespace epee { namespace net_utils { + namespace + { + struct new_connection + { + boost::promise<boost::asio::ip::tcp::socket> result_; + boost::asio::ip::tcp::socket socket_; + + template<typename T> + explicit new_connection(T&& executor) + : result_(), socket_(std::forward<T>(executor)) + {} + }; + } + boost::unique_future<boost::asio::ip::tcp::socket> direct_connect::operator()(const std::string& addr, const std::string& port, boost::asio::steady_timer& timeout) const { // Get a list of endpoints corresponding to the server name. ////////////////////////////////////////////////////////////////////////// - boost::asio::ip::tcp::resolver resolver(GET_IO_SERVICE(timeout)); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port, boost::asio::ip::tcp::resolver::query::canonical_name); + boost::asio::ip::tcp::resolver resolver(MONERO_GET_EXECUTOR(timeout)); bool try_ipv6 = false; - boost::asio::ip::tcp::resolver::iterator iterator; - boost::asio::ip::tcp::resolver::iterator end; + boost::asio::ip::tcp::resolver::results_type results{}; boost::system::error_code resolve_error; + try { - iterator = resolver.resolve(query, resolve_error); - if(iterator == end) // Documentation states that successful call is guaranteed to be non-empty + results = resolver.resolve( + boost::asio::ip::tcp::v4(), addr, port, boost::asio::ip::tcp::resolver::canonical_name, resolve_error + ); + + if (results.empty()) { // if IPv4 resolution fails, try IPv6. Unintentional outgoing IPv6 connections should only // be possible if for some reason a hostname was given and that hostname fails IPv4 resolution, @@ -37,27 +53,20 @@ namespace net_utils } try_ipv6 = true; } + if (try_ipv6) { - boost::asio::ip::tcp::resolver::query query6(boost::asio::ip::tcp::v6(), addr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - iterator = resolver.resolve(query6); - if (iterator == end) + results = resolver.resolve( + boost::asio::ip::tcp::v6(), addr, port, boost::asio::ip::tcp::resolver::canonical_name + ); + if (results.empty()) throw boost::system::system_error{boost::asio::error::fault, "Failed to resolve " + addr}; } ////////////////////////////////////////////////////////////////////////// - struct new_connection - { - boost::promise<boost::asio::ip::tcp::socket> result_; - boost::asio::ip::tcp::socket socket_; - - explicit new_connection(boost::asio::io_service& io_service) - : result_(), socket_(io_service) - {} - }; - const auto shared = std::make_shared<new_connection>(GET_IO_SERVICE(timeout)); + const auto shared = std::make_shared<new_connection>(MONERO_GET_EXECUTOR(timeout)); timeout.async_wait([shared] (boost::system::error_code error) { if (error != boost::system::errc::operation_canceled && shared && shared->socket_.is_open()) @@ -66,7 +75,7 @@ namespace net_utils shared->socket_.close(); } }); - shared->socket_.async_connect(*iterator, [shared] (boost::system::error_code error) + shared->socket_.async_connect(*results.begin(), [shared] (boost::system::error_code error) { if (shared) { |
