summaryrefslogtreecommitdiff
path: root/qpid/cpp/src
diff options
context:
space:
mode:
authorAndrew Stitcher <astitcher@apache.org>2012-05-18 22:05:37 +0000
committerAndrew Stitcher <astitcher@apache.org>2012-05-18 22:05:37 +0000
commit6d7405089db8359d001b3f9133e819f8d40c0a8a (patch)
treedb5bc84749f808afce94d640ed04bf00be26952f /qpid/cpp/src
parentd09c5fd0d1c027bba41db30f8648fd8a024f9633 (diff)
downloadqpid-python-6d7405089db8359d001b3f9133e819f8d40c0a8a.tar.gz
QPID-4011: TestIsLocalHost unit_test fails with if machine name resolves to loopback address
QPID-3404 - This change also adds support for IPv6 interface addresses to getLocalIpAddresses git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1340279 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/SystemInfo.cpp39
-rw-r--r--qpid/cpp/src/tests/SystemInfo.cpp2
2 files changed, 30 insertions, 11 deletions
diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
index 9e66417aef..c57f784058 100755
--- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
@@ -60,19 +60,41 @@ bool SystemInfo::getLocalHostname (Address &address) {
return true;
}
-static const string LOCALHOST("127.0.0.1");
+static const string LOOPBACK("127.0.0.1");
static const string TCP("tcp");
+// Test IPv4 address for loopback
+inline bool IN_IS_ADDR_LOOPBACK(const ::in_addr* a) {
+ return ((::ntohl(a->s_addr) & 0xff000000) == 0x7f000000);
+}
+
+inline bool isLoopback(const ::sockaddr* addr) {
+ switch (addr->sa_family) {
+ case AF_INET: return IN_IS_ADDR_LOOPBACK(&((const ::sockaddr_in*)(const void*)addr)->sin_addr);
+ case AF_INET6: return IN6_IS_ADDR_LOOPBACK(&((const ::sockaddr_in6*)(const void*)addr)->sin6_addr);
+ default: return false;
+ }
+}
+
void SystemInfo::getLocalIpAddresses (uint16_t port,
std::vector<Address> &addrList) {
::ifaddrs* ifaddr = 0;
QPID_POSIX_CHECK(::getifaddrs(&ifaddr));
for (::ifaddrs* ifap = ifaddr; ifap != 0; ifap = ifap->ifa_next) {
if (ifap->ifa_addr == 0) continue;
-
+ if (isLoopback(ifap->ifa_addr)) continue;
int family = ifap->ifa_addr->sa_family;
switch (family) {
- case AF_INET: {
+ case AF_INET6: {
+ // Ignore link local addresses as:
+ // * The scope id is illegal in URL syntax
+ // * Clients won't be able to use a link local address
+ // without adding their own (potentially different) scope id
+ sockaddr_in6* sa6 = (sockaddr_in6*)(ifap->ifa_addr);
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) break;
+ // Fallthrough
+ }
+ case AF_INET: {
char dispName[NI_MAXHOST];
int rc = ::getnameinfo(
ifap->ifa_addr,
@@ -85,14 +107,9 @@ void SystemInfo::getLocalIpAddresses (uint16_t port,
throw QPID_POSIX_ERROR(rc);
}
string addr(dispName);
- if (addr != LOCALHOST) {
- addrList.push_back(Address(TCP, addr, port));
- }
+ 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;
}
@@ -100,7 +117,7 @@ void SystemInfo::getLocalIpAddresses (uint16_t port,
::freeifaddrs(ifaddr);
if (addrList.empty()) {
- addrList.push_back(Address(TCP, LOCALHOST, port));
+ addrList.push_back(Address(TCP, LOOPBACK, port));
}
}
@@ -116,7 +133,6 @@ struct AddrInfo {
}
bool SystemInfo::isLocalHost(const std::string& host) {
- if (host == LOCALHOST) return true;
std::vector<Address> myAddrs;
getLocalIpAddresses(0, myAddrs);
std::set<string> localHosts;
@@ -126,6 +142,7 @@ bool SystemInfo::isLocalHost(const std::string& host) {
AddrInfo ai(host);
if (!ai.ptr) return false;
for (struct addrinfo *res = ai.ptr; res != NULL; res = res->ai_next) {
+ if (isLoopback(res->ai_addr)) return true;
// Get string form of IP addr
char addr[NI_MAXHOST] = "";
int error = ::getnameinfo(res->ai_addr, res->ai_addrlen, addr, NI_MAXHOST, NULL, 0,
diff --git a/qpid/cpp/src/tests/SystemInfo.cpp b/qpid/cpp/src/tests/SystemInfo.cpp
index c467a0b012..12d8d3dba8 100644
--- a/qpid/cpp/src/tests/SystemInfo.cpp
+++ b/qpid/cpp/src/tests/SystemInfo.cpp
@@ -37,12 +37,14 @@ QPID_AUTO_TEST_CASE(TestIsLocalHost) {
BOOST_ASSERT(SystemInfo::getLocalHostname(a));
BOOST_ASSERT(SystemInfo::isLocalHost(a.host));
std::vector<Address> addrs;
+ SystemInfo::getLocalIpAddresses(0, 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"));
+ BOOST_ASSERT(SystemInfo::isLocalHost("::1"));
}
QPID_AUTO_TEST_SUITE_END()