diff options
author | Andrew Stitcher <astitcher@apache.org> | 2012-11-16 14:27:14 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2012-11-16 14:27:14 +0000 |
commit | 039e634984f5dbcf1d9271b2e9a364b8a2c228c1 (patch) | |
tree | ab359a95feed13af86c5062cb34809b420870d91 /qpid/cpp/src/qpid/sys/posix | |
parent | 9d277505a7640b1f03039009f5dd41c9a3678e5c (diff) | |
download | qpid-python-039e634984f5dbcf1d9271b2e9a364b8a2c228c1.tar.gz |
QPID-3351: Provide ability to specify the network interfaces
Added functions to find machines network interface names and addresses
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1410362 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src/qpid/sys/posix')
-rwxr-xr-x | qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp index 0f29f511b1..cbff1effac 100755 --- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp +++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp @@ -32,6 +32,7 @@ #include <iostream> #include <fstream> #include <sstream> +#include <map> #include <netdb.h> #include <string.h> @@ -121,6 +122,72 @@ void SystemInfo::getLocalIpAddresses (uint16_t port, } } +namespace { + inline socklen_t sa_len(::sockaddr* sa) + { + switch (sa->sa_family) { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + default: + return sizeof(struct sockaddr_storage); + } + } + + inline bool isInetOrInet6(::sockaddr* sa) { + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + return true; + default: + return false; + } + } + typedef std::map<std::string, std::vector<std::string> > InterfaceInfo; + std::map<std::string, std::vector<std::string> > cachedInterfaces; + + void cacheInterfaceInfo() { + // Get interface info + ::ifaddrs* interfaceInfo; + QPID_POSIX_CHECK( ::getifaddrs(&interfaceInfo) ); + + char name[NI_MAXHOST]; + for (::ifaddrs* info = interfaceInfo; info != 0; info = info->ifa_next) { + + // Only use IPv4/IPv6 interfaces + if (!isInetOrInet6(info->ifa_addr)) continue; + + int rc=::getnameinfo(info->ifa_addr, sa_len(info->ifa_addr), + name, sizeof(name), 0, 0, + NI_NUMERICHOST); + if (rc >= 0) { + std::string address(name); + cachedInterfaces[info->ifa_name].push_back(address); + } else { + throw qpid::Exception(QPID_MSG(gai_strerror(rc))); + } + } + ::freeifaddrs(interfaceInfo); + } +} + +bool SystemInfo::getInterfaceAddresses(const std::string& interface, std::vector<std::string>& addresses) { + if ( cachedInterfaces.empty() ) cacheInterfaceInfo(); + InterfaceInfo::iterator i = cachedInterfaces.find(interface); + if ( i==cachedInterfaces.end() ) return false; + std::copy(i->second.begin(), i->second.end(), std::back_inserter(addresses)); + return true; +} + +void SystemInfo::getInterfaceNames(std::vector<std::string>& names ) { + if ( cachedInterfaces.empty() ) cacheInterfaceInfo(); + + for (InterfaceInfo::const_iterator i = cachedInterfaces.begin(); i!=cachedInterfaces.end(); ++i) { + names.push_back(i->first); + } +} + void SystemInfo::getSystemId (std::string &osName, std::string &nodeName, std::string &release, |