diff options
| author | Kim van der Riet <kpvdr@apache.org> | 2012-08-03 12:13:32 +0000 |
|---|---|---|
| committer | Kim van der Riet <kpvdr@apache.org> | 2012-08-03 12:13:32 +0000 |
| commit | d43d1912b376322e27fdcda551a73f9ff5487972 (patch) | |
| tree | ce493e10baa95f44be8beb5778ce51783463196d /cpp/src/qpid/sys/posix | |
| parent | 04877fec0c6346edec67072d7f2d247740cf2af5 (diff) | |
| download | qpid-python-d43d1912b376322e27fdcda551a73f9ff5487972.tar.gz | |
QPID-3858: Updated branch - merged from trunk r.1368650
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1368910 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/sys/posix')
| -rwxr-xr-x | cpp/src/qpid/sys/posix/LockFile.cpp | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/sys/posix/MemStat.cpp | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/sys/posix/SocketAddress.cpp | 6 | ||||
| -rwxr-xr-x | cpp/src/qpid/sys/posix/SystemInfo.cpp | 108 |
4 files changed, 87 insertions, 31 deletions
diff --git a/cpp/src/qpid/sys/posix/LockFile.cpp b/cpp/src/qpid/sys/posix/LockFile.cpp index c1f1c37b47..9fdf83f1bd 100755 --- a/cpp/src/qpid/sys/posix/LockFile.cpp +++ b/cpp/src/qpid/sys/posix/LockFile.cpp @@ -46,7 +46,7 @@ LockFile::LockFile(const std::string& path_, bool create) errno = 0; int flags=create ? O_WRONLY|O_CREAT|O_NOFOLLOW : O_RDWR; int fd = ::open(path.c_str(), flags, 0644); - if (fd < 0) throw ErrnoException("Cannot open " + path, errno); + if (fd < 0) throw ErrnoException("Cannot open lock file " + path, errno); if (::lockf(fd, F_TLOCK, 0) < 0) { ::close(fd); throw ErrnoException("Cannot lock " + path, errno); diff --git a/cpp/src/qpid/sys/posix/MemStat.cpp b/cpp/src/qpid/sys/posix/MemStat.cpp index 72c53e5886..2fbf119cab 100644 --- a/cpp/src/qpid/sys/posix/MemStat.cpp +++ b/cpp/src/qpid/sys/posix/MemStat.cpp @@ -20,6 +20,7 @@ */ #include "qpid/sys/MemStat.h" + #include <malloc.h> void qpid::sys::MemStat::loadMemInfo(qmf::org::apache::qpid::broker::Memory* object) @@ -35,4 +36,3 @@ void qpid::sys::MemStat::loadMemInfo(qmf::org::apache::qpid::broker::Memory* obj object->set_malloc_keepcost(info.keepcost); } - diff --git a/cpp/src/qpid/sys/posix/SocketAddress.cpp b/cpp/src/qpid/sys/posix/SocketAddress.cpp index a7049c1851..344bd28669 100644 --- a/cpp/src/qpid/sys/posix/SocketAddress.cpp +++ b/cpp/src/qpid/sys/posix/SocketAddress.cpp @@ -35,14 +35,16 @@ namespace sys { SocketAddress::SocketAddress(const std::string& host0, const std::string& port0) : host(host0), port(port0), - addrInfo(0) + addrInfo(0), + currentAddrInfo(0) { } SocketAddress::SocketAddress(const SocketAddress& sa) : host(sa.host), port(sa.port), - addrInfo(0) + addrInfo(0), + currentAddrInfo(0) { } diff --git a/cpp/src/qpid/sys/posix/SystemInfo.cpp b/cpp/src/qpid/sys/posix/SystemInfo.cpp index 540cc8bc91..2b1bbb97df 100755 --- a/cpp/src/qpid/sys/posix/SystemInfo.cpp +++ b/cpp/src/qpid/sys/posix/SystemInfo.cpp @@ -18,10 +18,11 @@ * */ +#include "qpid/log/Statement.h" #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 @@ -33,6 +34,7 @@ #include <fstream> #include <sstream> #include <netdb.h> +#include <string.h> #ifndef HOST_NAME_MAX # define HOST_NAME_MAX 256 @@ -59,48 +61,100 @@ 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: { - 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); + 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 } - 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); + addrList.push_back(Address(TCP, addr, port)); + break; + } + default: continue; } } - freeifaddrs(ifaddr); + ::freeifaddrs(ifaddr); if (addrList.empty()) { - addrList.push_back(Address(TCP, LOCALHOST, port)); + addrList.push_back(Address(TCP, LOOPBACK, port)); + } +} + +namespace { +struct AddrInfo { + struct addrinfo* ptr; + AddrInfo(const std::string& host) : ptr(0) { + ::addrinfo hints; + ::memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // Allow both IPv4 and IPv6 + if (::getaddrinfo(host.c_str(), NULL, &hints, &ptr) != 0) + ptr = 0; + } + ~AddrInfo() { if (ptr) ::freeaddrinfo(ptr); } +}; +} + +bool SystemInfo::isLocalHost(const std::string& host) { + 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) { + 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, + NI_NUMERICHOST | NI_NUMERICSERV); + if (error) return false; + if (localHosts.find(addr) != localHosts.end()) return true; } + return false; } void SystemInfo::getSystemId (std::string &osName, |
