diff options
author | Andrew Stitcher <astitcher@apache.org> | 2009-03-09 21:21:27 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2009-03-09 21:21:27 +0000 |
commit | f268a8e835344710794751d42c75454993b3829f (patch) | |
tree | de3ea8e321d3bac58c7684be63bf1b2ba89bdc53 /qpid/cpp/src | |
parent | 8b47ecc67da479eb0d8b650c8d172bc81b0343f6 (diff) | |
download | qpid-python-f268a8e835344710794751d42c75454993b3829f.tar.gz |
QPID-1722 Replace use of non thread safe gethostbyname()
with more useful getaddrinfo()
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@751844 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
-rw-r--r-- | qpid/cpp/src/qpid/sys/posix/Socket.cpp | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/qpid/cpp/src/qpid/sys/posix/Socket.cpp b/qpid/cpp/src/qpid/sys/posix/Socket.cpp index 9f67e6b7c0..ab0c28c48c 100644 --- a/qpid/cpp/src/qpid/sys/posix/Socket.cpp +++ b/qpid/cpp/src/qpid/sys/posix/Socket.cpp @@ -108,7 +108,7 @@ void Socket::createTcp() const { int& socket = impl->fd; if (socket != -1) Socket::close(); - int s = ::socket (PF_INET, SOCK_STREAM, 0); + int s = ::socket (AF_INET, SOCK_STREAM, 0); if (s < 0) throw QPID_POSIX_ERROR(errno); socket = s; } @@ -138,25 +138,30 @@ const char* h_errstr(int e) { } } -void Socket::connect(const std::string& host, uint16_t port) const +void Socket::connect(const std::string& host, uint16_t p) const { - std::stringstream namestream; - namestream << host << ":" << port; - connectname = namestream.str(); + std::stringstream portstream; + portstream << p; + std::string port = portstream.str(); + connectname = host + ":" + port; const int& socket = impl->fd; - struct sockaddr_in name; - name.sin_family = AF_INET; - name.sin_port = htons(port); - // TODO: Be good to make this work for IPv6 as well as IPv4 - // Use more modern lookup functions - struct hostent* hp = gethostbyname ( host.c_str() ); - if (hp == 0) - throw Exception(QPID_MSG("Cannot resolve " << host << ": " << h_errstr(h_errno))); - ::memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); - if ((::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) && - (errno != EINPROGRESS)) + + ::addrinfo *res; + ::addrinfo hints; + ::memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; // In order to allow AF_INET6 we'd have to change createTcp() as well + hints.ai_socktype = SOCK_STREAM; + int n = ::getaddrinfo(host.c_str(), port.c_str(), &hints, &res); + if (n != 0) + throw Exception(QPID_MSG("Cannot resolve " << host << ": " << ::gai_strerror(n))); + // TODO the correct thing to do here is loop on failure until you've used all the returned addresses + if ((::connect(socket, res->ai_addr, res->ai_addrlen) < 0) && + (errno != EINPROGRESS)) { + ::freeaddrinfo(res); throw qpid::Exception(QPID_MSG(strError(errno) << ": " << host << ":" << port)); + } + ::freeaddrinfo(res); } void |