From 67fac0b761932bc39e502c5f741dce6fb2b8f984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Thu, 3 Nov 2022 13:25:32 +0100 Subject: [PATCH] Fix 'compression' integration with 'fast_forward' sessions - Compression flag is now propagated from client to backend connection when the backend connection is being created for a 'fast_forward' session. In case of client trying to connect without compression, to a server configured with compression, we fallback to an uncompressed connection. - After a 'MySQL_Session' has obtained a connection for a 'fast_forward' session, i.e, the one-to-one relationship between the client and backend connection has been stablished, we completely disable the compression 'STATUS_MYSQL_CONNECTION_COMPRESSION' flag from the client 'MySQL_Connection'. --- lib/MySQL_Session.cpp | 13 +++++++++++++ lib/mysql_connection.cpp | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 22e004dcc..cb4f8a5c2 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -2864,6 +2864,19 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) { myds->DSS=STATE_SLEEP; myds->myconn->send_quit = false; myds->myconn->reusable = false; + // In a 'fast_forward' session after we disable compression for the fronted connection + // after we have adquired a backend connection, this is, the 'FAST_FORWARD' session status + // is reached, and the 1-1 connection relationship is established. We can safely do this + // due two main reasons: + // 1. The client and backend have to agree on compression, i.e. if the client connected without + // compression using fast-forward to a backend connections expected to have compression, it results + // in a fallback to a connection without compression, as it's expected by protocol. In this case we do + // not require to compress the data received from the backend. + // 2. The client and backend have agreed in using compression, in this case, the data received from + // the backend is already compressed, so we are only required to forward the data to the client. + // In both cases, we do not require to perform any specials actions for the received data, + // so we completely disable the compression flag for the client connection. + client_myds->myconn->set_status(false, STATUS_MYSQL_CONNECTION_COMPRESSION); } NEXT_IMMEDIATE_NEW(st); break; diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 81646e719..1cfa6fb99 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -795,6 +795,15 @@ void MySQL_Connection::connect_start() { mysql->options.client_flag |= CLIENT_DEPRECATE_EOF; } } + // In case of 'fast_forward', we only enable compression if both, client and backend matches. Otherwise, + // we honor the behavior of a regular connection of when a connection doesn't agree on using compression + // during handshake, and we fallback to an uncompressed connection. + client_flags &= ~(CLIENT_COMPRESS); // we disable it by default + if (c->options.client_flag & CLIENT_COMPRESS) { + if (c->options.server_capabilities & CLIENT_COMPRESS) { + client_flags |= CLIENT_COMPRESS; + } + } } } }