summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2012-05-08 15:04:38 +0000
committerAlan Conway <aconway@apache.org>2012-05-08 15:04:38 +0000
commitdf7cc99c47c1917c736691a71c0b50eb08ebfa9f (patch)
treee02d37dd3a651580e1437b5f20bcdfaa6ae9cc9e
parent088a5a4f546dab65a72574e7704dd08a302f008f (diff)
downloadqpid-python-df7cc99c47c1917c736691a71c0b50eb08ebfa9f.tar.gz
QPID-3603: Added SystemInfo::isLocalHost to check if a host name refers to the local host.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1335562 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/include/qpid/sys/SystemInfo.h88
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/SystemInfo.cpp82
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/SystemInfo.cpp6
-rw-r--r--qpid/cpp/src/tests/CMakeLists.txt1
-rw-r--r--qpid/cpp/src/tests/Makefile.am3
-rw-r--r--qpid/cpp/src/tests/SystemInfo.cpp50
6 files changed, 165 insertions, 65 deletions
diff --git a/qpid/cpp/include/qpid/sys/SystemInfo.h b/qpid/cpp/include/qpid/sys/SystemInfo.h
index 23594cf650..24bc099d75 100644
--- a/qpid/cpp/include/qpid/sys/SystemInfo.h
+++ b/qpid/cpp/include/qpid/sys/SystemInfo.h
@@ -34,51 +34,61 @@ namespace sys {
* Results may be dependent on OS/hardware.
*/
namespace SystemInfo {
- /**
- * Estimate available concurrency, e.g. number of CPU cores.
- * -1 means estimate not available on this platform.
- */
- QPID_COMMON_EXTERN long concurrency();
+/**
+ * Estimate available concurrency, e.g. number of CPU cores.
+ * -1 means estimate not available on this platform.
+ */
+QPID_COMMON_EXTERN long concurrency();
- /**
- * Get the local host name and set it in the specified.
- * Returns false if it can't be obtained and sets errno to any error value.
- */
- QPID_COMMON_EXTERN bool getLocalHostname (Address &address);
+/**
+ * Get the local host name and set it in the specified.
+ * Returns false if it can't be obtained and sets errno to any error value.
+ */
+QPID_COMMON_EXTERN bool getLocalHostname (Address &address);
- QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
+/**
+ * Get the (possibly multiple) local IP addresses of this host
+ * using the specified port.
+ */
+QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
+
+/**
+ * Return true if host names an address of the local host.
+ *@param host host name or IP address.
+ */
+QPID_COMMON_EXTERN bool isLocalHost(const std::string& host);
- /**
- * Retrieve system identifiers and versions. This is information that can
- * generally be retrieved via POSIX uname().
- *
- * @param osName Receives the OS name; e.g., GNU/Linux or Windows
- * @param nodeName Receives the nodename. This may or may not match the
- * set hostname from getLocalHostname().
- * @param release Receives the OS release identifier.
- * @param version Receives the OS release version (kernel, build, sp, etc.)
- * @param machine Receives the hardware type.
- */
- QPID_COMMON_EXTERN void getSystemId (std::string &osName,
- std::string &nodeName,
- std::string &release,
- std::string &version,
- std::string &machine);
+/**
+ * Retrieve system identifiers and versions. This is information that can
+ * generally be retrieved via POSIX uname().
+ *
+ * @param osName Receives the OS name; e.g., GNU/Linux or Windows
+ * @param nodeName Receives the nodename. This may or may not match the
+ * set hostname from getLocalHostname().
+ * @param release Receives the OS release identifier.
+ * @param version Receives the OS release version (kernel, build, sp, etc.)
+ * @param machine Receives the hardware type.
+ */
+QPID_COMMON_EXTERN void getSystemId (std::string &osName,
+ std::string &nodeName,
+ std::string &release,
+ std::string &version,
+ std::string &machine);
- /**
- * Get the process ID of the current process.
- */
- QPID_COMMON_EXTERN uint32_t getProcessId();
+/**
+ * Get the process ID of the current process.
+ */
+QPID_COMMON_EXTERN uint32_t getProcessId();
- /**
- * Get the process ID of the parent of the current process.
- */
- QPID_COMMON_EXTERN uint32_t getParentProcessId();
+/**
+ * Get the process ID of the parent of the current process.
+ */
+QPID_COMMON_EXTERN uint32_t getParentProcessId();
- /**
- * Get the name of the current process (i.e. the name of the executable)
- */
- QPID_COMMON_EXTERN std::string getProcessName();
+/**
+ * Get the name of the current process (i.e. the name of the executable)
+ */
+QPID_COMMON_EXTERN std::string getProcessName();
}}} // namespace qpid::sys::SystemInfo
diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
index 540cc8bc91..f6250f5831 100755
--- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
@@ -19,9 +19,9 @@
*/
#include "qpid/sys/SystemInfo.h"
-
#include "qpid/sys/posix/check.h"
-
+#include <set>
+#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/types.h> // For FreeBSD
@@ -71,38 +71,70 @@ void SystemInfo::getLocalIpAddresses (uint16_t port,
int family = ifap->ifa_addr->sa_family;
switch (family) {
- case AF_INET: {
- char dispName[NI_MAXHOST];
- int rc = ::getnameinfo(
- ifap->ifa_addr,
- (family == AF_INET)
- ? sizeof(struct sockaddr_in)
- : sizeof(struct sockaddr_in6),
- dispName, sizeof(dispName),
- 0, 0, NI_NUMERICHOST);
- if (rc != 0) {
- throw QPID_POSIX_ERROR(rc);
- }
- string addr(dispName);
- if (addr != LOCALHOST) {
- addrList.push_back(Address(TCP, addr, port));
- }
- break;
- }
- // TODO: Url parsing currently can't cope with IPv6 addresses so don't return them
- // when it can cope move this line to above "case AF_INET:"
- case AF_INET6:
- default:
+ case AF_INET: {
+ char dispName[NI_MAXHOST];
+ int rc = ::getnameinfo(
+ ifap->ifa_addr,
+ (family == AF_INET)
+ ? sizeof(struct sockaddr_in)
+ : sizeof(struct sockaddr_in6),
+ dispName, sizeof(dispName),
+ 0, 0, NI_NUMERICHOST);
+ if (rc != 0) {
+ throw QPID_POSIX_ERROR(rc);
+ }
+ string addr(dispName);
+ if (addr != LOCALHOST) {
+ addrList.push_back(Address(TCP, addr, port));
+ }
+ break;
+ }
+ // TODO: Url parsing currently can't cope with IPv6 addresses so don't return them
+ // when it can cope move this line to above "case AF_INET:"
+ case AF_INET6:
+ default:
continue;
}
}
- freeifaddrs(ifaddr);
+ ::freeifaddrs(ifaddr);
if (addrList.empty()) {
addrList.push_back(Address(TCP, LOCALHOST, port));
}
}
+namespace {
+struct AddrInfo {
+ struct addrinfo* ptr;
+ AddrInfo(const std::string& host) : ptr(0) {
+ if (::getaddrinfo(host.c_str(), NULL, NULL, &ptr) != 0)
+ ptr = 0;
+ }
+ ~AddrInfo() { if (ptr) ::freeaddrinfo(ptr); }
+};
+}
+
+bool SystemInfo::isLocalHost(const std::string& host) {
+ if (host == LOCALHOST) return true;
+ std::vector<Address> myAddrs;
+ getLocalIpAddresses(0, myAddrs);
+ std::set<string> localHosts;
+ for (std::vector<Address>::const_iterator i = myAddrs.begin(); i != myAddrs.end(); ++i)
+ localHosts.insert(i->host);
+ // Resolve host
+ AddrInfo ai(host);
+ if (!ai.ptr) return false;
+ for (struct addrinfo *res = ai.ptr; res != NULL; res = res->ai_next) {
+ // Get string form of IP addr
+ char addr[NI_MAXHOST] = "";
+ int error = ::getnameinfo(res->ai_addr, res->ai_addrlen, addr, NI_MAXHOST, NULL, 0,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (error) return false;
+ if (localHosts.find(addr) != localHosts.end()) return true;
+ }
+ return false;
+}
+
void SystemInfo::getSystemId (std::string &osName,
std::string &nodeName,
std::string &release,
diff --git a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
index 4da440bdd4..f1b62d80ff 100755
--- a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
@@ -93,6 +93,12 @@ void SystemInfo::getLocalIpAddresses (uint16_t port,
}
}
+bool SystemInfo::isLocalHost(const std::string& candidateHost) {
+ // FIXME aconway 2012-05-03: not implemented.
+ assert(0);
+ throw Exception("Not implemented: isLocalHost");
+}
+
void SystemInfo::getSystemId (std::string &osName,
std::string &nodeName,
std::string &release,
diff --git a/qpid/cpp/src/tests/CMakeLists.txt b/qpid/cpp/src/tests/CMakeLists.txt
index 5979ce42ae..e9ad80080c 100644
--- a/qpid/cpp/src/tests/CMakeLists.txt
+++ b/qpid/cpp/src/tests/CMakeLists.txt
@@ -149,6 +149,7 @@ set(unit_tests_to_build
PollableCondition
Variant
ClientMessage
+ SystemInfo
${xml_tests}
CACHE STRING "Which unit tests to build"
)
diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am
index 472de39d0b..3e705b074e 100644
--- a/qpid/cpp/src/tests/Makefile.am
+++ b/qpid/cpp/src/tests/Makefile.am
@@ -124,7 +124,8 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \
Address.cpp \
ClientMessage.cpp \
Qmf2.cpp \
- BrokerOptions.cpp
+ BrokerOptions.cpp \
+ SystemInfo.cpp
if HAVE_XML
unit_test_SOURCES+= XmlClientSessionTest.cpp
diff --git a/qpid/cpp/src/tests/SystemInfo.cpp b/qpid/cpp/src/tests/SystemInfo.cpp
new file mode 100644
index 0000000000..c467a0b012
--- /dev/null
+++ b/qpid/cpp/src/tests/SystemInfo.cpp
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include "unit_test.h"
+#include "test_tools.h"
+#include "qpid/sys/SystemInfo.h"
+#include <boost/assign.hpp>
+
+using namespace std;
+using namespace qpid::sys;
+using namespace boost::assign;
+
+namespace qpid {
+namespace tests {
+
+QPID_AUTO_TEST_SUITE(SystemInfoTestSuite)
+
+QPID_AUTO_TEST_CASE(TestIsLocalHost) {
+ // Test that local hostname and addresses are considered local
+ Address a;
+ BOOST_ASSERT(SystemInfo::getLocalHostname(a));
+ BOOST_ASSERT(SystemInfo::isLocalHost(a.host));
+ std::vector<Address> addrs;
+ for (std::vector<Address>::iterator i = addrs.begin(); i != addrs.end(); ++i)
+ BOOST_ASSERT(SystemInfo::isLocalHost(i->host));
+ // Check some non-local addresses
+ BOOST_ASSERT(!SystemInfo::isLocalHost("123.4.5.6"));
+ BOOST_ASSERT(!SystemInfo::isLocalHost("nosuchhost"));
+ BOOST_ASSERT(SystemInfo::isLocalHost("127.0.0.1"));
+}
+
+QPID_AUTO_TEST_SUITE_END()
+
+}} // namespace qpid::tests