BUG/MEDIUM: ssl: Fix sometimes reneg fails if requested by server.

SSL_do_handshake is not appropriate for reneg, it's only appropriate at the
beginning of a connection. OpenSSL correctly handles renegs using the data
functions, so we use SSL_peek() here to make its state machine progress if
SSL_renegotiate_pending() says a reneg is pending.
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 8fec632..75f7b5d 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -855,6 +855,61 @@
 	if (!conn->xprt_ctx)
 		goto out_error;
 
+	/* If we use SSL_do_handshake to process a reneg initiated by
+	 * the remote peer, it sometimes returns SSL_ERROR_SSL.
+	 * Usually SSL_write and SSL_read are used and process implicitly
+	 * the reneg handshake.
+	 * Here we use SSL_peek as a workaround for reneg.
+	 */
+	if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
+		char c;
+
+		ret = SSL_peek(conn->xprt_ctx, &c, 1);
+		if (ret <= 0) {
+			/* handshake may have not been completed, let's find why */
+			ret = SSL_get_error(conn->xprt_ctx, ret);
+			if (ret == SSL_ERROR_WANT_WRITE) {
+				/* SSL handshake needs to write, L4 connection may not be ready */
+				__conn_sock_stop_recv(conn);
+				__conn_sock_poll_send(conn);
+				return 0;
+			}
+			else if (ret == SSL_ERROR_WANT_READ) {
+				/* handshake may have been completed but we have
+				 * no more data to read.
+                                 */
+				if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
+					ret = 1;
+					goto reneg_ok;
+				}
+				/* SSL handshake needs to read, L4 connection is ready */
+				if (conn->flags & CO_FL_WAIT_L4_CONN)
+					conn->flags &= ~CO_FL_WAIT_L4_CONN;
+				__conn_sock_stop_send(conn);
+				__conn_sock_poll_recv(conn);
+				return 0;
+			}
+			else if (ret == SSL_ERROR_SYSCALL) {
+				/* if errno is null, then connection was successfully established */
+				if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
+					conn->flags &= ~CO_FL_WAIT_L4_CONN;
+				goto out_error;
+			}
+			else {
+				/* Fail on all other handshake errors */
+				/* Note: OpenSSL may leave unread bytes in the socket's
+				 * buffer, causing an RST to be emitted upon close() on
+				 * TCP sockets. We first try to drain possibly pending
+				 * data to avoid this as much as possible.
+				 */
+				ret = recv(conn->t.sock.fd, trash.str, trash.size, MSG_NOSIGNAL|MSG_DONTWAIT);
+				goto out_error;
+			}
+		}
+		/* read some data: consider handshake completed */
+		goto reneg_ok;
+	}
+
 	ret = SSL_do_handshake(conn->xprt_ctx);
 	if (ret != 1) {
 		/* handshake did not complete, let's find why */
@@ -892,6 +947,8 @@
 		}
 	}
 
+reneg_ok:
+
 	/* Handshake succeeded */
 	if (objt_server(conn->target)) {
 		if (!SSL_session_reused(conn->xprt_ctx)) {