Skip to content

Commit

Permalink
Merge branch 'v2.x' into v2.x-4066-upgrade_deps
Browse files Browse the repository at this point in the history
  • Loading branch information
mirostauder authored Jan 23, 2023
2 parents 2cef18c + e8db84e commit 42c135d
Show file tree
Hide file tree
Showing 32 changed files with 1,576 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ DEBUG=${ALL_DEBUG}
#export OPTZ
#export EXTRALINK
export MAKE
export CURVER?=2.4.6
export CURVER?=2.5.0
ifneq (,$(wildcard /etc/os-release))
DISTRO := $(shell gawk -F= '/^NAME/{print $$2}' /etc/os-release)
else
Expand Down
13 changes: 13 additions & 0 deletions deps/libhttpserver/empty_uri_log_crash.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git src/webserver.cpp src/webserver.cpp
index 5ae7381..04a5a28 100644
--- src/webserver.cpp
+++ src/webserver.cpp
@@ -443,7 +443,7 @@ int policy_callback (void *cls, const struct sockaddr* addr, socklen_t addrlen)
void* uri_log(void* cls, const char* uri)
{
struct details::modded_request* mr = new details::modded_request();
- mr->complete_uri = new string(uri);
+ mr->complete_uri = new string(uri == NULL ? "" : uri);
mr->second = false;
return ((void*)mr);
}
4 changes: 4 additions & 0 deletions deps/mariadb-client-library/UPGRADE_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Please note that upgrading `mariadb-connector-c` can require some changes
in `include/MySQL_Data_Stream.h` where we define `P_MARIADB_TLS` as a copy
of `MARIADB_TLS` . If `MARIADB_TLS` is changed, `P_MARIADB_TLS` must be
updated too.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
57 changes: 56 additions & 1 deletion include/MySQL_Data_Stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@

#include "MySQL_Protocol.h"

#ifndef uchar
typedef unsigned char uchar;
#endif

#include "ma_pvio.h"
// here we define P_MARIADB_TLS as a copy of MARIADB_TLS
// copied from ma_tls.h
// note that ma_pvio.h defines it as void
typedef struct P_st_ma_pvio_tls {
void *data;
MARIADB_PVIO *pvio;
void *ssl;
} P_MARIADB_TLS;


#define QUEUE_T_DEFAULT_SIZE 32768
#define MY_SSL_BUFFER 8192

Expand Down Expand Up @@ -35,8 +50,12 @@ class MyDS_real_query {
*/
pkt.ptr=_pkt->ptr;
pkt.size=_pkt->size;
QueryPtr=(char *)pkt.ptr+5;
QuerySize=pkt.size-5;
if (QuerySize == 0) {
QueryPtr=const_cast<char*>("");
} else {
QueryPtr=(char *)pkt.ptr+5;
}
}
void end() {
l_free(pkt.size,pkt.ptr);
Expand Down Expand Up @@ -192,6 +211,33 @@ class MySQL_Data_Stream
myconn=mc;
myconn->statuses.myconnpoll_get++;
mc->myds=this;
encrypted = false; // this is the default
// we handle encryption for backend
//
// we have a similar code in MySQL_Connection
// in case of ASYNC_CONNECT_SUCCESSFUL
if (sess != NULL && sess->session_fast_forward == true) {
// if frontend and backend connection use SSL we will set
// encrypted = true and we will start using the SSL structure
// directly from P_MARIADB_TLS structure.
//
// For futher details:
// - without ssl: we use the file descriptor from mysql connection
// - with ssl: we use the SSL structure from mysql connection
if (myconn->mysql && myconn->ret_mysql) {
if (myconn->mysql->options.use_ssl == 1) {
encrypted = true;
if (ssl == NULL) {
// check the definition of P_MARIADB_TLS
P_MARIADB_TLS * matls = (P_MARIADB_TLS *)myconn->mysql->net.pvio->ctls;
ssl = (SSL *)matls->ssl;
rbio_ssl = BIO_new(BIO_s_mem());
wbio_ssl = BIO_new(BIO_s_mem());
SSL_set_bio(ssl, rbio_ssl, wbio_ssl);
}
}
}
}
}

// safe way to detach a MySQL Connection
Expand All @@ -201,6 +247,15 @@ class MySQL_Data_Stream
statuses.myconnpoll_put++;
myconn->myds=NULL;
myconn=NULL;
if (encrypted == true) {
if (sess != NULL && sess->session_fast_forward == true) {
// it seems we are a connection with SSL on a fast_forward session.
// See attach_connection() for more details .
// We now disable SSL metadata from the Data Stream
encrypted = false;
ssl = NULL;
}
}
}

void return_MySQL_Connection_To_Pool();
Expand Down
19 changes: 18 additions & 1 deletion lib/ClickHouse_Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ void ClickHouse_Server_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t
query_no_space[query_no_space_length]=0;
}

proxy_debug(PROXY_DEBUG_SQLITE, 4, "Received query on Session %p , thread_session_id %u : %s\n", sess, sess->thread_session_id, query_no_space);


if (sess->session_type == PROXYSQL_SESSION_CLICKHOUSE) {
if (!strncasecmp("SET ", query_no_space, 4)) {
Expand Down Expand Up @@ -1365,9 +1367,24 @@ static void *child_mysql(void *arg) {
}
}
myds->revents=fds[0].revents;
myds->read_from_net();
int rb = 0;
rb - myds->read_from_net();
if (myds->net_failure) goto __exit_child_mysql;
myds->read_pkts();
if (myds->encrypted == true) {
// PMC-10004
// we probably should use SSL_pending() and/or SSL_has_pending() to determine
// if there is more data to be read, but it doesn't seem to be working.
// Therefore we try to call read_from_net() again as long as there is data.
// Previously we hardcoded 16KB but it seems that it can return in smaller
// chunks of 4KB.
// We finally removed the chunk size as it seems that any size is possible.
while (rb > 0) {
rb = myds->read_from_net();
if (myds->net_failure) goto __exit_child_mysql;
myds->read_pkts();
}
}
sess->to_process=1;
int rc=sess->handler();
if (rc==-1) goto __exit_child_mysql;
Expand Down
6 changes: 5 additions & 1 deletion lib/MySQL_HostGroups_Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3554,7 +3554,11 @@ void MySQL_HostGroups_Manager::replication_lag_action_inner(MyHGC *myhgc, char *
if (
// (current_replication_lag==-1 )
// ||
(current_replication_lag>=0 && ((unsigned int)current_replication_lag > mysrvc->max_replication_lag))
(
current_replication_lag>=0 &&
mysrvc->max_replication_lag > 0 && // see issue #4018
((unsigned int)current_replication_lag > mysrvc->max_replication_lag)
)
) {
// always increase the counter
mysrvc->cur_replication_lag_count += 1;
Expand Down
16 changes: 9 additions & 7 deletions lib/MySQL_Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,16 @@ MYSQL * MySQL_Monitor_Connection_Pool::get_connection(char *hostname, int port,
break;
}
#ifdef DEBUG
for (unsigned int j=0; j<conns->len; j++) {
MYSQL *my1 = (MYSQL *)conns->index(j);
assert(my!=my1);
assert(my->net.fd!=my1->net.fd);
}
//proxy_info("Registering MYSQL with FD %d from mmsd %p and MYSQL %p\n", my->net.fd, mmsd, my);
if (my)
if (my) {
for (unsigned int j=0; j<conns->len; j++) {
MYSQL *my1 = (MYSQL *)conns->index(j);
assert(my!=my1);
assert(my->net.fd!=my1->net.fd);
}
//proxy_info("Registering MYSQL with FD %d from mmsd %p and MYSQL %p\n", my->net.fd, mmsd, my);

conns->add(my);
}
#endif // DEBUG
}
#ifdef DEBUG
Expand Down
5 changes: 4 additions & 1 deletion lib/MySQL_Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,7 +1947,10 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned
#endif
(*myds)->sess->schema_locked=schema_locked;
(*myds)->sess->transaction_persistent=transaction_persistent;
(*myds)->sess->session_fast_forward=fast_forward;
(*myds)->sess->session_fast_forward=false; // default
if ((*myds)->sess->session_type == PROXYSQL_SESSION_MYSQL) {
(*myds)->sess->session_fast_forward=fast_forward;
}
(*myds)->sess->user_max_connections=max_connections;
}
if (password == NULL) {
Expand Down
9 changes: 5 additions & 4 deletions lib/MySQL_Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,7 @@ void MySQL_Session::writeout() {
}

bool MySQL_Session::handler_CommitRollback(PtrSize_t *pkt) {
if (pkt->size <= 5) { return false; }
char c=((char *)pkt->ptr)[5];
bool ret=false;
if (c=='c' || c=='C') {
Expand Down Expand Up @@ -5398,7 +5399,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
(strcmp(client_addr,(char *)"::1")==0)
) {
// we are good!
client_myds->myprot.generate_pkt_OK(true,NULL,NULL, _pid, 0,0,0,0,NULL);
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, _pid, 0, 0, 2, 0, NULL);
handshake_err = false;
GloMyLogger->log_audit_entry(PROXYSQL_MYSQL_AUTH_OK, this, NULL);
status=WAITING_CLIENT_DATA;
Expand Down Expand Up @@ -5444,7 +5445,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
//client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL,false);
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION,8,"Session=%p , DS=%p . STATE_CLIENT_AUTH_OK\n", this, client_myds);
GloMyLogger->log_audit_entry(PROXYSQL_MYSQL_AUTH_OK, this, NULL);
client_myds->myprot.generate_pkt_OK(true,NULL,NULL, _pid, 0,0,0,0,NULL);
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, _pid, 0, 0, 2, 0, NULL);
handshake_err = false;
status=WAITING_CLIENT_DATA;
client_myds->DSS=STATE_CLIENT_AUTH_OK;
Expand Down Expand Up @@ -6711,7 +6712,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
client_authenticated=false;
if (client_myds->myprot.process_pkt_COM_CHANGE_USER((unsigned char *)pkt->ptr, pkt->size)==true) {
l_free(pkt->size,pkt->ptr);
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,0,0,NULL);
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, 1, 0, 0, 2, 0, NULL);
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
*wrong_pass=false;
Expand Down Expand Up @@ -6801,7 +6802,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C

l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,0,0,NULL);
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, 1, 0, 0, 2, 0, NULL);
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
} else {
Expand Down
61 changes: 51 additions & 10 deletions lib/MySQL_Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "MySQL_PreparedStatement.h"
#include "MySQL_Logger.hpp"

#include <fcntl.h>

using std::vector;
using std::function;

Expand Down Expand Up @@ -2834,6 +2836,20 @@ MySQL_Session * MySQL_Thread::create_new_session_and_client_data_stream(int _fd)
register_session(sess); // register session
sess->client_myds = new MySQL_Data_Stream();
sess->client_myds->fd=_fd;

// set not blocking for client connections too!
{
// PMC-10004
// While implementing SSL and fast_forward it was noticed that all frontend connections
// are in blocking, although this was never a problem because we call poll() before reading.
// Although it became a problem with fast_forward, SSL and large packets because SSL handled
// data in chunks of 16KB and there may be data inside SSL even when there is no data
// received from the network.
// The only modules that seems to be affected by this issue are Admin, SQLite3 Server
// and Clickhouse Server
int nb = fcntl(_fd, F_SETFL, fcntl(_fd, F_GETFL, 0) | O_NONBLOCK);
assert (nb != -1);
}
setsockopt(sess->client_myds->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &arg_on, sizeof(arg_on));

if (mysql_thread___use_tcp_keepalive) {
Expand Down Expand Up @@ -3578,17 +3594,42 @@ bool MySQL_Thread::process_data_on_data_stream(MySQL_Data_Stream *myds, unsigned

if (rb > 0 && myds->myds_type == MYDS_BACKEND) {
if (myds->sess->session_fast_forward) {
struct pollfd _fds;
nfds_t _nfds = 1;
_fds.fd = mypolls.fds[n].fd;
_fds.events = POLLIN;
_fds.revents = 0;
int _rc = poll(&_fds, _nfds, 0);
if ((_rc > 0) && _fds.revents == POLLIN) {
// there is more data
myds->revents = _fds.revents;
} else {
if (myds->encrypted == true) { // we are in fast_forward mode and encrypted == true
// PMC-10004
// we probably should use SSL_pending() and/or SSL_has_pending() to determine
// if there is more data to be read, but it doesn't seem to be working.
// Therefore we try to call read_from_net() again as long as there is data.
// Previously we hardcoded 16KB but it seems that it can return in smaller
// chunks of 4KB.
// We finally removed the chunk size as it seems that any size is possible.
/*
int sslp = SSL_pending(myds->ssl);
int sslhp = SSL_has_pending(myds->ssl);
proxy_debug(PROXY_DEBUG_NET, 5, "Session=%p: in fast_forward mode and SSL read %d bytes , SSL_pending: %d bytes , SSL_has_pending: %d\n", myds->sess, rb, sslp, sslhp);
*/
proxy_debug(PROXY_DEBUG_NET, 5, "Session=%p, DataStream=%p , thread_session_id=%u -- in fast_forward mode and SSL read %d bytes\n", myds->sess, myds, myds->sess->thread_session_id, rb);
while (rb > 0) {
rb = myds->read_from_net();
if (rb > 0 && myds->myds_type == MYDS_FRONTEND) {
status_variables.stvar[st_var_queries_frontends_bytes_recv] += rb;
}
proxy_debug(PROXY_DEBUG_NET, 5, "Session=%p, DataStream=%p -- in fast_forward mode and SSL read %d bytes\n", myds->sess, myds, rb);
myds->read_pkts();
}
rb = 0; // exit loop
} else { // we are in fast_forward mode and encrypted == false
struct pollfd _fds;
nfds_t _nfds = 1;
_fds.fd = mypolls.fds[n].fd;
_fds.events = POLLIN;
_fds.revents = 0;
int _rc = poll(&_fds, _nfds, 0);
if ((_rc > 0) && _fds.revents == POLLIN) {
// there is more data
myds->revents = _fds.revents;
} else {
rb = 0; // exit loop
}
}
} else {
rb = 0; // exit loop
Expand Down
17 changes: 16 additions & 1 deletion lib/ProxySQL_Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5459,9 +5459,24 @@ void *child_mysql(void *arg) {
}
mysql_thr->curtime = monotonic_time();
myds->revents=fds[0].revents;
myds->read_from_net();
int rb = 0;
rb = myds->read_from_net();
if (myds->net_failure) goto __exit_child_mysql;
myds->read_pkts();
if (myds->encrypted == true) {
// PMC-10004
// we probably should use SSL_pending() and/or SSL_has_pending() to determine
// if there is more data to be read, but it doesn't seem to be working.
// Therefore we try to call read_from_net() again as long as there is data.
// Previously we hardcoded 16KB but it seems that it can return in smaller
// chunks of 4KB.
// We finally removed the chunk size as it seems that any size is possible.
while (rb > 0) {
rb = myds->read_from_net();
if (myds->net_failure) goto __exit_child_mysql;
myds->read_pkts();
}
}
sess->to_process=1;
int rc=sess->handler();
if (rc==-1) goto __exit_child_mysql;
Expand Down
Loading

0 comments on commit 42c135d

Please sign in to comment.