diff --git a/lib/ClickHouse_Server.cpp b/lib/ClickHouse_Server.cpp index 89f88d486..b3b61061c 100644 --- a/lib/ClickHouse_Server.cpp +++ b/lib/ClickHouse_Server.cpp @@ -1375,9 +1375,11 @@ static void *child_mysql(void *arg) { // 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 hardcored the value 16384 (16KB) as a special case and - // we try to call read_from_net() again - while (rb == 16384) { + // Therefore we hardcored the values 4096 (4K) as a special case and + // we try to call read_from_net() again. + // Previously we hardcoded 16KB but it seems that it can return in smaller + // chunks of 4KB. + while (rb > 0 && rb%4096 == 0) { rb = myds->read_from_net(); if (myds->net_failure) goto __exit_child_mysql; myds->read_pkts(); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 5948d7f2f..54f8644a9 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -5466,9 +5466,11 @@ void *child_mysql(void *arg) { // 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 hardcored the value 16384 (16KB) as a special case and - // we try to call read_from_net() again - while (rb == 16384) { + // Therefore we hardcored the values 4096 (4K) as a special case and + // we try to call read_from_net() again. + // Previously we hardcoded 16KB but it seems that it can return in smaller + // chunks of 4KB. + while (rb > 0 && rb%4096 == 0) { rb = myds->read_from_net(); if (myds->net_failure) goto __exit_child_mysql; myds->read_pkts(); diff --git a/src/SQLite3_Server.cpp b/src/SQLite3_Server.cpp index ee0736059..3c04a3f74 100644 --- a/src/SQLite3_Server.cpp +++ b/src/SQLite3_Server.cpp @@ -944,9 +944,11 @@ static void *child_mysql(void *arg) { // 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 hardcored the value 16384 (16KB) as a special case and - // we try to call read_from_net() again - while (rb == 16384) { + // Therefore we hardcored the values 4096 (4K) as a special case and + // we try to call read_from_net() again. + // Previously we hardcoded 16KB but it seems that it can return in smaller + // chunks of 4KB. + while (rb > 0 && rb%4096 == 0) { rb = myds->read_from_net(); if (myds->net_failure) goto __exit_child_mysql; myds->read_pkts(); diff --git a/test/tap/tests/test_ssl_large_query-2-t.cpp b/test/tap/tests/test_ssl_large_query-2-t.cpp new file mode 100644 index 000000000..b015af9de --- /dev/null +++ b/test/tap/tests/test_ssl_large_query-2-t.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + + +char * username = (char *)"user1459"; +char * password = (char *)"pass1459"; + +std::vector queries_set1 = { + "SET mysql-have_ssl='true'", + "LOAD MYSQL VARIABLES TO RUNTIME", + "DELETE FROM mysql_users WHERE username = 'user1459'", + "INSERT INTO mysql_users (username,password,default_hostgroup) VALUES ('" + std::string(username) + "','" + std::string(password) + "',1459)", + "LOAD MYSQL USERS TO RUNTIME", +}; + +std::vector queries_SQL1 = { + "DROP TABLE IF EXISTS tbl1459", + "CREATE TABLE tbl1459 (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , t1 VARCHAR)", +}; + + +int run_queries_sets(std::vector& queries, MYSQL *my, const std::string& message_prefix) { + for (std::vector::iterator it = queries.begin(); it != queries.end(); it++) { + std::string q = *it; + diag("%s: %s", message_prefix.c_str(), q.c_str()); + MYSQL_QUERY(my, q.c_str()); + } + return 0; +} + +#define ITER 400 + +const std::string lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; + +int main(int argc, char** argv) { + CommandLine cl; + + if(cl.getEnv()) + return exit_status(); + + plan(2+2*ITER); + diag("Testing SSL and fast_forward"); + + MYSQL* mysqladmin = mysql_init(NULL); + if (!mysqladmin) + return exit_status(); + + if (!mysql_real_connect(mysqladmin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", + __FILE__, __LINE__, mysql_error(mysqladmin)); + return exit_status(); + } + + + + if (run_queries_sets(queries_set1, mysqladmin, "Running on Admin")) + return exit_status(); + + + MYSQL * mysqladmin2 = mysql_init(NULL); + if (!mysqladmin2) + return exit_status(); + + mysql_ssl_set(mysqladmin2, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(mysqladmin2, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", + __FILE__, __LINE__, mysql_error(mysqladmin2)); + return exit_status(); + } + + { + const char * c = mysql_get_ssl_cipher(mysqladmin2); + ok(c != NULL , "Cipher in use: %s", c == NULL ? "NULL" : c); + } + + MYSQL * mysqllite3 = mysql_init(NULL); + if (!mysqllite3) + return exit_status(); + + mysql_ssl_set(mysqllite3, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(mysqllite3, cl.host, username, password, NULL, 6030, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", + __FILE__, __LINE__, mysql_error(mysqllite3)); + return exit_status(); + } + + { + const char * c = mysql_get_ssl_cipher(mysqllite3); + ok(c != NULL , "Cipher in use: %s", c == NULL ? "NULL" : c); + } + + for (int i=1; i<=ITER; i++) { + std::string s = "SELECT ''"; + for (int j=0; j