From 86cced792bd7e16a08b6185187083cc7024ed87d Mon Sep 17 00:00:00 2001 From: Alexey Rybalchenko Date: Thu, 3 May 2018 15:00:32 +0200 Subject: [PATCH] Add resolver for hostname -> ip, use it before bind/connect --- fairmq/FairMQChannel.cxx | 6 ++--- fairmq/FairMQDevice.cxx | 27 ++++++++++++++++---- fairmq/FairMQDevice.h | 4 +-- fairmq/tools/Network.h | 55 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/fairmq/FairMQChannel.cxx b/fairmq/FairMQChannel.cxx index c50332ad..e72e4903 100644 --- a/fairmq/FairMQChannel.cxx +++ b/fairmq/FairMQChannel.cxx @@ -12,12 +12,12 @@ * @author A. Rybalchenko */ -#include -#include // std::move +#include "FairMQChannel.h" #include // join/split -#include "FairMQChannel.h" +#include +#include // std::move using namespace std; diff --git a/fairmq/FairMQDevice.cxx b/fairmq/FairMQDevice.cxx index 50ed5fd0..5443cc56 100644 --- a/fairmq/FairMQDevice.cxx +++ b/fairmq/FairMQDevice.cxx @@ -302,15 +302,32 @@ bool FairMQDevice::AttachChannel(FairMQChannel& ch) address = endpoint.substr(1); } - bool rc = true; + if (address.compare(0, 6, "tcp://") == 0) + { + string addressString = address.substr(6); + auto pos = addressString.find(":"); + string hostPart = addressString.substr(0, pos); + if (!(bind && hostPart == "*")) + { + string portPart = addressString.substr(pos + 1); + string resolvedHost = fair::mq::tools::getIpFromHostname(hostPart); + if (resolvedHost == "") + { + return false; + } + address.assign("tcp://" + resolvedHost + ":" + portPart); + } + } + + bool success = true; // make the connection if (bind) { - rc = BindEndpoint(*ch.fSocket, address); + success = BindEndpoint(*ch.fSocket, address); } else { - rc = ConnectEndpoint(*ch.fSocket, address); + success = ConnectEndpoint(*ch.fSocket, address); } // bind might bind to an address different than requested, @@ -325,9 +342,9 @@ bool FairMQDevice::AttachChannel(FairMQChannel& ch) LOG(debug) << "Attached channel " << ch.fName << " to " << endpoint << (bind ? " (bind) " : " (connect) "); // after the book keeping is done, exit in case of errors - if (!rc) + if (!success) { - return rc; + return success; } } diff --git a/fairmq/FairMQDevice.h b/fairmq/FairMQDevice.h index d4acae7d..6b2bdaae 100644 --- a/fairmq/FairMQDevice.h +++ b/fairmq/FairMQDevice.h @@ -530,8 +530,8 @@ class FairMQDevice : public FairMQStateMachine bool fExternalConfig; const fair::mq::tools::Version fVersion; - float fRate; - size_t fLastTime; + float fRate; ///< Rate limiting for ConditionalRun + size_t fLastTime; ///< Rate limiting for ConditionalRun }; #endif /* FAIRMQDEVICE_H_ */ diff --git a/fairmq/tools/Network.h b/fairmq/tools/Network.h index 4d35f297..9cd7514b 100644 --- a/fairmq/tools/Network.h +++ b/fairmq/tools/Network.h @@ -22,11 +22,13 @@ #include #include // trim +#include #include #include #include #include +#include namespace fair { @@ -128,6 +130,59 @@ inline std::string getDefaultRouteNetworkInterface() return interfaceName; } +inline std::string getIpFromHostname(const std::string& hostname) +{ + try { + boost::asio::io_service ios; + boost::asio::ip::tcp::resolver resolver(ios); + boost::asio::ip::tcp::resolver::query query(hostname, ""); + boost::asio::ip::tcp::resolver::iterator end; + + auto it = std::find_if(resolver.resolve(query), end, [](const boost::asio::ip::tcp::endpoint& ep) { + return ep.address().is_v4(); + }); + + if (it != end) { + std::stringstream ss; + ss << static_cast(*it).address(); + return ss.str(); + } + + LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'"; + + return ""; + } catch (std::exception& e) { + LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what(); + return ""; + } +} + +inline std::string getIpFromHostname(const std::string& hostname, boost::asio::io_service& ios) +{ + try { + boost::asio::ip::tcp::resolver resolver(ios); + boost::asio::ip::tcp::resolver::query query(hostname, ""); + boost::asio::ip::tcp::resolver::iterator end; + + auto it = std::find_if(resolver.resolve(query), end, [](const boost::asio::ip::tcp::endpoint& ep) { + return ep.address().is_v4(); + }); + + if (it != end) { + std::stringstream ss; + ss << static_cast(*it).address(); + return ss.str(); + } + + LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'"; + + return ""; + } catch (std::exception& e) { + LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what(); + return ""; + } +} + } /* namespace tools */ } /* namespace mq */ } /* namespace fair */