Improve logging in unexpected COM_PING packet handling

Logging messages now include 'client address', 'session status' and
'data stream status'. Client address is also logged when OK packets are
dispatched, this should help tracking if a client has received the
expected packets or not.
v3.0-handle_unexp_ping
Javier Jaramago Fernández 2 months ago
parent 503b0975c6
commit 6fea828e86

@ -332,4 +332,14 @@ static inline void set_thread_name(const char(&name)[LEN], const bool en = true)
#endif
}
/**
* @brief Gets the client address stored in 'client_addr' member as
* an string if available. If member 'client_addr' is NULL, returns an
* empty string.
*
* @return Either an string holding the string representation of internal
* member 'client_addr', or empty string if this member is NULL.
*/
std::string get_client_addr(struct sockaddr* client_addr);
#endif

@ -7784,15 +7784,24 @@ void MySQL_Session::RequestEnd(MySQL_Data_Stream *myds,const unsigned int myerrn
if (client_myds->unexp_com_pings) {
client_myds->setDSS_STATE_QUERY_SENT_NET();
while (client_myds->unexp_com_pings) {
proxy_warning("Sending OK packet for unexpected COM_PING packet\n");
if (client_myds->unexp_com_pings) {
const string cli_addr { get_client_addr(this->client_myds->client_addr) };
client_myds->pkt_sid += 1;
uint16_t st = NumActiveTransactions() ? SERVER_STATUS_IN_TRANS : 0;
if (autocommit) { st |= SERVER_STATUS_AUTOCOMMIT; }
while (client_myds->unexp_com_pings) {
proxy_warning(
"Sending OK packet for unexpected COM_PING packet client_addr=\"%s\"\n",
cli_addr.c_str()
);
client_myds->pkt_sid += 1;
uint16_t st = NumActiveTransactions() ? SERVER_STATUS_IN_TRANS : 0;
if (autocommit) { st |= SERVER_STATUS_AUTOCOMMIT; }
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, client_myds->pkt_sid, 0, 0, st, 0, NULL);
client_myds->unexp_com_pings--;
client_myds->myprot.generate_pkt_OK(
true, NULL, NULL, client_myds->pkt_sid, 0, 0, st, 0, NULL
);
client_myds->unexp_com_pings--;
}
}
client_myds->DSS = STATE_SLEEP;

@ -7,6 +7,7 @@ using json = nlohmann::json;
#include <functional>
#include <vector>
#include "proxysql_utils.h"
#include "MySQL_HostGroups_Manager.h"
#include "prometheus_helpers.h"
#define MYSQL_THREAD_IMPLEMENTATION
@ -2584,43 +2585,6 @@ void MySQL_Threads_Handler::stop_listeners() {
free_tokenizer( &tok );
}
/**
* @brief Gets the client address stored in 'client_addr' member as
* an string if available. If member 'client_addr' is NULL, returns an
* empty string.
*
* @return Either an string holding the string representation of internal
* member 'client_addr', or empty string if this member is NULL.
*/
static std::string get_client_addr(struct sockaddr* client_addr) {
char buf[INET6_ADDRSTRLEN];
std::string str_client_addr {};
if (client_addr == NULL) {
return str_client_addr;
}
switch (client_addr->sa_family) {
case AF_INET: {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)client_addr;
inet_ntop(client_addr->sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN);
str_client_addr = std::string { buf };
break;
}
case AF_INET6: {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)client_addr;
inet_ntop(client_addr->sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN);
str_client_addr = std::string { buf };
break;
}
default:
str_client_addr = std::string { "localhost" };
break;
}
return str_client_addr;
}
MySQL_Client_Host_Cache_Entry MySQL_Threads_Handler::find_client_host_cache(struct sockaddr* client_sockaddr) {
MySQL_Client_Host_Cache_Entry entry { 0, 0 };
// Client_sockaddr **shouldn't** ever by 'NULL', no matter the

@ -7,6 +7,7 @@ using json = nlohmann::json;
#include <functional>
#include <vector>
#include "proxysql_utils.h"
#include "PgSQL_HostGroups_Manager.h"
#include "prometheus_helpers.h"
#define PGSQL_THREAD_IMPLEMENTATION
@ -2354,43 +2355,6 @@ void PgSQL_Threads_Handler::stop_listeners() {
free_tokenizer(&tok);
}
/**
* @brief Gets the client address stored in 'client_addr' member as
* an string if available. If member 'client_addr' is NULL, returns an
* empty string.
*
* @return Either an string holding the string representation of internal
* member 'client_addr', or empty string if this member is NULL.
*/
static std::string get_client_addr(struct sockaddr* client_addr) {
char buf[INET6_ADDRSTRLEN];
std::string str_client_addr{};
if (client_addr == NULL) {
return str_client_addr;
}
switch (client_addr->sa_family) {
case AF_INET: {
struct sockaddr_in* ipv4 = (struct sockaddr_in*)client_addr;
inet_ntop(client_addr->sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN);
str_client_addr = std::string{ buf };
break;
}
case AF_INET6: {
struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)client_addr;
inet_ntop(client_addr->sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN);
str_client_addr = std::string{ buf };
break;
}
default:
str_client_addr = std::string{ "localhost" };
break;
}
return str_client_addr;
}
PgSQL_Client_Host_Cache_Entry PgSQL_Threads_Handler::find_client_host_cache(struct sockaddr* client_sockaddr) {
PgSQL_Client_Host_Cache_Entry entry{ 0, 0 };
// Client_sockaddr **shouldn't** ever by 'NULL', no matter the

@ -490,7 +490,11 @@ void MySQL_Data_Stream::check_data_flow() {
const uint8_t c = *(static_cast<uint8_t*>(PSarrayIN->pdata[0].ptr) + sizeof(mysql_hdr));
if (c == _MYSQL_COM_PING && this->sess->status != WAITING_CLIENT_DATA) {
proxy_warning("Handling unexpected COM_PING packet\n");
const string cli_addr { get_client_addr(this->client_addr) };
proxy_warning(
"Handling unexpected COM_PING packet client_addr=\"%s\" sess_status=%d myds_status=%d\n",
cli_addr.c_str(), this->sess->status, this->DSS
);
// Queue the COM_PING for later handling at MySQL_Session level
this->unexp_com_pings += 1;

@ -7,6 +7,7 @@
#include <algorithm>
#include <climits>
#include <arpa/inet.h>
#include <fcntl.h>
#include <poll.h>
#include <random>
@ -550,3 +551,40 @@ const nlohmann::json* get_nested_elem(const nlohmann::json& j, const vector<stri
return next_step;
}
/**
* @brief Gets the client address stored in 'client_addr' member as
* an string if available. If member 'client_addr' is NULL, returns an
* empty string.
*
* @return Either an string holding the string representation of internal
* member 'client_addr', or empty string if this member is NULL.
*/
std::string get_client_addr(struct sockaddr* client_addr) {
char buf[INET6_ADDRSTRLEN];
std::string str_client_addr {};
if (client_addr == NULL) {
return str_client_addr;
}
switch (client_addr->sa_family) {
case AF_INET: {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)client_addr;
inet_ntop(client_addr->sa_family, &ipv4->sin_addr, buf, INET_ADDRSTRLEN);
str_client_addr = std::string { buf };
break;
}
case AF_INET6: {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)client_addr;
inet_ntop(client_addr->sa_family, &ipv6->sin6_addr, buf, INET6_ADDRSTRLEN);
str_client_addr = std::string { buf };
break;
}
default:
str_client_addr = std::string { "localhost" };
break;
}
return str_client_addr;
}

Loading…
Cancel
Save