Author: astitcher
Date: Fri May 18 22:05:37 2012
New Revision: 1340279
URL: http://svn.apache.org/viewvc?rev=1340279&view=rev
Log:
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
Modified:
qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
qpid/trunk/qpid/cpp/src/tests/SystemInfo.cpp
Modified: qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp?rev=1340279&r1=1340278&r2=1340279&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp Fri May 18 22:05:37
2012
@@ -60,19 +60,41 @@ bool SystemInfo::getLocalHostname (Addre
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 (ui
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 (ui
::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::
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,
Modified: qpid/trunk/qpid/cpp/src/tests/SystemInfo.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/SystemInfo.cpp?rev=1340279&r1=1340278&r2=1340279&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/SystemInfo.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/SystemInfo.cpp Fri May 18 22:05:37 2012
@@ -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()
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]