From 2bed28f702c8b328c367f785194d95a45ecd77a5 Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Wed, 5 Jul 2023 12:24:12 -0700 Subject: [PATCH] Limit number of server-initiated instant failovers followed by client Set the limit to 8 for now. This will prevent the client from getting stuck in redirect loops. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- libmariadb/mariadb_lib.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 6c9ffaaf7..93f34342a 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -85,6 +85,7 @@ #define MA_RPL_VERSION_HACK "5.5.5-" #define CHARSET_NAME_LEN 64 +#define INSTANT_FAILOVER_LIMIT 8 #undef max_allowed_packet #undef net_buffer_length @@ -1589,7 +1590,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, my_bool is_multi= 0; char *host_copy= NULL; struct st_host *host_list= NULL; - int connect_attempts= 0; + int connect_attempts= 0, instant_failovers=0; if (!mysql->methods) mysql->methods= &MARIADB_DEFAULT_METHODS; @@ -2002,6 +2003,13 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, /* Client has disabled instant failover. Fall through and treat this * as a "normal" error. */ } + else if (instant_failovers >= INSTANT_FAILOVER_LIMIT) + { + /* Too many instant failovers */ + my_set_error(mysql, ER_INSTANT_FAILOVER, SQLSTATE_UNKNOWN, + "Too many instant failovers (>= %d)", + INSTANT_FAILOVER_LIMIT); + } else { char *p= mysql->net.last_error; /* Should look like '|message|host[:port]' */ @@ -2020,6 +2028,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, port= 0; } fprintf(stderr, "Got instant failover to '%s' (port %d)\n", host, port); + ++instant_failovers; goto tcp_redirect; } }