Mercurial > code
changeset 379:57ce1a6293b9
Socket: bring SocketSsl back in the run
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 19 Jun 2015 11:18:53 +0200 |
parents | 92457ea8f7e2 |
children | 06b0f405c58f |
files | C++/modules/Socket/Socket.cpp C++/modules/Socket/Socket.h C++/modules/Socket/SocketSsl.cpp C++/modules/Socket/SocketSsl.h |
diffstat | 4 files changed, 84 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Socket/Socket.cpp Fri Jun 19 10:52:54 2015 +0200 +++ b/C++/modules/Socket/Socket.cpp Fri Jun 19 11:18:53 2015 +0200 @@ -26,6 +26,14 @@ * -------------------------------------------------------- */ #if defined(_WIN32) +const Socket::Handle Socket::Invalid{INVALID_SOCKET}; +const int Socket::Error{SOCKET_ERROR}; +#else +const int Socket::Invalid{-1}; +const int Socket::Error{-1}; +#endif + +#if defined(_WIN32) std::string Socket::syserror(int errn) {
--- a/C++/modules/Socket/Socket.h Fri Jun 19 10:52:54 2015 +0200 +++ b/C++/modules/Socket/Socket.h Fri Jun 19 11:18:53 2015 +0200 @@ -71,6 +71,10 @@ */ class SocketError : public std::exception { public: + /** + * @enum Code + * @brief Which kind of error + */ enum Code { WouldBlockRead, ///!< The operation would block for reading WouldBlockWrite, ///!< The operation would block for writing @@ -78,10 +82,12 @@ System ///!< There is a system error }; +private: Code m_code; std::string m_function; std::string m_error; +public: /** * Constructor that use the last system error. * @@ -165,12 +171,34 @@ * and Windows. */ #if defined(_WIN32) + /** + * Socket type, SOCKET. + */ using Handle = SOCKET; + + /** + * Argument to pass to set. + */ using ConstArg = const char *; + + /** + * Argument to pass to get. + */ using Arg = char *; #else + /** + * Socket type, int. + */ using Handle = int; + + /** + * Argument to pass to set. + */ using ConstArg = const void *; + + /** + * Argument to pass to get. + */ using Arg = void *; #endif @@ -183,11 +211,25 @@ * to Windows. */ #if defined(_WIN32) - static constexpr const Handle Invalid = INVALID_SOCKET; - static constexpr const int Error = SOCKET_ERROR; + /** + * Socket creation failure or invalidation. + */ + static const Handle Invalid; + + /** + * Socket operation failure. + */ + static const int Error; #else - static constexpr const int Invalid = -1; - static constexpr const int Error = -1; + /** + * Socket creation failure or invalidation. + */ + static const int Invalid; + + /** + * Socket operation failure. + */ + static const int Error; #endif /* }}} */ @@ -205,11 +247,17 @@ static std::atomic<bool> s_initialized; public: + /** + * Calls WSACleanup. + */ static inline void finish() noexcept { WSACleanup(); } + /** + * Initialize using WSAStartup. + */ static inline void initialize() noexcept { std::lock_guard<std::mutex> lock(s_mutex); @@ -245,8 +293,8 @@ /* }}} */ protected: - Handle m_handle{Invalid}; - SocketState m_state{SocketState::Opened}; + Handle m_handle{Invalid}; //!< The native handle + SocketState m_state{SocketState::Opened}; //!< The socket state public: /**
--- a/C++/modules/Socket/SocketSsl.cpp Fri Jun 19 10:52:54 2015 +0200 +++ b/C++/modules/Socket/SocketSsl.cpp Fri Jun 19 11:18:53 2015 +0200 @@ -41,10 +41,10 @@ std::mutex SocketSsl::s_sslMutex; std::atomic<bool> SocketSsl::s_sslInitialized{false}; -SocketSsl::SocketSsl(Socket::Handle handle, SSL_CTX *context, SSL *ssl) - : SocketTcp(handle) - , m_context(context, SSL_CTX_free) - , m_ssl(ssl, SSL_free) +SocketSsl::SocketSsl(std::unique_ptr<SocketTcp> sc, SSL_CTX *context, SSL *ssl) + : SocketTcp{std::move(*sc)} + , m_context{context, SSL_CTX_free} + , m_ssl{ssl, SSL_free} { #if !defined(SOCKET_NO_SSL_INIT) if (!s_sslInitialized) { @@ -54,37 +54,32 @@ } SocketSsl::SocketSsl(int family, int protocol, SocketSslOptions options) - : SocketTcp(family, protocol) - , m_options(std::move(options)) + : SocketTcp{family, protocol} + , m_context{nullptr, nullptr} + , m_ssl{nullptr, nullptr} + , m_options{std::move(options)} { #if !defined(SOCKET_NO_SSL_INIT) if (!s_sslInitialized) { sslInitialize(); } #endif + m_context = ContextHandle{SSL_CTX_new(sslMethod(m_options.method)), SSL_CTX_free}; + m_ssl = SslHandle{SSL_new(m_context.get()), SSL_free}; + + SSL_set_fd(m_ssl.get(), m_handle); } void SocketSsl::connect(const std::unique_ptr<SocketAddress> &address) { -#if 0 - std::unique_ptr<SocketTcp> standard = SocketTcp::connect(address); - - // Context first - auto context = SSL_CTX_new(sslMethod(m_options.method)); - - m_context = ContextHandle(context, SSL_CTX_free); + // 1. Standard connect + SocketTcp::connect(address); - // SSL object then - auto ssl = SSL_new(context); - - m_ssl = SslHandle(ssl, SSL_free); - - SSL_set_fd(ssl, m_handle); - - auto ret = SSL_connect(ssl); + // 2. OpenSSL handshake + auto ret = SSL_connect(m_ssl.get()); if (ret <= 0) { - auto error = SSL_get_error(ssl, ret); + auto error = SSL_get_error(m_ssl.get(), ret); if (error == SSL_ERROR_WANT_READ) { throw SocketError(SocketError::WouldBlockRead, "connect", "Operation in progress"); @@ -96,13 +91,11 @@ } m_state = SocketState::Connected; -#endif } std::unique_ptr<SocketTcp> SocketSsl::accept(std::unique_ptr<SocketAddress> &info) { -#if 0 - auto client = standardAccept(info); + auto client = SocketTcp::accept(info); auto context = SSL_CTX_new(sslMethod(m_options.method)); if (m_options.certificate.size() > 0) @@ -110,14 +103,13 @@ if (m_options.privateKey.size() > 0) SSL_CTX_use_PrivateKey_file(context, m_options.privateKey.c_str(), SSL_FILETYPE_PEM); if (m_options.verify && !SSL_CTX_check_private_key(context)) { - client.close(); throw SocketError(SocketError::System, "accept", "certificate failure"); } // SSL object auto ssl = SSL_new(context); - SSL_set_fd(ssl, client.handle()); + SSL_set_fd(ssl, client->handle()); auto ret = SSL_accept(ssl); @@ -133,8 +125,7 @@ } } - return SocketSsl(client.handle(), context, ssl); -#endif + return std::make_unique<SocketSsl>(std::move(client), context, ssl); } unsigned SocketSsl::recv(void *data, unsigned len)
--- a/C++/modules/Socket/SocketSsl.h Fri Jun 19 10:52:54 2015 +0200 +++ b/C++/modules/Socket/SocketSsl.h Fri Jun 19 11:18:53 2015 +0200 @@ -120,11 +120,11 @@ /** * Create a SocketSsl from an already created one. * - * @param handle the native handle + * @param sc the standard TCP socket * @param context the context * @param ssl the ssl object */ - SocketSsl(Socket::Handle handle, SSL_CTX *context, SSL *ssl); + SocketSsl(std::unique_ptr<SocketTcp> sc, SSL_CTX *context, SSL *ssl); /** * Open a SSL socket with the specified family. Automatically