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;