Mercurial > code
changeset 467:41766abe942e
Socket:
- Protocol is passed before Address,
- Tls has dedicated funtions to prepare the socket before creating it.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 04 Nov 2015 20:53:36 +0100 |
parents | a126c10d9321 |
children | becd06089e8f |
files | C++/modules/Socket/Sockets.h C++/tests/Socket/main.cpp |
diffstat | 2 files changed, 109 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Socket/Sockets.h Wed Nov 04 20:36:07 2015 +0100 +++ b/C++/modules/Socket/Sockets.h Wed Nov 04 20:53:36 2015 +0100 @@ -620,11 +620,11 @@ * * Domain and type are determined by the Address and Protocol object. * + * @param protocol the protocol * @param address which type of address - * @param type the type instance */ - explicit inline Socket(const Address &address = {}, Protocol proto = Protocol{}) - : Socket{address.domain(), proto.type(), 0, std::move(proto)} + explicit inline Socket(Protocol protocol = {}, const Address &address = {}) + : Socket{address.domain(), protocol.type(), 0, std::move(protocol)} { } @@ -633,12 +633,12 @@ * * @param handle the native descriptor * @param state specify the socket state - * @param type the type of socket implementation + * @param protocol the type of socket implementation * @post action is set to None * @post condition is set to None */ - explicit inline Socket(Handle handle, State state = State::Closed, Protocol type = Protocol{}) noexcept - : m_proto(std::move(type)) + explicit inline Socket(Handle handle, State state = State::Closed, Protocol protocol = {}) noexcept + : m_proto(std::move(protocol)) , m_state{state} , m_handle{handle} { @@ -1250,7 +1250,7 @@ other.m_handle = Invalid; other.m_state = State::Closed; other.m_action = Action::None; - other.m_conditon = Condition::None; + other.m_condition = Condition::None; return *this; } @@ -1686,6 +1686,7 @@ * * @param sc the socket * @param address the address destination + * @param length the address length * @return the socket * @throw Error on errors */ @@ -1907,20 +1908,24 @@ #if !defined(SOCKET_NO_SSL) +namespace ssl { + +/** + * @enum Method + * @brief Which OpenSSL method to use. + */ +enum Method { + Tlsv1, //!< TLS v1.2 (recommended) + Sslv3 //!< SSLv3 +}; + +} // !ssl + /** * @class Tls * @brief OpenSSL secure layer for TCP */ class Tls : private Tcp { -public: - /** - * OpenSSL method to use. - */ - enum Method { - Tlsv1, //!< Tlsv1 (recommended) - Sslv3 //!< SSL v3 - }; - private: using Context = std::shared_ptr<SSL_CTX>; using Ssl = std::unique_ptr<SSL, void (*)(SSL *)>; @@ -1929,15 +1934,20 @@ Context m_context; Ssl m_ssl{nullptr, nullptr}; - /* Parameters */ - Method m_method{Tlsv1}; + /* Status */ + bool m_tcpconnected{false}; + + /* + * User definable parameters + */ + ssl::Method m_method{ssl::Tlsv1}; std::string m_key; std::string m_certificate; bool m_verify{false}; - /* Status */ - bool m_tcpconnected{false}; - + /* + * Construct with a context and ssl, for accept(). + */ Tls(Context context, Ssl ssl) : m_context{std::move(context)} , m_ssl{std::move(ssl)} @@ -2031,21 +2041,47 @@ } /** - * Construct a specific Tls object. + * Set the method. * - * @param method the method to use# - - * @param verify true to verify the certificate - * @param key the private key - * @param certificate the certificate file + * @param method the method + * @pre the socket must not be already created + */ + inline void setMethod(ssl::Method method) noexcept + { + assert(!m_context); + assert(!m_ssl); + + m_method = method; + } + + /** + * Use the specified private key file. + * + * @param file the path to the private key */ - Tls(Method method, bool verify = true, std::string key = "", std::string certificate = "") - : Tls() + inline void setPrivateKey(std::string file) noexcept + { + m_key = std::move(file); + } + + /** + * Use the specified certificate file. + * + * @param file the path to the file + */ + inline void setCertificate(std::string file) noexcept { - m_method = method; + m_certificate = std::move(file); + } + + /** + * Set to true if we must verify the certificate and private key. + * + * @param verify the mode + */ + inline void setVerify(bool verify = true) noexcept + { m_verify = verify; - m_key = std::move(key); - m_certificate = std::move(certificate); } /** @@ -2056,7 +2092,7 @@ template <typename Address> inline void create(Socket<Address, Tls> &sc) { - auto method = (m_method == Tlsv1) ? TLSv1_method() : SSLv3_method(); + auto method = (m_method == ssl::Tlsv1) ? TLSv1_method() : SSLv3_method(); m_context = {SSL_CTX_new(method), SSL_CTX_free}; m_ssl = {SSL_new(m_context.get()), SSL_free}; @@ -2080,6 +2116,7 @@ * * @param sc the socket * @param address the address + * @param length the address length * @throw Error on errors */ template <typename Address, typename Protocol> @@ -2119,6 +2156,7 @@ * * @param sc the socket * @param address the address destination + * @param length the address length * @return the client */ template <typename Address> @@ -2155,6 +2193,7 @@ /** * Receive some secure data. * + * @param sc the socket * @param data the destination * @param len the buffer length * @return the number of bytes read @@ -2181,6 +2220,7 @@ /** * Send some data. * + * @param sc the socket * @param data the data to send * @param len the buffer length * @return the number of bytes sent @@ -2851,6 +2891,9 @@ template <typename Address, typename Protocol> class StreamConnection { public: + /** + * Called when the output has changed. + */ using WriteHandler = Callback<>; private: @@ -2960,11 +3003,34 @@ template <typename Address, typename Protocol> class StreamServer { public: + /** + * Handler when a new client is connected. + */ using ConnectionHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &>; + + /** + * Handler when a client is disconnected. + */ using DisconnectionHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &>; + + /** + * Handler when data has been received from a client. + */ using ReadHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &, const std::string &>; + + /** + * Handler when data has been correctly sent to a client. + */ using WriteHandler = Callback<const std::shared_ptr<StreamConnection<Address, Protocol>> &, const std::string &>; + + /** + * Handler when an error occured. + */ using ErrorHandler = Callback<const Error &>; + + /** + * Handler when there was a timeout. + */ using TimeoutHandler = Callback<>; private: @@ -3148,10 +3214,11 @@ * Create a stream server with the specified address to bind. * * @param address the address to bind + * @param protocol the protocol * @param max the max number to listen * @throw Error on errors */ - StreamServer(const Address &address, Protocol type = {}, int max = 128) + StreamServer(const Address &address, Protocol protocol = {}, int max = 128) : m_master{address, std::move(type)} { // TODO: m_onError
--- a/C++/tests/Socket/main.cpp Wed Nov 04 20:36:07 2015 +0100 +++ b/C++/tests/Socket/main.cpp Wed Nov 04 20:53:36 2015 +0100 @@ -576,7 +576,7 @@ class TlsRecvTest : public testing::Test { protected: - SocketTls<Ipv4> m_server; + SocketTls<Ipv4> m_server{nullptr}; SocketTls<Ipv4> m_client; std::thread m_tserver; @@ -584,9 +584,14 @@ public: TlsRecvTest() - : m_server{Ipv4{}, Tls{Tls::Tlsv1, false, "Socket/test.key", "Socket/test.crt"}} - , m_client{Ipv4{}, Tls{Tls::Tlsv1, false}} { + Tls protocol; + + protocol.setCertificate("Socket/test.crt"); + protocol.setPrivateKey("Socket/test.key"); + protocol.setVerify(false); + + m_server = SocketTls<Ipv4>{std::move(protocol)}; m_server.set(SOL_SOCKET, SO_REUSEADDR, 1); m_server.bind(Ipv4{"*", 16000}); m_server.listen();