Mercurial > code
changeset 460:f6b4c7491d18
Socket: update Tls::connect stuff
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 03 Nov 2015 19:57:00 +0100 |
parents | 819bccefce8e |
children | 41d1a36cc461 |
files | C++/modules/Socket/Sockets.h |
diffstat | 1 files changed, 52 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Socket/Sockets.h Tue Nov 03 17:48:35 2015 +0100 +++ b/C++/modules/Socket/Sockets.h Tue Nov 03 19:57:00 2015 +0100 @@ -1621,6 +1621,9 @@ { } + /* + * Get the OpenSSL error message. + */ inline std::string error(int error) { auto msg = ERR_reason_error_string(error); @@ -1628,6 +1631,30 @@ return msg == nullptr ? "" : msg; } + /* + * Continue the connect operation. + */ + template <typename Address, typename Type> + void processConnect(Socket<Address, Type> &sc) + { + int ret = SSL_connect(m_ssl.get()); + + if (ret <= 0) { + int no = SSL_get_error(m_ssl.get(), ret); + + if (no == SSL_ERROR_WANT_READ) { + sc.setState(State::ConnectingRead); + } else if (no == SSL_ERROR_WANT_WRITE) { + sc.setState(State::ConnectingWrite); + } else { + throw Error{Error::System, "connect", error(no)}; + } + } else { + sc.setState(State::Connected); + } + + } + public: /** * @copydoc Tcp::type @@ -1701,32 +1728,32 @@ template <typename Address, typename Type> void connect(Socket<Address, Type> &sc, const sockaddr *address, socklen_t length) { - /* 1. Standard connect */ - if (!m_tcpconnected) { - Tcp::connect(sc, address, length); - - /* Standard connection is done */ + /* 1. Connect using raw TCP */ + Tcp::connect(sc, address, length); + + /* 2. If the connection is complete (e.g. non-blocking), try handshake */ + if (sc.state() == State::Connected) { m_tcpconnected = true; - - /* Reset because the TCP is connected but not OpenSSL */ - sc.setState(State::Connecting); - } else { - /* 2. OpenSSL handshake */ - auto ret = SSL_connect(m_ssl.get()); - - if (ret <= 0) { - auto no = SSL_get_error(m_ssl.get(), ret); - - if (no == SSL_ERROR_WANT_READ) { - throw Error{Error::WouldBlockRead, "connect", "Operation in progress"}; - } else if (no == SSL_ERROR_WANT_WRITE) { - throw Error{Error::WouldBlockWrite, "connect", "Operation in progress"}; - } else { - throw Error{Error::System, "connect", error(no)}; - } - } - - sc.setState(State::Connected); + processConnect(sc); + } + } + + /** + * Continue the connection. + * + * @param sc the socket + */ + template <typename Address, typename Type> + void connect(Socket<Address, Type> &sc) + { + /* 1. Be sure to complete standard connect before */ + if (!m_tcpconnected) { + Tcp::connect(sc); + m_tcpconnected = sc.state() == State::Connected; + } + + if (m_tcpconnected) { + processConnect(sc); } }