feat: add mysql resolution_family setting

Agent-Logs-Url: https://github.com/sysown/proxysql/sessions/7d0ebed6-886c-4e06-add5-d74b44eced4a

Co-authored-by: renecannao <3645227+renecannao@users.noreply.github.com>
pull/5554/head
copilot-swe-agent[bot] 3 weeks ago
parent 3f1c17778c
commit 4a93861c6c

@ -0,0 +1,34 @@
#ifndef MYSQL_RESOLUTION_H
#define MYSQL_RESOLUTION_H
#include <strings.h>
#include <sys/socket.h>
inline bool mysql_resolution_family_is_valid(const char* value) {
return value &&
(strcasecmp(value, "system") == 0 ||
strcasecmp(value, "ipv4") == 0 ||
strcasecmp(value, "ipv6") == 0);
}
inline const char* mysql_resolution_family_normalize(const char* value) {
if (value && strcasecmp(value, "ipv4") == 0) {
return "ipv4";
}
if (value && strcasecmp(value, "ipv6") == 0) {
return "ipv6";
}
return "system";
}
inline int mysql_resolution_family_to_ai_family(const char* value) {
if (value && strcasecmp(value, "ipv4") == 0) {
return AF_INET;
}
if (value && strcasecmp(value, "ipv6") == 0) {
return AF_INET6;
}
return AF_UNSPEC;
}
#endif // MYSQL_RESOLUTION_H

@ -437,6 +437,7 @@ class MySQL_Threads_Handler
int monitor_local_dns_cache_ttl;
int monitor_local_dns_cache_refresh_interval;
int monitor_local_dns_resolver_queue_maxsize;
char *resolution_family;
char *monitor_username;
char *monitor_password;
char * monitor_replication_lag_use_percona_heartbeat;

@ -26,6 +26,7 @@ using json = nlohmann::json;
#include "ProxySQL_Cluster.hpp"
#include "proxysql.h"
#include "cpp.h"
#include "MySQL_Resolution.h"
#include "proxysql_utils.h"
#include "thread.h"
@ -4673,17 +4674,21 @@ void* monitor_dns_resolver_thread(const std::vector<DNS_Resolve_Data*>& dns_reso
/* set hints for getaddrinfo */
memset(&hints, 0, sizeof(hints));
hints.ai_protocol = IPPROTO_TCP;
hints.ai_family = AF_UNSPEC; /*includes: IPv4, IPv6*/
hints.ai_socktype = SOCK_STREAM;
/* AI_ADDRCONFIG: IPv4 addresses are returned in the list pointed to by res only if the
local system has at least one IPv4 address configured, and IPv6
addresses are returned only if the local system has at least one
IPv6 address configured. The loopback address is not considered
for this case as valid as a configured address. This flag is
useful on, for example, IPv4-only systems, to ensure that
getaddrinfo() does not return IPv6 socket addresses that would
always fail in connect or bind. */
useful on, for example, IPv4-only systems, to ensure that
getaddrinfo() does not return IPv6 socket addresses that would
always fail in connect or bind. */
hints.ai_flags = AI_ADDRCONFIG;
char* resolution_family = GloMTH ? GloMTH->get_variable_string((char *)"resolution_family") : NULL;
hints.ai_family = mysql_resolution_family_to_ai_family(resolution_family); /*includes: IPv4, IPv6*/
if (resolution_family) {
free(resolution_family);
}
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Resolving hostname:[%s] to its mapped IP address.\n", dns_resolve_data->hostname.c_str());
int gai_rc = getaddrinfo(dns_resolve_data->hostname.c_str(), NULL, &hints, &res);

@ -27,6 +27,7 @@ using json = nlohmann::json;
#include "StatCounters.h"
#include "MySQL_PreparedStatement.h"
#include "MySQL_Logger.hpp"
#include "MySQL_Resolution.h"
#include <fcntl.h>
@ -421,6 +422,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"monitor_local_dns_cache_ttl",
(char *)"monitor_local_dns_cache_refresh_interval",
(char *)"monitor_local_dns_resolver_queue_maxsize",
(char *)"resolution_family",
(char *)"monitor_wait_timeout",
(char *)"monitor_writer_is_also_reader",
(char *)"max_allowed_packet",
@ -1303,6 +1305,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.monitor_local_dns_cache_ttl = 300000;
variables.monitor_local_dns_cache_refresh_interval = 60000;
variables.monitor_local_dns_resolver_queue_maxsize = 128;
variables.resolution_family=strdup((char *)"system");
variables.monitor_username=strdup((char *)"monitor");
variables.monitor_password=strdup((char *)"monitor");
variables.monitor_replication_lag_use_percona_heartbeat=strdup((char *)"");
@ -1668,6 +1671,7 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) {
if (!strcmp(name,"eventslog_filename")) return strdup(variables.eventslog_filename);
if (!strcmp(name,"auditlog_filename")) return strdup(variables.auditlog_filename);
if (!strcmp(name,"interfaces")) return strdup(variables.interfaces);
if (!strcmp(name,"resolution_family")) return strdup(variables.resolution_family);
if (!strcmp(name,"keep_multiplexing_variables")) return strdup(variables.keep_multiplexing_variables);
if (!strcmp(name,"default_authentication_plugin")) return strdup(variables.default_authentication_plugin);
if (!strcmp(name,"proxy_protocol_networks")) return strdup(variables.proxy_protocol_networks);
@ -1825,6 +1829,7 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
if (!strcasecmp(name,"auditlog_filename")) return strdup(variables.auditlog_filename);
if (!strcasecmp(name,"eventslog_filename")) return strdup(variables.eventslog_filename);
if (!strcasecmp(name,"default_schema")) return strdup(variables.default_schema);
if (!strcasecmp(name,"resolution_family")) return strdup(variables.resolution_family);
if (!strcasecmp(name,"keep_multiplexing_variables")) return strdup(variables.keep_multiplexing_variables);
if (!strcasecmp(name,"default_authentication_plugin")) return strdup(variables.default_authentication_plugin);
if (!strcasecmp(name,"proxy_protocol_networks")) return strdup(variables.proxy_protocol_networks);
@ -2261,6 +2266,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi
return false;
}
}
if (!strcasecmp(name,"resolution_family")) {
if (mysql_resolution_family_is_valid(value)) {
free(variables.resolution_family);
variables.resolution_family=strdup(mysql_resolution_family_normalize(value));
return true;
}
proxy_error("%s is an invalid value for %s. Supported values are system, ipv4, ipv6\n", value, name);
return false;
}
if (!strcasecmp(name,"proxy_protocol_networks")) {
bool ret = false;
if (vallen == 0) {
@ -3108,6 +3122,7 @@ MySQL_Threads_Handler::~MySQL_Threads_Handler() {
free(variables.monitor_replication_lag_use_percona_heartbeat);
variables.monitor_replication_lag_use_percona_heartbeat=NULL;
}
if (variables.resolution_family) { free(variables.resolution_family); variables.resolution_family=NULL; }
if (variables.default_schema) free(variables.default_schema);
if (variables.interfaces) free(variables.interfaces);
if (variables.server_version) free(variables.server_version);

@ -259,6 +259,7 @@ UNIT_TESTS := smoke_test-t query_cache_unit-t query_processor_unit-t \
mysql_error_classifier_unit-t \
backend_sync_unit-t \
mysql_encode_unit-t \
mysql_resolution_unit-t \
pgsql_variables_validator_unit-t \
proxysql_utils_unit-t \
gen_utils_unit-t \
@ -312,6 +313,11 @@ ezoption_parser_unit-t: ezoption_parser_unit-t.cpp $(ODIR)/tap.o $(ODIR)/tap_noi
-I$(TAP_IDIR) -I$(PROXYSQL_PATH)/include \
$(STDCPP) -O0 -ggdb $(WGCOV) $(LWGCOV) -lpthread -o $@
mysql_resolution_unit-t: mysql_resolution_unit-t.cpp $(ODIR)/tap.o $(ODIR)/tap_noise_stubs.o
$(CXX) $< $(ODIR)/tap.o $(ODIR)/tap_noise_stubs.o \
-I$(TAP_IDIR) -I$(PROXYSQL_PATH)/include \
$(STDCPP) -O0 -ggdb $(WGCOV) $(LWGCOV) -lpthread -o $@
# Pattern rule: all unit tests use the same compile + link flags.
# Each test binary is built from its .cpp source, linked against
# the test harness objects and libproxysql.a with all dependencies.

@ -0,0 +1,23 @@
#include "tap.h"
#include <cstring>
#include "MySQL_Resolution.h"
int main() {
plan(9);
ok(mysql_resolution_family_is_valid("system"), "system is accepted");
ok(mysql_resolution_family_is_valid("ipv4"), "ipv4 is accepted");
ok(mysql_resolution_family_is_valid("ipv6"), "ipv6 is accepted");
ok(!mysql_resolution_family_is_valid("invalid"), "invalid value is rejected");
ok(strcmp(mysql_resolution_family_normalize("IPv4"), "ipv4") == 0, "ipv4 values are normalized");
ok(strcmp(mysql_resolution_family_normalize("IPv6"), "ipv6") == 0, "ipv6 values are normalized");
ok(strcmp(mysql_resolution_family_normalize("SYSTEM"), "system") == 0, "system values are normalized");
ok(mysql_resolution_family_to_ai_family("ipv4") == AF_INET, "ipv4 maps to AF_INET");
ok(mysql_resolution_family_to_ai_family("invalid") == AF_UNSPEC, "invalid values fall back to AF_UNSPEC");
return exit_status();
}
Loading…
Cancel
Save