Mercurial > code
changeset 382:4b08afed634d
Socket:
- Clean up a bit
- Get rid of useless SocketAddress class
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 23 Jun 2015 14:21:47 +0200 |
parents | 9fd636045546 |
children | 403fa2642e19 |
files | C++/modules/Socket/SocketAddress.cpp C++/modules/Socket/SocketAddress.h C++/modules/Socket/SocketListener.h C++/tests/Socket/main.cpp |
diffstat | 4 files changed, 102 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Socket/SocketAddress.cpp Tue Jun 23 14:06:37 2015 +0200 +++ b/C++/modules/Socket/SocketAddress.cpp Tue Jun 23 14:21:47 2015 +0200 @@ -28,18 +28,24 @@ * Ip implementation * -------------------------------------------------------- */ +Ip::Ip() +{ + // Default uses IPv4 + std::memset(&m_sin, 0, sizeof (sockaddr_in)); +} + Ip::Ip(const std::string &host, unsigned port, int domain) : m_domain{domain} { if (host == "*") { if (m_domain == AF_INET6) { - std::memset(&m_sin6, 0, sizeof (struct sockaddr_in6)); + std::memset(&m_sin6, 0, sizeof (sockaddr_in6)); m_sin6.sin6_addr = in6addr_any; m_sin6.sin6_family = AF_INET6; m_sin6.sin6_port = htons(port); } else { - std::memset(&m_sin, 0, sizeof (struct sockaddr_in)); + std::memset(&m_sin, 0, sizeof (sockaddr_in)); m_sin.sin_addr.s_addr = INADDR_ANY; m_sin.sin_family = AF_INET; @@ -53,13 +59,13 @@ auto error = getaddrinfo(host.c_str(), std::to_string(port).c_str(), &hints, &res); if (error != 0) { - throw SocketError(SocketError::System, "getaddrinfo", gai_strerror(error)); + throw SocketError{SocketError::System, "getaddrinfo", gai_strerror(error)}; } if (m_domain == AF_INET6) { - std::memcpy(&m_sin6, res->ai_addr, sizeof (struct sockaddr_in6)); + std::memcpy(&m_sin6, res->ai_addr, sizeof (sockaddr_in6)); } else { - std::memcpy(&m_sin, res->ai_addr, sizeof (struct sockaddr_in)); + std::memcpy(&m_sin, res->ai_addr, sizeof (sockaddr_in)); } freeaddrinfo(res); @@ -81,6 +87,7 @@ std::string type = (m_domain == AF_INET6) ? "ipv6" : "ipv4"; std::string port = std::to_string(m_domain == AF_INET6 ? ntohs(m_sin6.sin6_port) : ntohs(m_sin.sin_port)); + // TODO: add IP here return SocketAddressInfo{ { "type", type }, { "port", port } @@ -102,8 +109,8 @@ } // Copy the path - memset(m_sun.sun_path, 0, sizeof (m_sun.sun_path)); - strncpy(m_sun.sun_path, m_path.c_str(), sizeof (m_sun.sun_path) - 1); + std::memset(m_sun.sun_path, 0, sizeof (m_sun.sun_path)); + std::strncpy(m_sun.sun_path, m_path.c_str(), sizeof (m_sun.sun_path) - 1); // Set the parameters m_sun.sun_family = AF_UNIX;
--- a/C++/modules/Socket/SocketAddress.h Tue Jun 23 14:06:37 2015 +0200 +++ b/C++/modules/Socket/SocketAddress.h Tue Jun 23 14:21:47 2015 +0200 @@ -27,6 +27,53 @@ * * SOCKET_HAVE_SUN_LEN - (bool) Some systems do not have SUN_LEN which is the preferred way to * compute the address size for a Unix address. Otherwise, sizeof is used. + * + * Addresses are used in many places such as bind, recvfrom, accept and such. They describe different + * parameters depending on the families. + * + * For example, when using IPv4, one should use Ipv4 class. + * + * All addresses are used directly as template parameter for a stronger type security. To be compatible + * with the sockets classes, an address must have the following requirements: + * + * - Default constructible + * - Copyable or Moveable + * + * Constructors: + * + * # With a storage address + * + * @code + * Address(const sockaddr_storage &ss, socklen_t size); + * @endcode + * + * The address is free to use the storage. + * + * Member functions: + * + * # Address + * + * @code + * inline const sockaddr &address() const noexcept + * @endcode + * + * Return the address converted to the C sockaddr structure. + * + * # Length + * + * @code + * inline socklen_t length() const noexcept + * @endcode + * + * Return the length of an address. + * + * # Info + * + * @code + * SocketAddressInfo info() const + * @endcode + * + * Return an information table about the address. */ #include <memory> @@ -49,42 +96,25 @@ using SocketAddressInfo = std::unordered_map<std::string, std::string>; /** - * @class SocketAddress - * @brief base class for socket addresses - * - * This class is mostly used to bind, connect or getting information - * on socket clients. - * - * @see Internet - * @see Unix + * @brief Predefined addresses. */ -class SocketAddress { -public: - /** - * Default constructor. - */ - SocketAddress() = default; - - /** - * Default destructor. - */ - virtual ~SocketAddress() = default; -}; - namespace address { /** * @class Ip - * @brief internet protocol connect class + * @brief Generic internet protocol address * * Create a connect address for internet protocol, * using getaddrinfo(3). + * + * @see Ipv4 + * @see Ipv6 */ -class Ip : public SocketAddress { +class Ip { private: union { - struct sockaddr_in m_sin; - struct sockaddr_in6 m_sin6; + sockaddr_in m_sin; + sockaddr_in6 m_sin6; }; int m_domain{AF_INET}; @@ -93,7 +123,7 @@ /** * Default constructor. */ - Ip() = default; + Ip(); /** * Create an IPv4 or IPV6 end point. @@ -139,6 +169,10 @@ SocketAddressInfo info() const; }; +/** + * @class Ipv6 + * @brief Convenient helper for IPv6 protocol + */ class Ipv6 : public Ip { public: /** @@ -157,6 +191,10 @@ } }; +/** + * @class Ipv4 + * @brief Convenient helper for IPv4 protocol + */ class Ipv4 : public Ip { public: /** @@ -183,12 +221,15 @@ * * Create an address to a specific path. Only available on Unix. */ -class Unix : public SocketAddress { +class Unix { private: - struct sockaddr_un m_sun; + sockaddr_un m_sun; std::string m_path; public: + /** + * Default constructor. + */ Unix() = default; /**
--- a/C++/modules/Socket/SocketListener.h Tue Jun 23 14:06:37 2015 +0200 +++ b/C++/modules/Socket/SocketListener.h Tue Jun 23 14:21:47 2015 +0200 @@ -315,7 +315,7 @@ * Returns the backend name. Usually the class in lower case. */ template <typename Backend = SOCKET_DEFAULT_BACKEND> -class SocketListenerBase final { +class SocketListenerAbstract final { public: /** * Mark the socket for read operation. @@ -335,24 +335,7 @@ /** * Construct an empty listener. */ - inline SocketListenerBase() noexcept - { - } - -#if 0 - - /** - * Create a listener from a list of sockets. - * - * @param list the list - */ - inline SocketListenerBase(std::initializer_list<std::pair<std::shared_ptr<Socket>, int>> list) - { - for (const auto &p : list) { - set(p.first, p.second); - } - } -#endif + SocketListenerAbstract() = default; /** * Get the backend. @@ -466,7 +449,7 @@ /** * Get the number of sockets in the listener. */ - inline auto size() const noexcept + inline SocketTable::size_type size() const noexcept { return m_table.size(); } @@ -522,7 +505,7 @@ }; template <typename Backend> -void SocketListenerBase<Backend>::set(SocketAbstract &sc, int flags) +void SocketListenerAbstract<Backend>::set(SocketAbstract &sc, int flags) { /* Invalid or useless flags */ if (flags == 0 || flags > 0x3) @@ -554,7 +537,7 @@ } template <typename Backend> -void SocketListenerBase<Backend>::unset(SocketAbstract &sc, int flags) +void SocketListenerAbstract<Backend>::unset(SocketAbstract &sc, int flags) { auto it = m_table.find(sc.handle()); @@ -590,12 +573,12 @@ /** * Helper to use the default. */ -using SocketListener = SocketListenerBase<>; +using SocketListener = SocketListenerAbstract<>; template <typename Backend> -const int SocketListenerBase<Backend>::Read{1 << 0}; +const int SocketListenerAbstract<Backend>::Read{1 << 0}; template <typename Backend> -const int SocketListenerBase<Backend>::Write{1 << 1}; +const int SocketListenerAbstract<Backend>::Write{1 << 1}; #endif // !_SOCKET_LISTENER_NG_H_
--- a/C++/tests/Socket/main.cpp Tue Jun 23 14:06:37 2015 +0200 +++ b/C++/tests/Socket/main.cpp Tue Jun 23 14:21:47 2015 +0200 @@ -28,8 +28,6 @@ #include <SocketAddress.h> #include <SocketListener.h> #include <SocketSsl.h> -#include <SocketTcp.h> -#include <SocketUdp.h> using namespace address; using namespace std::literals::chrono_literals; @@ -202,7 +200,7 @@ TEST(ListenerSet, initialAdd) { - SocketListenerBase<TestBackendSet> listener; + SocketListenerAbstract<TestBackendSet> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read); @@ -215,7 +213,7 @@ TEST(ListenerSet, readThenWrite) { - SocketListenerBase<TestBackendSet> listener; + SocketListenerAbstract<TestBackendSet> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read); @@ -229,7 +227,7 @@ TEST(ListenerSet, allOneShot) { - SocketListenerBase<TestBackendSet> listener; + SocketListenerAbstract<TestBackendSet> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read | SocketListener::Write); @@ -242,7 +240,7 @@ TEST(ListenerSet, readTwice) { - SocketListenerBase<TestBackendSet> listener; + SocketListenerAbstract<TestBackendSet> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read); @@ -256,7 +254,7 @@ TEST(ListenerSet, failure) { - SocketListenerBase<TestBackendSetFail> listener; + SocketListenerAbstract<TestBackendSetFail> listener; SocketAbstract s{0}; try { @@ -317,7 +315,7 @@ TEST(ListenerUnsetRemove, unset) { - SocketListenerBase<TestBackendUnset> listener; + SocketListenerAbstract<TestBackendUnset> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read); @@ -332,7 +330,7 @@ TEST(ListenerUnsetRemove, unsetOne) { - SocketListenerBase<TestBackendUnset> listener; + SocketListenerAbstract<TestBackendUnset> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read | SocketListener::Write); @@ -347,7 +345,7 @@ TEST(ListenerUnsetRemove, unsetAll) { - SocketListenerBase<TestBackendUnset> listener; + SocketListenerAbstract<TestBackendUnset> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read | SocketListener::Write); @@ -363,7 +361,7 @@ TEST(ListenerUnsetRemove, remove) { - SocketListenerBase<TestBackendUnset> listener; + SocketListenerAbstract<TestBackendUnset> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read | SocketListener::Write); @@ -378,7 +376,7 @@ TEST(ListenerUnsetRemove, failure) { - SocketListenerBase<TestBackendUnsetFail> listener; + SocketListenerAbstract<TestBackendUnsetFail> listener; SocketAbstract s{0}; listener.set(s, SocketListener::Read | SocketListener::Write); @@ -399,7 +397,7 @@ class ListenerTest : public testing::Test { protected: - SocketListenerBase<backend::Select> m_listener; + SocketListenerAbstract<backend::Select> m_listener; SocketTcp<Ipv4> m_masterTcp; SocketTcp<Ipv4> m_clientTcp;