Refactor FairMQTools

* Split header, add common header
  * Transform to canonical namespace
  * Deprecate old header
  * Adapt to new Tools.h
This commit is contained in:
Dennis Klein
2017-05-18 16:53:02 +02:00
committed by Mohammad Al-Turany
parent 9215c81362
commit d2c78479f0
7 changed files with 210 additions and 126 deletions

32
fairmq/tools/CppSTL.h Normal file
View File

@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_TOOLS_CPPSTL_H
#define FAIR_MQ_TOOLS_CPPSTL_H
#include <memory>
namespace fair
{
namespace mq
{
namespace tools
{
// make_unique implementation, until C++14 is default
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
} /* namespace tools */
} /* namespace mq */
} /* namespace fair */
#endif /* FAIR_MQ_TOOLS_CPPSTL_H */

View File

@@ -1,129 +1,21 @@
#ifndef FAIRMQTOOLS_H_
#define FAIRMQTOOLS_H_
#ifndef _GNU_SOURCE
#define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST
#endif
#warning "This header file is deprecated. Include <fairmq/Tools.h> instead. Note, that the namespace FairMQ::tools has been changed to fair::mq::tools in the new header."
#include "FairMQLogger.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <boost/algorithm/string.hpp> // trim
#include <map>
#include <string>
#include <iostream>
#include <array>
#include <fairmq/tools/CppSTL.h>
#include <fairmq/tools/Network.h>
namespace FairMQ
{
namespace tools
{
// make_unique implementation, until C++14 is default
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
using fair::mq::tools::make_unique;
// returns a map with network interface names as keys and their IP addresses as values
int getHostIPs(std::map<std::string, std::string>& addressMap)
{
struct ifaddrs *ifaddr, *ifa;
int s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
return -1;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
if (ifa->ifa_addr->sa_family == AF_INET)
{
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0)
{
std::cout << "getnameinfo() failed: " << gai_strerror(s) << std::endl;
return -1;
}
addressMap.insert(std::pair<std::string, std::string>(ifa->ifa_name, host));
}
}
freeifaddrs(ifaddr);
return 0;
}
// get IP address of a given interface name
std::string getInterfaceIP(std::string interface)
{
std::map<std::string, std::string> IPs;
getHostIPs(IPs);
if (IPs.count(interface))
{
return IPs[interface];
}
else
{
LOG(ERROR) << "Could not find provided network interface: \"" << interface << "\"!, exiting.";
return "";
}
}
// get name of the default route interface
std::string getDefaultRouteNetworkInterface()
{
std::array<char, 128> buffer;
std::string interfaceName;
#ifdef __APPLE__ // MacOS
std::unique_ptr<FILE, decltype(pclose) *> file(popen("route -n get default | grep interface | cut -d \":\" -f 2", "r"), pclose);
#else // Linux
std::unique_ptr<FILE, decltype(pclose) *> file(popen("ip route | grep default | cut -d \" \" -f 5", "r"), pclose);
#endif
if (!file)
{
LOG(ERROR) << "Could not detect default route network interface name - popen() failed!";
return "";
}
while (!feof(file.get()))
{
if (fgets(buffer.data(), 128, file.get()) != NULL)
{
interfaceName += buffer.data();
}
}
boost::algorithm::trim(interfaceName);
if (interfaceName == "")
{
LOG(ERROR) << "Could not detect default route network interface name";
}
else
{
LOG(DEBUG) << "Detected network interface name for the default route: " << interfaceName;
}
return interfaceName;
}
using fair::mq::tools::getHostIPs;
using fair::mq::tools::getInterfaceIP;
using fair::mq::tools::getDefaultRouteNetworkInterface;
} // namespace tools
} // namespace FairMQ

135
fairmq/tools/Network.h Normal file
View File

@@ -0,0 +1,135 @@
/********************************************************************************
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_TOOLS_NETWORK_H
#define FAIR_MQ_TOOLS_NETWORK_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST
#endif
#include "FairMQLogger.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <boost/algorithm/string.hpp> // trim
#include <map>
#include <string>
#include <iostream>
#include <array>
namespace fair
{
namespace mq
{
namespace tools
{
// returns a map with network interface names as keys and their IP addresses as values
int getHostIPs(std::map<std::string, std::string>& addressMap)
{
struct ifaddrs *ifaddr, *ifa;
int s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
return -1;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
if (ifa->ifa_addr->sa_family == AF_INET)
{
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0)
{
std::cout << "getnameinfo() failed: " << gai_strerror(s) << std::endl;
return -1;
}
addressMap.insert(std::pair<std::string, std::string>(ifa->ifa_name, host));
}
}
freeifaddrs(ifaddr);
return 0;
}
// get IP address of a given interface name
std::string getInterfaceIP(std::string interface)
{
std::map<std::string, std::string> IPs;
getHostIPs(IPs);
if (IPs.count(interface))
{
return IPs[interface];
}
else
{
LOG(ERROR) << "Could not find provided network interface: \"" << interface << "\"!, exiting.";
return "";
}
}
// get name of the default route interface
std::string getDefaultRouteNetworkInterface()
{
std::array<char, 128> buffer;
std::string interfaceName;
#ifdef __APPLE__ // MacOS
std::unique_ptr<FILE, decltype(pclose) *> file(popen("route -n get default | grep interface | cut -d \":\" -f 2", "r"), pclose);
#else // Linux
std::unique_ptr<FILE, decltype(pclose) *> file(popen("ip route | grep default | cut -d \" \" -f 5", "r"), pclose);
#endif
if (!file)
{
LOG(ERROR) << "Could not detect default route network interface name - popen() failed!";
return "";
}
while (!feof(file.get()))
{
if (fgets(buffer.data(), 128, file.get()) != NULL)
{
interfaceName += buffer.data();
}
}
boost::algorithm::trim(interfaceName);
if (interfaceName == "")
{
LOG(ERROR) << "Could not detect default route network interface name";
}
else
{
LOG(DEBUG) << "Detected network interface name for the default route: " << interfaceName;
}
return interfaceName;
}
} /* namespace tools */
} /* namespace mq */
} /* namespace fair */
#endif /* FAIR_MQ_TOOLS_NETWORK_H */

View File

@@ -2,7 +2,7 @@
Contains common tools for use by FairMQ and/or users.
## FairMQ::tools::getHostIPs
## fair::mq::tools::getHostIPs
Fills a map with the network interfaces and their IP addresses available on the current host.
@@ -13,13 +13,13 @@ Fills a map with the network interfaces and their IP addresses available on the
#include <string>
#include <iostream>
#include "FairMQTools.h"
#include <fairmq/Tools.h>
void main()
{
std::map<string,string> IPs;
FairMQ::tools::getHostIPs(IPs);
fair::mq::tools::getHostIPs(IPs);
for (std::map<string,string>::iterator it = IPs.begin(); it != IPs.end(); ++it)
{
@@ -32,4 +32,4 @@ void main()
eth0: 123.123.1.123
ib0: 123.123.2.123
lo: 127.0.0.1
```
```