diff options
| author | Andrew Stitcher <astitcher@apache.org> | 2012-05-18 22:05:37 +0000 |
|---|---|---|
| committer | Andrew Stitcher <astitcher@apache.org> | 2012-05-18 22:05:37 +0000 |
| commit | 6d7405089db8359d001b3f9133e819f8d40c0a8a (patch) | |
| tree | db5bc84749f808afce94d640ed04bf00be26952f /qpid/cpp/src | |
| parent | d09c5fd0d1c027bba41db30f8648fd8a024f9633 (diff) | |
| download | qpid-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-x | qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp | 39 | ||||
| -rw-r--r-- | qpid/cpp/src/tests/SystemInfo.cpp | 2 |
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() |
