From 6b311b7014567eada827f6c0476d149df103a6d7 Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Fri, 17 Apr 2026 15:51:32 +0000 Subject: [PATCH] Restore greeting upper-word caps via local 'extended_capabilities' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous commit (536c9d916) OR-ed the dropped upper-word bits into 'mysql_thread___server_capabilities', which made them leak into '(*myds)->myconn->options.server_capabilities' — a behaviour delta vs. pre-8c6a6444d. Revert that and reinstate the original pattern: a local 'extended_capabilities' whose only consumer is 'upper_word'. Seed it with the hardcoded baseline (CLIENT_MULTI_*, CLIENT_PLUGIN_AUTH, CLIENT_REMEMBER_OPTIONS) and fold in any other upper-word bits currently set in 'server_capabilities' (CLIENT_DEPRECATE_EOF, CLIENT_SESSION_TRACKING, CLIENT_ZSTD_COMPRESSION, ...) so the greeting stays in sync with the per-session / per-toggle state — preserving 8c6a6444d's zstd advertisement while restoring the #4023 baseline. --- lib/MySQL_Protocol.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index 0d9f41915..c8747fe38 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -1088,13 +1088,6 @@ bool MySQL_Protocol::generate_pkt_initial_handshake(bool send, void **ptr, unsig } mysql_thread___server_capabilities |= CLIENT_LONG_FLAG; mysql_thread___server_capabilities |= CLIENT_MYSQL | CLIENT_PLUGIN_AUTH | CLIENT_RESERVED; - // Upper-word capabilities that ProxySQL always advertises, matching real - // MySQL server greetings (see issue #4023). These were previously supplied - // via a separate 'extended_capabilities' local and were accidentally - // dropped during the zstd refactor in 8c6a6444d. - mysql_thread___server_capabilities |= - CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS | - CLIENT_PS_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS; if (mysql_thread___enable_client_deprecate_eof) { mysql_thread___server_capabilities |= CLIENT_DEPRECATE_EOF; } else { @@ -1125,8 +1118,21 @@ bool MySQL_Protocol::generate_pkt_initial_handshake(bool send, void **ptr, unsig uint8_t uint8_charset = ci->nr & 255; memcpy(_ptr+l,&uint8_charset, sizeof(uint8_charset)); l+=sizeof(uint8_charset); memcpy(_ptr+l,&server_status, sizeof(server_status)); l+=sizeof(server_status); - // Copy the upper 16 capability bits from the effective server capability mask. - uint16_t upper_word = static_cast(server_capabilities >> 16); + // Upper-word ('capability_flags_2') capabilities advertised in the greeting. + // Baseline bits match what real MySQL servers advertise (see issue #4023); + // they were accidentally dropped during the zstd refactor in 8c6a6444d. + // The remaining upper-word bits (CLIENT_DEPRECATE_EOF, CLIENT_SESSION_TRACKING, + // CLIENT_ZSTD_COMPRESSION, ...) are folded in from 'server_capabilities' so + // the greeting stays in sync with the per-session / per-toggle state. + // 'extended_capabilities' is intentionally a local: it must NOT leak into + // '(*myds)->myconn->options.server_capabilities' nor into the low-word + // memcpy above, which record the per-connection state rather than the full + // greeting. + uint32_t extended_capabilities = + CLIENT_MULTI_RESULTS | CLIENT_MULTI_STATEMENTS | CLIENT_PS_MULTI_RESULTS | + CLIENT_PLUGIN_AUTH | CLIENT_REMEMBER_OPTIONS; + extended_capabilities |= server_capabilities & 0xFFFF0000u; + uint16_t upper_word = static_cast(extended_capabilities >> 16); memcpy(_ptr+l, static_cast(&upper_word), sizeof(upper_word)); l += sizeof(upper_word); // Copy the 'auth_plugin_data_len'. Hardcoded due to 'CLIENT_PLUGIN_AUTH' always enabled and reported // as 'mysql_native_password'.