]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: ssl: Fix some reneg cases not correctly handled.
authorEmeric Brun <ebrun@exceliance.fr>
Thu, 8 Nov 2012 17:02:56 +0000 (18:02 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 12 Nov 2012 10:43:05 +0000 (11:43 +0100)
SSL may decide to switch to a handshake in the middle of a transfer due to
a reneg. In this case we don't want to re-enable polling because data might
have been left pending in the buffer. We just want to switch immediately to
the handshake mode.

src/ssl_sock.c

index 2fba79b9d09fbc92beb35c4dffce62498f6f068c..8fec632ba6887a051ed825f10234aa263b6fd327 100644 (file)
@@ -984,6 +984,12 @@ static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
                                break;
                        }
                        else if (ret == SSL_ERROR_WANT_READ) {
+                               if (SSL_renegotiate_pending(conn->xprt_ctx)) {
+                                       /* handshake is running, and it may need to re-enable read */
+                                       conn->flags |= CO_FL_SSL_WAIT_HS;
+                                       __conn_sock_want_recv(conn);
+                                       break;
+                               }
                                /* we need to poll for retry a read later */
                                __conn_data_poll_recv(conn);
                                break;
@@ -1056,6 +1062,12 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
                else {
                        ret = SSL_get_error(conn->xprt_ctx, ret);
                        if (ret == SSL_ERROR_WANT_WRITE) {
+                               if (SSL_renegotiate_pending(conn->xprt_ctx)) {
+                                       /* handshake is running, and it may need to re-enable write */
+                                       conn->flags |= CO_FL_SSL_WAIT_HS;
+                                       __conn_sock_want_send(conn);
+                                       break;
+                               }
                                /* we need to poll to retry a write later */
                                __conn_data_poll_send(conn);
                                break;