Closes #3280: Add support to control 'CLIENT_DEPRECATE_EOF' in client and backend connections through global variables

pull/3281/head
Javier Jaramago Fernández 5 years ago
parent 420913f0a1
commit 1ee832affd

@ -12,7 +12,7 @@ index 62cf71c..c05e9a3 100644
COM_MULTI_OFF= 0,
COM_MULTI_CANCEL,
diff --git include/mariadb_com.h include/mariadb_com.h
index 7e722a0..3d89fdf 100644
index 7e722a0..dc121c7 100644
--- include/mariadb_com.h
+++ include/mariadb_com.h
@@ -160,6 +160,7 @@ enum enum_server_command
@ -23,22 +23,21 @@ index 7e722a0..3d89fdf 100644
#define CLIENT_PROGRESS (1UL << 29) /* client supports progress indicator */
#define CLIENT_PROGRESS_OBSOLETE CLIENT_PROGRESS
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
@@ -204,6 +205,7 @@ enum enum_server_command
@@ -204,8 +205,14 @@ enum enum_server_command
CLIENT_REMEMBER_OPTIONS |\
CLIENT_PLUGIN_AUTH |\
CLIENT_SESSION_TRACKING |\
+ CLIENT_DEPRECATE_EOF |\
CLIENT_CONNECT_ATTRS)
+/* Client capabilities *does no* longer holds 'CLIENT_DEPRECATE_EOF' flag
+ * by default. This is part of ProxySQL feature for conditionally disabling
+ * 'deprecate_eof' support in both client and backend connections. For more
+ * context see #3280.
+ */
#define CLIENT_CAPABILITIES (CLIENT_MYSQL | \
@@ -215,6 +217,7 @@ enum enum_server_command
CLIENT_PROTOCOL_41 |\
CLIENT_PLUGIN_AUTH |\
CLIENT_SESSION_TRACKING |\
+ CLIENT_DEPRECATE_EOF |\
CLIENT_CONNECT_ATTRS)
#define CLIENT_DEFAULT_FLAGS ((CLIENT_SUPPORTED_FLAGS & ~CLIENT_COMPRESS)\
CLIENT_LONG_FLAG |\
CLIENT_TRANSACTIONS |\
diff --git include/mariadb_stmt.h include/mariadb_stmt.h
index d07540e..4930573 100644
--- include/mariadb_stmt.h
@ -66,7 +65,7 @@ index 15be4fc..a69e637 100644
See bug conc-57
*/
diff --git libmariadb/mariadb_lib.c libmariadb/mariadb_lib.c
index 8c2a99b..249e981 100644
index 8c2a99b..e849b76 100644
--- libmariadb/mariadb_lib.c
+++ libmariadb/mariadb_lib.c
@@ -144,6 +144,7 @@ struct st_mariadb_methods MARIADB_DEFAULT_METHODS;
@ -490,7 +489,24 @@ index 8c2a99b..249e981 100644
{
if (mysql->net.last_errno == CR_SERVER_LOST)
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
@@ -2290,14 +2446,13 @@ int mthd_my_read_query_result(MYSQL *mysql)
@@ -1593,6 +1749,16 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
}
}
+ /* If client flags doesn't have 'deprecate_eof' we forcely disable the server capability,
+ * This, in combination with the capability flag 'CLIENT_DEPRECATE_EOF' being disabled by default,
+ * completely disables the library support for CLIENT_DEPRECATE_EOF. This two changes were introduced
+ * as part of ProxySQL capability for controlling 'deprecate_eof' support in both client and
+ * backend connections. For more context see: #3280.
+ */
+ if ((mysql->options.client_flag & CLIENT_DEPRECATE_EOF) == 0) {
+ mysql->server_capabilities &= ~CLIENT_DEPRECATE_EOF;
+ }
+
/* pad 2 */
end+= 18;
@@ -2290,14 +2456,13 @@ int mthd_my_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
@ -506,7 +522,7 @@ index 8c2a99b..249e981 100644
{
return(1);
}
@@ -2310,7 +2465,7 @@ get_info:
@@ -2310,7 +2475,7 @@ get_info:
{
int error=mysql_handle_local_infile(mysql, (char *)pos, can_local_infile);
@ -515,7 +531,7 @@ index 8c2a99b..249e981 100644
return(-1);
goto get_info; /* Get info packet */
}
@@ -2318,12 +2473,13 @@ get_info:
@@ -2318,12 +2483,13 @@ get_info:
mysql->server_status|= SERVER_STATUS_IN_TRANS;
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
@ -535,7 +551,7 @@ index 8c2a99b..249e981 100644
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
return(0);
@@ -2704,21 +2860,17 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
@@ -2704,21 +2870,17 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
MYSQL_RES * STDCALL
mysql_list_processes(MYSQL *mysql)
{
@ -560,7 +576,7 @@ index 8c2a99b..249e981 100644
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
return(mysql_store_result(mysql));
@@ -4164,7 +4316,7 @@ mysql_debug(const char *debug __attribute__((unused)))
@@ -4164,7 +4326,7 @@ mysql_debug(const char *debug __attribute__((unused)))
*********************************************************************/
ulong STDCALL mysql_net_read_packet(MYSQL *mysql)
{

@ -513,6 +513,8 @@ class MySQL_Threads_Handler
bool query_cache_stores_empty_result;
bool kill_backend_connection_when_disconnect;
bool client_session_track_gtid;
bool enable_client_deprecate_eof;
bool enable_server_deprecate_eof;
} variables;
struct {
unsigned int mirror_sessions_current;

@ -765,6 +765,8 @@ __thread bool mysql_thread___kill_backend_connection_when_disconnect;
__thread bool mysql_thread___client_session_track_gtid;
__thread char * mysql_thread___default_variables[SQL_NAME_LAST];
__thread int mysql_thread___query_digests_grouping_limit;
__thread bool mysql_thread___enable_client_deprecate_eof;
__thread bool mysql_thread___enable_server_deprecate_eof;
/* variables used for Query Cache */
__thread int mysql_thread___query_cache_size_MB;
@ -914,6 +916,8 @@ extern __thread bool mysql_thread___kill_backend_connection_when_disconnect;
extern __thread bool mysql_thread___client_session_track_gtid;
extern __thread char * mysql_thread___default_variables[SQL_NAME_LAST];
extern __thread int mysql_thread___query_digests_grouping_limit;
extern __thread bool mysql_thread___enable_client_deprecate_eof;
extern __thread bool mysql_thread___enable_server_deprecate_eof;
/* variables used for Query Cache */
extern __thread int mysql_thread___query_cache_size_MB;

@ -1373,7 +1373,12 @@ 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);
if (deprecate_eof_active) {
// we conditionally reply the client specifying in 'server_capabilities' that
// 'CLIENT_DEPRECATE_EOF' is available if explicitly enabled by 'mysql-enable_client_deprecate_eof'
// variable. This is the first step of ensuring that client connections doesn't
// enable 'CLIENT_DEPRECATE_EOF' unless explicitly stated by 'mysql-enable_client_deprecate_eof'.
// Second step occurs during client handshake response (process_pkt_handshake_response).
if (deprecate_eof_active && mysql_thread___enable_client_deprecate_eof) {
memcpy(_ptr+l,"\x8f\x81\x15",3); l+=3;
}
else {
@ -1714,6 +1719,18 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned
if (capabilities & CLIENT_MULTI_STATEMENTS) {
capabilities |= CLIENT_MULTI_RESULTS;
}
// we enforce disabling 'CLIENT_DEPRECATE_EOF' from the supported capabilities
// in case it's explicitly disabled by global variable 'mysql_thread___enable_client_deprecate_eof'.
// This is because further checks to actually threat the connection as a connection
// supporting 'CLIENT_DEPRECATE_EOF' rely in 'client_flag' field from
// 'MySQL_Connection::options'.
// This is the second step for ensuring that the connection is being handling
// in both ProxySQL and client side as a connection without 'CLIENT_DEPRECATE_EOF' support.
// First step is replying to client during initial handshake (in 'generate_pkt_initial_handshake')
// specifying no 'CLIENT_DEPRECATE_EOF' support in 'server_capabilities'.
if (!mysql_thread___enable_client_deprecate_eof) {
capabilities &= ~CLIENT_DEPRECATE_EOF;
}
(*myds)->myconn->options.client_flag = capabilities;
pkt += sizeof(uint32_t);
max_pkt = CPY4(pkt);

@ -990,6 +990,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) {
j["conn"]["client_flag"]["client_found_rows"] = (client_myds->myconn->options.client_flag & CLIENT_FOUND_ROWS ? 1 : 0);
j["conn"]["client_flag"]["client_multi_statements"] = (client_myds->myconn->options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0);
j["conn"]["client_flag"]["client_multi_results"] = (client_myds->myconn->options.client_flag & CLIENT_MULTI_RESULTS ? 1 : 0);
j["conn"]["client_flag"]["client_deprecate_eof"] = (client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF ? 1 : 0);
j["conn"]["no_backslash_escapes"] = client_myds->myconn->options.no_backslash_escapes;
j["conn"]["status"]["compression"] = client_myds->myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION);
j["conn"]["status"]["transaction"] = client_myds->myconn->get_status(STATUS_MYSQL_CONNECTION_TRANSACTION);
@ -1049,6 +1050,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) {
j["backends"][i]["conn"]["client_flag"]["value"] = _myconn->options.client_flag;
j["backends"][i]["conn"]["client_flag"]["client_found_rows"] = (_myconn->options.client_flag & CLIENT_FOUND_ROWS ? 1 : 0);
j["backends"][i]["conn"]["client_flag"]["client_multi_statements"] = (_myconn->options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0);
j["backends"][i]["conn"]["client_flag"]["client_deprecate_eof"] = (_myconn->options.client_flag & CLIENT_DEPRECATE_EOF ? 1 : 0);
if (_myconn->mysql && _myconn->ret_mysql) {
MYSQL * _my = _myconn->mysql;
sprintf(buff,"%p",_my);

@ -420,6 +420,8 @@ static char * mysql_thread_variables_names[]= {
(char *)"connect_timeout_client",
(char *)"connect_timeout_server",
(char *)"connect_timeout_server_max",
(char *)"enable_client_deprecate_eof",
(char *)"enable_server_deprecate_eof",
(char *)"eventslog_filename",
(char *)"eventslog_filesize",
(char *)"eventslog_default_log",
@ -1156,6 +1158,8 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.session_debug=true;
#endif /*debug */
variables.query_digests_grouping_limit = 3;
variables.enable_client_deprecate_eof=true;
variables.enable_server_deprecate_eof=true;
// status variables
status_variables.mirror_sessions_current=0;
__global_MySQL_Thread_Variables_version=1;
@ -1461,6 +1465,8 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
if (!strcmp(name,"eventslog_default_log")) return (int)variables.eventslog_default_log;
if (!strcmp(name,"eventslog_filesize")) return (int)variables.eventslog_filesize;
if (!strcmp(name,"eventslog_format")) return (int)variables.eventslog_format;
if (!strcmp(name,"enable_client_deprecate_eof")) return (int)variables.enable_client_deprecate_eof;
if (!strcmp(name,"enable_server_deprecate_eof")) return (int)variables.enable_server_deprecate_eof;
break;
case 'f':
if (!strcmp(name,"forward_autocommit")) return (int)variables.forward_autocommit;
@ -1890,7 +1896,12 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
sprintf(intbuf,"%d",variables.automatic_detect_sqli);
return strdup(intbuf);
}
if (!strcasecmp(name,"enable_client_deprecate_eof")) {
return strdup((variables.enable_client_deprecate_eof ? "true" : "false"));
}
if (!strcasecmp(name,"enable_server_deprecate_eof")) {
return strdup((variables.enable_server_deprecate_eof ? "true" : "false"));
}
if (!strcasecmp(name,"throttle_connections_per_sec_to_hostgroup")) {
sprintf(intbuf,"%d",variables.throttle_connections_per_sec_to_hostgroup);
return strdup(intbuf);
@ -3035,7 +3046,28 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi
}
return false; // we couldn't set it to a valid value. It will be reset to default
}
if (!strcasecmp(name,"enable_client_deprecate_eof")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.enable_client_deprecate_eof=true;
return true;
}
if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) {
variables.enable_client_deprecate_eof=false;
return true;
}
return false;
}
if (!strcasecmp(name,"enable_server_deprecate_eof")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.enable_server_deprecate_eof=true;
return true;
}
if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) {
variables.enable_server_deprecate_eof=false;
return true;
}
return false;
}
if (!strncmp(name,"default_",8)) {
for (int i=0; i<SQL_NAME_LAST; i++) {
@ -5062,6 +5094,8 @@ void MySQL_Thread::refresh_variables() {
mysql_thread___show_processlist_extended=GloMTH->get_variable_int((char *)"show_processlist_extended");
mysql_thread___servers_stats=(bool)GloMTH->get_variable_int((char *)"servers_stats");
mysql_thread___default_reconnect=(bool)GloMTH->get_variable_int((char *)"default_reconnect");
mysql_thread___enable_client_deprecate_eof=(bool)GloMTH->get_variable_int((char *)"enable_client_deprecate_eof");
mysql_thread___enable_server_deprecate_eof=(bool)GloMTH->get_variable_int((char *)"enable_server_deprecate_eof");
#ifdef DEBUG
mysql_thread___session_debug=(bool)GloMTH->get_variable_int((char *)"session_debug");
#endif /* DEBUG */

@ -605,6 +605,13 @@ void MySQL_Connection::connect_start() {
}
}
// set 'CLIENT_DEPRECATE_EOF' flag if explicitly stated by 'mysql-enable_server_deprecate_eof'.
// Capability is disabled by default in 'mariadb_client', so setting this option is not optional
// for having 'CLIENT_DEPRECATE_EOF' in the connection to be stablished.
if (mysql_thread___enable_server_deprecate_eof) {
mysql->options.client_flag |= CLIENT_DEPRECATE_EOF;
}
char *auth_password=NULL;
if (userinfo->password) {
if (userinfo->password[0]=='*') { // we don't have the real password, let's pass sha1

Loading…
Cancel
Save