diff options
author | Andrew Stitcher <astitcher@apache.org> | 2011-08-17 22:07:36 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2011-08-17 22:07:36 +0000 |
commit | 804a3a644f2ab1a7c958a945332b42953c36f367 (patch) | |
tree | 055e6793e63297e23cf5d8f7fd057abb7fe5b329 /cpp/src | |
parent | 4ed58953ddb2f89069edae20da375cc91b7e091f (diff) | |
download | qpid-python-804a3a644f2ab1a7c958a945332b42953c36f367.tar.gz |
NO-JIRA: Tidy up the Socket/SocketAddress code:
- Move (almost) all knowledge of difference in address types to SocketAddress
- Make the Windows and Posix sockets code more similar with the aim of
eliminating differences in the future
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1158934 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/qpid/sys/SocketAddress.h | 5 | ||||
-rw-r--r-- | cpp/src/qpid/sys/posix/Socket.cpp | 39 | ||||
-rw-r--r-- | cpp/src/qpid/sys/posix/SocketAddress.cpp | 46 | ||||
-rw-r--r-- | cpp/src/qpid/sys/windows/Socket.cpp | 66 | ||||
-rw-r--r-- | cpp/src/qpid/sys/windows/SocketAddress.cpp | 49 |
5 files changed, 114 insertions, 91 deletions
diff --git a/cpp/src/qpid/sys/SocketAddress.h b/cpp/src/qpid/sys/SocketAddress.h index 481beab747..dcca109d94 100644 --- a/cpp/src/qpid/sys/SocketAddress.h +++ b/cpp/src/qpid/sys/SocketAddress.h @@ -27,6 +27,7 @@ #include <string> struct addrinfo; +struct sockaddr; namespace qpid { namespace sys { @@ -45,6 +46,10 @@ public: QPID_COMMON_EXTERN std::string asString(bool numeric=true) const; QPID_COMMON_EXTERN void setAddrInfoPort(uint16_t port); + QPID_COMMON_EXTERN static std::string asString(::sockaddr const * const addr, size_t addrlen); + QPID_COMMON_EXTERN static uint16_t getPort(::sockaddr const * const addr); + + private: std::string host; std::string port; diff --git a/cpp/src/qpid/sys/posix/Socket.cpp b/cpp/src/qpid/sys/posix/Socket.cpp index 0ec5688d07..4a6dc66f80 100644 --- a/cpp/src/qpid/sys/posix/Socket.cpp +++ b/cpp/src/qpid/sys/posix/Socket.cpp @@ -34,9 +34,6 @@ #include <netdb.h> #include <cstdlib> #include <string.h> -#include <iostream> - -#include <boost/format.hpp> namespace qpid { namespace sys { @@ -44,38 +41,28 @@ namespace sys { namespace { std::string getName(int fd, bool local) { - ::sockaddr_storage name; // big enough for any socket address - ::socklen_t namelen = sizeof(name); + ::sockaddr_storage name_s; // big enough for any socket address + ::sockaddr* name = (::sockaddr*)&name_s; + ::socklen_t namelen = sizeof(name_s); - int result = -1; if (local) { - result = ::getsockname(fd, (::sockaddr*)&name, &namelen); + QPID_POSIX_CHECK( ::getsockname(fd, name, &namelen) ); } else { - result = ::getpeername(fd, (::sockaddr*)&name, &namelen); + QPID_POSIX_CHECK( ::getpeername(fd, name, &namelen) ); } - QPID_POSIX_CHECK(result); - - char servName[NI_MAXSERV]; - char dispName[NI_MAXHOST]; - if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName), - servName, sizeof(servName), - NI_NUMERICHOST | NI_NUMERICSERV) != 0) - throw QPID_POSIX_ERROR(rc); - return std::string(dispName) + ":" + std::string(servName); + + return SocketAddress::asString(name, namelen); } uint16_t getLocalPort(int fd) { - ::sockaddr_storage name; - ::socklen_t namelen = sizeof(name); - if (::getsockname(fd, (::sockaddr*)&name, &namelen) < 0) - throw QPID_POSIX_ERROR(errno); + ::sockaddr_storage name_s; // big enough for any socket address + ::sockaddr* name = (::sockaddr*)&name_s; + ::socklen_t namelen = sizeof(name_s); - switch (name.ss_family) { - case AF_INET: return ntohs(((::sockaddr_in&)name).sin_port); - case AF_INET6: return ntohs(((::sockaddr_in6&)name).sin6_port); - default:throw Exception(QPID_MSG("Unexpected socket type")); - } + QPID_POSIX_CHECK( ::getsockname(fd, name, &namelen) ); + + return SocketAddress::getPort(name); } } diff --git a/cpp/src/qpid/sys/posix/SocketAddress.cpp b/cpp/src/qpid/sys/posix/SocketAddress.cpp index 67438c0d89..077942ef2f 100644 --- a/cpp/src/qpid/sys/posix/SocketAddress.cpp +++ b/cpp/src/qpid/sys/posix/SocketAddress.cpp @@ -21,11 +21,13 @@ #include "qpid/sys/SocketAddress.h" -#include "qpid/sys/posix/check.h" +#include "qpid/Exception.h" +#include "qpid/Msg.h" #include <sys/socket.h> -#include <string.h> +#include <netinet/in.h> #include <netdb.h> +#include <string.h> namespace qpid { namespace sys { @@ -59,25 +61,45 @@ SocketAddress::~SocketAddress() } } -std::string SocketAddress::asString(bool numeric) const +std::string SocketAddress::asString(::sockaddr const * const addr, size_t addrlen) { - if (!numeric) - return host + ":" + port; - // Canonicalise into numeric id - const ::addrinfo& ai = getAddrInfo(*this); char servName[NI_MAXSERV]; char dispName[NI_MAXHOST]; - if (int rc=::getnameinfo(ai.ai_addr, ai.ai_addrlen, - dispName, sizeof(dispName), - servName, sizeof(servName), - NI_NUMERICHOST | NI_NUMERICSERV) != 0) + if (int rc=::getnameinfo(addr, addrlen, + dispName, sizeof(dispName), + servName, sizeof(servName), + NI_NUMERICHOST | NI_NUMERICSERV) != 0) throw qpid::Exception(QPID_MSG(gai_strerror(rc))); - std::string s(dispName); + std::string s; + switch (addr->sa_family) { + case AF_INET: s += dispName; break; + case AF_INET6: s += "["; s += dispName; s+= "]"; break; + default: throw Exception(QPID_MSG("Unexpected socket type")); + } s += ":"; s += servName; return s; } +uint16_t SocketAddress::getPort(::sockaddr const * const addr) +{ + switch (addr->sa_family) { + case AF_INET: return ntohs(((::sockaddr_in*)addr)->sin_port); + case AF_INET6: return ntohs(((::sockaddr_in6*)addr)->sin6_port); + default:throw Exception(QPID_MSG("Unexpected socket type")); + } +} + +std::string SocketAddress::asString(bool numeric) const +{ + if (!numeric) + return host + ":" + port; + // Canonicalise into numeric id + const ::addrinfo& ai = getAddrInfo(*this); + + return asString(ai.ai_addr, ai.ai_addrlen); +} + bool SocketAddress::nextAddress() { bool r = currentAddrInfo->ai_next != 0; if (r) diff --git a/cpp/src/qpid/sys/windows/Socket.cpp b/cpp/src/qpid/sys/windows/Socket.cpp index 8736656e19..c85e8162da 100644 --- a/cpp/src/qpid/sys/windows/Socket.cpp +++ b/cpp/src/qpid/sys/windows/Socket.cpp @@ -19,25 +19,19 @@ * */ -// Ensure we get all of winsock2.h -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#endif - #include "qpid/sys/Socket.h" + #include "qpid/sys/SocketAddress.h" -#include "qpid/sys/windows/IoHandlePrivate.h" #include "qpid/sys/windows/check.h" -#include "qpid/sys/Time.h" +#include "qpid/sys/windows/IoHandlePrivate.h" -#include <cstdlib> -#include <string.h> +// Ensure we get all of winsock2.h +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif #include <winsock2.h> -#include <boost/format.hpp> -#include <boost/lexical_cast.hpp> - // Need to initialize WinSock. Ideally, this would be a singleton or embedded // in some one-time initialization function. I tried boost singleton and could // not get it to compile (and others located in google had the same problem). @@ -91,35 +85,28 @@ namespace { std::string getName(SOCKET fd, bool local) { - sockaddr_storage name; // big enough for any socket address - socklen_t namelen = sizeof(name); + ::sockaddr_storage name_s; // big enough for any socket address + ::sockaddr* name = (::sockaddr*)&name_s; + ::socklen_t namelen = sizeof(name_s); + if (local) { - QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen)); + QPID_WINSOCK_CHECK(::getsockname(fd, name, &namelen)); } else { - QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen)); + QPID_WINSOCK_CHECK(::getpeername(fd, name, &namelen)); } - char servName[NI_MAXSERV]; - char dispName[NI_MAXHOST]; - if (int rc = ::getnameinfo((sockaddr*)&name, namelen, - dispName, sizeof(dispName), - servName, sizeof(servName), - NI_NUMERICHOST | NI_NUMERICSERV) != 0) - throw qpid::Exception(QPID_MSG(gai_strerror(rc))); - return std::string(dispName) + ":" + std::string(servName); + return SocketAddress::asString(name, namelen); } uint16_t getLocalPort(int fd) { - ::sockaddr_storage name; - ::socklen_t namelen = sizeof(name); - QPID_WINSOCK_CHECK(::getsockname(fd, (::sockaddr*)&name, &namelen)); - - switch (name.ss_family) { - case AF_INET: return ntohs(((::sockaddr_in&)name).sin_port); - case AF_INET6: return ntohs(((::sockaddr_in6&)name).sin6_port); - default:throw Exception(QPID_MSG("Unexpected socket type")); - } + ::sockaddr_storage name_s; // big enough for any socket address + ::sockaddr* name = (::sockaddr*)&name_s; + ::socklen_t namelen = sizeof(name_s); + + QPID_WINSOCK_CHECK(::getsockname(fd, name, &namelen)); + + return SocketAddress::getPort(name); } } // namespace @@ -135,8 +122,7 @@ Socket::Socket(IOHandlePrivate* h) : nodelay(false) {} -void -Socket::createSocket(const SocketAddress& sa) const +void Socket::createSocket(const SocketAddress& sa) const { SOCKET& socket = impl->fd; if (socket != INVALID_SOCKET) Socket::close(); @@ -152,11 +138,11 @@ Socket::createSocket(const SocketAddress& sa) const if (nodelay) setTcpNoDelay(); if (getAddrInfo(sa).ai_family == AF_INET6) { int flag = 1; - int result = setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&flag, sizeof(flag)); + int result = ::setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&flag, sizeof(flag)); QPID_WINSOCK_CHECK(result); } } catch (std::exception&) { - closesocket(s); + ::closesocket(s); socket = INVALID_SOCKET; throw; } @@ -264,15 +250,17 @@ Socket* Socket::accept() const std::string Socket::getPeerAddress() const { - if (peername.empty()) + if (peername.empty()) { peername = getName(impl->fd, false); + } return peername; } std::string Socket::getLocalAddress() const { - if (localname.empty()) + if (localname.empty()) { localname = getName(impl->fd, true); + } return localname; } diff --git a/cpp/src/qpid/sys/windows/SocketAddress.cpp b/cpp/src/qpid/sys/windows/SocketAddress.cpp index 438c31f001..77bbf85810 100644 --- a/cpp/src/qpid/sys/windows/SocketAddress.cpp +++ b/cpp/src/qpid/sys/windows/SocketAddress.cpp @@ -19,15 +19,16 @@ * */ +#include "qpid/sys/SocketAddress.h" + +#include "qpid/Exception.h" +#include "qpid/Msg.h" + // Ensure we get all of winsock2.h #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif -#include "qpid/sys/SocketAddress.h" - -#include "qpid/sys/windows/check.h" - #include <winsock2.h> #include <ws2tcpip.h> #include <string.h> @@ -64,25 +65,45 @@ SocketAddress::~SocketAddress() } } -std::string SocketAddress::asString(bool numeric) const +std::string SocketAddress::asString(::sockaddr const * const addr, size_t addrlen) { - if (!numeric) - return host + ":" + port; - // Canonicalise into numeric id - const ::addrinfo& ai = getAddrInfo(*this); char servName[NI_MAXSERV]; char dispName[NI_MAXHOST]; - if (int rc=::getnameinfo(ai.ai_addr, ai.ai_addrlen, - dispName, sizeof(dispName), - servName, sizeof(servName), - NI_NUMERICHOST | NI_NUMERICSERV) != 0) + if (int rc=::getnameinfo(addr, addrlen, + dispName, sizeof(dispName), + servName, sizeof(servName), + NI_NUMERICHOST | NI_NUMERICSERV) != 0) throw qpid::Exception(QPID_MSG(gai_strerror(rc))); - std::string s(dispName); + std::string s; + switch (addr->sa_family) { + case AF_INET: s += dispName; break; + case AF_INET6: s += "["; s += dispName; s+= "]"; break; + default: throw Exception(QPID_MSG("Unexpected socket type")); + } s += ":"; s += servName; return s; } +uint16_t SocketAddress::getPort(::sockaddr const * const addr) +{ + switch (addr->sa_family) { + case AF_INET: return ntohs(((::sockaddr_in*)addr)->sin_port); + case AF_INET6: return ntohs(((::sockaddr_in6*)addr)->sin6_port); + default:throw Exception(QPID_MSG("Unexpected socket type")); + } +} + +std::string SocketAddress::asString(bool numeric) const +{ + if (!numeric) + return host + ":" + port; + // Canonicalise into numeric id + const ::addrinfo& ai = getAddrInfo(*this); + + return asString(ai.ai_addr, ai.ai_addrlen); +} + bool SocketAddress::nextAddress() { bool r = currentAddrInfo->ai_next != 0; if (r) |