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);
 		}
 	}