From b2549127ee86abb3c32d868fffda04df3f9743c2 Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Thu, 15 Feb 2024 12:37:53 +0500 Subject: [PATCH] Resolving node's hostname in the event of a connection error and when executing the "LOAD PROXYSQL SERVERS TO RUNTIME" command --- include/ProxySQL_Cluster.hpp | 47 +++----------------- lib/ProxySQL_Cluster.cpp | 85 ++++++++++++++++++++++++++++++------ 2 files changed, 78 insertions(+), 54 deletions(-) diff --git a/include/ProxySQL_Cluster.hpp b/include/ProxySQL_Cluster.hpp index 75e2eed0e5..23150c1de9 100644 --- a/include/ProxySQL_Cluster.hpp +++ b/include/ProxySQL_Cluster.hpp @@ -96,47 +96,11 @@ class ProxySQL_Node_Address { char *hostname; char *admin_mysql_ifaces; uint16_t port; - ProxySQL_Node_Address(char *h, uint16_t p) : ProxySQL_Node_Address(h, p, NULL) { - // resolving DNS if available in Cache - if (h && p) { - size_t ip_count = 0; - const std::string& ip = MySQL_Monitor::dns_lookup(h, false, &ip_count); - - if (ip_count > 1) { - proxy_error("Proxy cluster node '%s' has more than one ('%ld') mapped IP address. It is recommended to provide IP address or domain with one resolvable IP address.\n", - h, ip_count); - } - - if (ip.empty() == false) { - ip_addr = strdup(ip.c_str()); - } - } - } - ProxySQL_Node_Address(char* h, uint16_t p, char* ip) { - hostname = strdup(h); - ip_addr = NULL; - if (ip) { - ip_addr = strdup(ip); - } - admin_mysql_ifaces = NULL; - port = p; - uuid = NULL; - hash = 0; - } - ~ProxySQL_Node_Address() { - if (hostname) free(hostname); - if (uuid) free(uuid); - if (admin_mysql_ifaces) free(admin_mysql_ifaces); - if (ip_addr) free(ip_addr); - } - const char* get_host_address() const { - const char* host_address = hostname; - - if (ip_addr) - host_address = ip_addr; - - return host_address; - } + ProxySQL_Node_Address(char* h, uint16_t p); + ProxySQL_Node_Address(char* h, uint16_t p, char* ip); + ~ProxySQL_Node_Address(); + const char* get_host_address() const; + void resolve_hostname(); private: char* ip_addr; }; @@ -163,6 +127,7 @@ class ProxySQL_Node_Entry { ProxySQL_Node_Entry(char *_hostname, uint16_t _port, uint64_t _weight, char *_comment); ProxySQL_Node_Entry(char* _hostname, uint16_t _port, uint64_t _weight, char* _comment, char* ip); ~ProxySQL_Node_Entry(); + void resolve_hostname(); bool get_active(); void set_active(bool a); uint64_t get_weight(); diff --git a/lib/ProxySQL_Cluster.cpp b/lib/ProxySQL_Cluster.cpp index d06ee5114a..a093bec952 100644 --- a/lib/ProxySQL_Cluster.cpp +++ b/lib/ProxySQL_Cluster.cpp @@ -271,6 +271,7 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) { } } else { proxy_warning("Cluster: unable to connect to peer %s:%d . Error: %s\n", node->hostname, node->port, mysql_error(conn)); + node->resolve_hostname(); mysql_close(conn); conn = mysql_init(NULL); int ci = __sync_fetch_and_add(&GloProxyCluster->cluster_check_interval_ms,0); @@ -317,19 +318,7 @@ void ProxySQL_Node_Metrics::reset() { ProxySQL_Node_Entry::ProxySQL_Node_Entry(char *_hostname, uint16_t _port, uint64_t _weight, char * _comment) : ProxySQL_Node_Entry(_hostname, _port, _weight, _comment, NULL) { // resolving DNS if available in Cache - if (_hostname && _port) { - size_t ip_count = 0; - const std::string& ip = MySQL_Monitor::dns_lookup(_hostname, false, &ip_count); - - if (ip_count > 1) { - proxy_warning("ProxySQL Cluster node '%s' has more than one (%ld) mapped IP address: under some circumstances this may lead to undefined behavior. It is recommended to provide IP address or hostname with only one resolvable IP.\n", - _hostname, ip_count); - } - - if (ip.empty() == false) { - ip_addr = strdup(ip.c_str()); - } - } + resolve_hostname(); } ProxySQL_Node_Entry::ProxySQL_Node_Entry(char* _hostname, uint16_t _port, uint64_t _weight, char* _comment, char* ip) { @@ -384,6 +373,26 @@ ProxySQL_Node_Entry::~ProxySQL_Node_Entry() { metrics = NULL; } +void ProxySQL_Node_Entry::resolve_hostname() { + if (ip_addr) { + free(ip_addr); + ip_addr = NULL; + } + if (hostname && port) { + size_t ip_count = 0; + const std::string& ip = MySQL_Monitor::dns_lookup(hostname, false, &ip_count); + + if (ip_count > 1) { + proxy_warning("ProxySQL Cluster node '%s' has more than one (%ld) mapped IP address: under some circumstances this may lead to undefined behavior. It is recommended to provide IP address or hostname with only one resolvable IP.\n", + hostname, ip_count); + } + + if (ip.empty() == false) { + ip_addr = strdup(ip.c_str()); + } + } +} + bool ProxySQL_Node_Entry::get_active() { return active; } @@ -2922,6 +2931,7 @@ void ProxySQL_Cluster_Nodes::load_servers_list(SQLite3_result *resultset, bool _ //pthread_detach(a->thrid); } else { node = ite->second; + node->resolve_hostname(); node->set_active(true); node->set_weight(w_); node->set_comment(c_); @@ -4404,3 +4414,52 @@ void ProxySQL_Cluster::join_term_thread() { } pthread_mutex_unlock(&mutex); } + +ProxySQL_Node_Address::ProxySQL_Node_Address(char* h, uint16_t p) : ProxySQL_Node_Address(h, p, NULL) { + // resolving DNS if available in Cache + resolve_hostname(); +} +ProxySQL_Node_Address::ProxySQL_Node_Address(char* h, uint16_t p, char* ip) { + hostname = strdup(h); + ip_addr = NULL; + if (ip) { + ip_addr = strdup(ip); + } + admin_mysql_ifaces = NULL; + port = p; + uuid = NULL; + hash = 0; +} +ProxySQL_Node_Address::~ProxySQL_Node_Address() { + if (hostname) free(hostname); + if (uuid) free(uuid); + if (admin_mysql_ifaces) free(admin_mysql_ifaces); + if (ip_addr) free(ip_addr); +} +const char* ProxySQL_Node_Address::get_host_address() const { + const char* host_address = hostname; + + if (ip_addr) + host_address = ip_addr; + + return host_address; +} +void ProxySQL_Node_Address::resolve_hostname() { + if (ip_addr) { + free(ip_addr); + ip_addr = NULL; + } + if (hostname && port) { + size_t ip_count = 0; + const std::string& ip = MySQL_Monitor::dns_lookup(hostname, false, &ip_count); + + if (ip_count > 1) { + proxy_warning("ProxySQL Cluster node '%s' has more than one (%ld) mapped IP address: under some circumstances this may lead to undefined behavior. It is recommended to provide IP address or hostname with only one resolvable IP.\n", + hostname, ip_count); + } + + if (ip.empty() == false) { + ip_addr = strdup(ip.c_str()); + } + } +}