diff --git a/.gitignore b/.gitignore index 5a313b0d3..bb4e557a4 100644 --- a/.gitignore +++ b/.gitignore @@ -186,3 +186,4 @@ heaptrack.* *-t test/tap/tests/galera_1_timeout_count test/tap/tests/galera_2_timeout_no_count +test/tap/tests/setparser_test diff --git a/deps/Makefile b/deps/Makefile index f03a6f4b4..61a91647d 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -104,7 +104,7 @@ curl/curl/lib/.libs/libcurl.a: libssl/openssl/libssl.a cd curl && rm -rf curl-7.57.0 || true cd curl && tar -zxf curl-7.57.0.tar.gz #cd curl/curl && ./configure --disable-debug --disable-ftp --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-ipv6 --disable-sspi --disable-crypto-auth --disable-ntlm-wb --disable-tls-srp --without-nghttp2 --without-libidn2 --without-libssh2 --without-brotli --with-ssl=$(shell pwd)/../../libssl/openssl/ && CC=${CC} CXX=${CXX} ${MAKE} - cd curl/curl && ./configure --disable-debug --disable-ftp --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-ipv6 --disable-sspi --disable-crypto-auth --disable-ntlm-wb --disable-tls-srp --without-nghttp2 --without-libidn2 --without-libssh2 --without-brotli --without-librtmp --without-libpsl --with-ssl=$(shell pwd)/libssl/openssl/ --enable-shared=no && CC=${CC} CXX=${CXX} ${MAKE} + cd curl/curl && ./configure --disable-debug --disable-ftp --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-ipv6 --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-nghttp2 --without-libidn2 --without-libssh2 --without-brotli --without-librtmp --without-libpsl --with-ssl=$(shell pwd)/libssl/openssl/ --enable-shared=no && CC=${CC} CXX=${CXX} ${MAKE} curl: curl/curl/lib/.libs/libcurl.a libmicrohttpd/libmicrohttpd/src/microhttpd/.libs/libmicrohttpd.a: diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index 73ce29d3c..0c71582b2 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -168,7 +168,6 @@ class MySQL_Data_Stream void set_pollout(); void mysql_free(); - void clean_net_failure(); void set_net_failure(); void setDSS_STATE_QUERY_SENT_NET(); @@ -181,8 +180,6 @@ class MySQL_Data_Stream void unplug_backend(); - int myds_connect(char *, int, int *); // the data stream MUST be initialized - void check_data_flow(); int assign_fd_from_mysql_conn(); diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index 6350cc5a6..6f74e142e 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -518,8 +518,7 @@ class MySQL_HostGroups_Manager { void init(); void wrlock(); void wrunlock(); - bool server_add(unsigned int hid, char *add, uint16_t p=3306, uint16_t gp=0, unsigned int _weight=1, enum MySerStatus status=MYSQL_SERVER_STATUS_ONLINE, unsigned int _comp=0, unsigned int _max_connections=100, unsigned int _max_replication_lag=0, unsigned int _use_ssl=0, unsigned int _max_latency_ms=0, char *comment=NULL); - int servers_add(SQLite3_result *resultset); // faster version of server_add + int servers_add(SQLite3_result *resultset); bool commit(); void set_incoming_replication_hostgroups(SQLite3_result *); diff --git a/include/MySQL_Protocol.h b/include/MySQL_Protocol.h index 25dc6bcc6..34a5918fe 100644 --- a/include/MySQL_Protocol.h +++ b/include/MySQL_Protocol.h @@ -80,7 +80,6 @@ class MySQL_Protocol { prot_status=0; } void init(MySQL_Data_Stream **, MySQL_Connection_userinfo *, MySQL_Session *); - int parse_mysql_pkt(PtrSize_t *, MySQL_Data_Stream *); // members get as arguments: // - a data stream (optionally NULL for some) @@ -112,10 +111,7 @@ class MySQL_Protocol { // - a data stream (optionally NULL for some) // - pointer to the packet // - size of the packet - bool process_pkt_OK(unsigned char *pkt, unsigned int len); - bool process_pkt_EOF(unsigned char *pkt, unsigned int len); bool process_pkt_handshake_response(unsigned char *pkt, unsigned int len); - bool process_pkt_COM_QUERY(unsigned char *pkt, unsigned int len); bool process_pkt_COM_CHANGE_USER(unsigned char *pkt, unsigned int len); void * Query_String_to_packet(uint8_t sid, std::string *s, unsigned int *l); diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index f4e5c5c61..5ff381e6f 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -95,7 +95,6 @@ class MySQL_Session void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_CHANGE_USER(PtrSize_t *, bool *); - void handler___status_WAITING_SERVER_DATA___STATE_READING_COM_STMT_PREPARE_RESPONSE(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_SET_OPTION(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STATISTICS(PtrSize_t *); void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *); diff --git a/include/mysql_connection.h b/include/mysql_connection.h index 305b36277..ad22474ae 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -161,8 +161,10 @@ class MySQL_Connection { void set_names_cont(short event); void real_query_start(); void real_query_cont(short event); +#ifndef PROXYSQL_USE_RESULT void store_result_start(); void store_result_cont(short event); +#endif // PROXYSQL_USE_RESULT void initdb_start(); void initdb_cont(short event); void set_option_start(); diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 8a1d580c5..ca53c1319 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -41,6 +41,8 @@ enum log_event_type { enum cred_username_type { USERNAME_BACKEND, USERNAME_FRONTEND }; +#define PROXYSQL_USE_RESULT + enum MDB_ASYNC_ST { // MariaDB Async State Machine ASYNC_CONNECT_START, ASYNC_CONNECT_CONT, @@ -76,8 +78,10 @@ enum MDB_ASYNC_ST { // MariaDB Async State Machine ASYNC_NEXT_RESULT_START, ASYNC_NEXT_RESULT_CONT, ASYNC_NEXT_RESULT_END, +#ifndef PROXYSQL_USE_RESULT ASYNC_STORE_RESULT_START, ASYNC_STORE_RESULT_CONT, +#endif // PROXYSQL_USE_RESULT ASYNC_USE_RESULT_START, ASYNC_USE_RESULT_CONT, ASYNC_INITDB_START, diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index c82ee0a28..30d44f6cb 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -1544,39 +1544,7 @@ unsigned int MySQL_HostGroups_Manager::get_servers_table_version() { return __sync_fetch_and_add(&status.servers_table_version,0); } -// add a new row in mysql_servers_incoming // we always assume that the calling thread has acquired a rdlock() -bool MySQL_HostGroups_Manager::server_add(unsigned int hid, char *add, uint16_t p, uint16_t gp, unsigned int _weight, enum MySerStatus status, unsigned int _comp /*, uint8_t _charset */, unsigned int _max_connections, unsigned int _max_replication_lag, unsigned int _use_ssl, unsigned int _max_latency_ms , char *comment) { - bool ret=true; - proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 7, "Adding in mysql_servers_incoming server %s:%d in hostgroup %u with weight %u , status %u, %s compression, max_connections %d, max_replication_lag %u, use_ssl=%u, max_latency_ms=%u\n", add,p,hid,_weight,status, (_comp ? "with" : "without") /*, _charset */ , _max_connections, _max_replication_lag, _use_ssl, _max_latency_ms); - int rc; - sqlite3_stmt *statement=NULL; - //sqlite3 *mydb3=mydb->get_db(); - char *query=(char *)"INSERT INTO mysql_servers_incoming VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)"; - //rc=(*proxy_sqlite3_prepare_v2)(mydb3, query, -1, &statement, 0); - rc = mydb->prepare_v2(query, &statement); - ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 1, hid); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_text)(statement, 2, add, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 3, p); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 4, gp); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 5, _weight); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 6, status); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 7, _comp); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 8, _max_connections); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 9, _max_replication_lag); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 10, _use_ssl); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_int64)(statement, 11, _max_latency_ms); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_bind_text)(statement, 12, comment, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, mydb); - - SAFE_SQLITE3_STEP2(statement); - rc=(*proxy_sqlite3_clear_bindings)(statement); ASSERT_SQLITE_OK(rc, mydb); - rc=(*proxy_sqlite3_reset)(statement); ASSERT_SQLITE_OK(rc, mydb); - (*proxy_sqlite3_finalize)(statement); - - return ret; -} - int MySQL_HostGroups_Manager::servers_add(SQLite3_result *resultset) { if (resultset==NULL) { return 0; diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index a687480c9..86850d315 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -87,6 +87,15 @@ void proxy_create_random_string(char *_to, uint length, struct rand_struct *rand int rc = 0; uint i; rc = RAND_bytes((unsigned char *)to,length); +#ifdef DEBUG + if (rc==1) { + // For code coverage (to test the following code and other function) + // in DEBUG mode we pretend that RAND_bytes() fails 1% of the time + if(rand()%100==0) { + rc=0; + } + } +#endif // DEBUG if (rc!=1) { for (i=0; iptr; - enum mysql_data_stream_status *DSS=&(*myds)->DSS; - - mysql_hdr hdr; - unsigned char cmd; - unsigned char *payload; - int from=(*myds)->myds_type; // if the packet is from client or server - enum MySQL_response_type c; - - payload=pkt+sizeof(mysql_hdr); - memcpy(&hdr,pkt,sizeof(mysql_hdr)); - proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL,1,"MySQL Packet length=%d, senquence_id=%d, addr=%p\n", hdr.pkt_length, hdr.pkt_id, payload); - - switch (*DSS) { - - // client is not connected yet - case STATE_NOT_CONNECTED: - if (from==MYDS_FRONTEND) { // at this stage we expect a packet from the server, not from client - return PKT_ERROR; - } - break; - - // client has sent the handshake - case STATE_CLIENT_HANDSHAKE: - if (from==MYDS_FRONTEND) { // at this stage we expect a packet from the server, not from client - return PKT_ERROR; - } - c=mysql_response(payload, hdr.pkt_length); - switch (c) { - case OK_Packet: - if (pkt_ok(payload, hdr.pkt_length, this)==PKT_PARSED) { - *DSS=STATE_SLEEP; - return PKT_PARSED; - } - break; - default: - return PKT_ERROR; // from the server we expect either an OK or an ERR. Everything else is wrong - } - break; - - // connection is idle. Client should be send a command - case STATE_SLEEP: -// if (!from_client) { -// return PKT_ERROR; -// } - cmd=*payload; - switch (cmd) { - case COM_QUERY: - if (pkt_com_query(payload, hdr.pkt_length)==PKT_PARSED) { - //*states=STATE_CLIENT_COM_QUERY; - return PKT_PARSED; - } - break; - } - //break; - - default: - // TO BE REMOVED: begin - if (from==MYDS_FRONTEND) { // at this stage we expect a packet from the server, not from client - return PKT_ERROR; - } - c=mysql_response(payload, hdr.pkt_length); - switch (c) { - case OK_Packet: - if (pkt_ok(payload, hdr.pkt_length, this)==PKT_PARSED) { - *DSS=STATE_SLEEP; - return PKT_PARSED; - } - break; - case EOF_Packet: - pkt_end(payload, hdr.pkt_length, this); - break; - default: - return PKT_ERROR; // from the server we expect either an OK or an ERR. Everything else is wrong - } - - // TO BE REMOVED: end - break; - } - - return PKT_ERROR; -} - - - static unsigned char protocol_version=10; static uint16_t server_status=SERVER_STATUS_AUTOCOMMIT; @@ -1440,81 +1363,6 @@ bool MySQL_Protocol::generate_pkt_initial_handshake(bool send, void **ptr, unsig return true; } -bool MySQL_Protocol::process_pkt_OK(unsigned char *pkt, unsigned int len) { - - if (len < 11) return false; - - mysql_hdr hdr; - memcpy(&hdr,pkt,sizeof(mysql_hdr)); - pkt += sizeof(mysql_hdr); - - if (*pkt) return false; - if (len!=hdr.pkt_length+sizeof(mysql_hdr)) return false; - - uint64_t affected_rows; - uint64_t insert_id; -#ifdef DEBUG - uint16_t warns; -#endif /* DEBUG */ - unsigned char msg[len]; - - unsigned int p=0; - int rc; - - pkt++; p++; - rc=mysql_decode_length(pkt,&affected_rows); - pkt += rc; p+=rc; - rc=mysql_decode_length(pkt,&insert_id); - pkt += rc; p+=rc; - prot_status=CPY2(pkt); - pkt+=sizeof(uint16_t); - p+=sizeof(uint16_t); -#ifdef DEBUG - warns=CPY2(pkt); -#endif /* DEBUG */ - pkt+=sizeof(uint16_t); - p+=sizeof(uint16_t); - pkt++; - p++; - if (len>p) { - memcpy(msg,pkt,len-p); - msg[len-p]=0; - } else { - msg[0]=0; - } - - proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL,1,"OK Packet \n", (uint32_t)affected_rows, (uint32_t)insert_id, (uint16_t)prot_status, (uint16_t)warns, msg); - - return true; -} - -bool MySQL_Protocol::process_pkt_EOF(unsigned char *pkt, unsigned int len) { - int ret; - mysql_hdr hdr; - unsigned char *payload; - memcpy(&hdr,pkt,sizeof(mysql_hdr)); - payload=pkt+sizeof(mysql_hdr); - ret=pkt_end(payload, hdr.pkt_length, this); - return ( ret==PKT_PARSED ? true : false ); -} - -bool MySQL_Protocol::process_pkt_COM_QUERY(unsigned char *pkt, unsigned int len) { - bool ret=false; - - unsigned int _len=len-sizeof(mysql_hdr)-1; - unsigned char *query=(unsigned char *)l_alloc(_len+1); - memcpy(query,pkt+1+sizeof(mysql_hdr),_len); - query[_len]=0x00; - - //printf("%s\n",query); - - l_free(_len+1,query); - - ret=true; - return ret; -} - - bool MySQL_Protocol::process_pkt_auth_swich_response(unsigned char *pkt, unsigned int len) { bool ret=false; char *password=NULL; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 7a7a97b96..7f0151901 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -4668,32 +4668,6 @@ bool MySQL_Session::handler_again___multiple_statuses(int *rc) { return ret; } -void MySQL_Session::handler___status_WAITING_SERVER_DATA___STATE_READING_COM_STMT_PREPARE_RESPONSE(PtrSize_t *pkt) { - unsigned char c; - c=*((unsigned char *)pkt->ptr+sizeof(mysql_hdr)); - - //fprintf(stderr,"%d %d\n", mybe->server_myds->myprot.current_PreStmt->pending_num_params, mybe->server_myds->myprot.current_PreStmt->pending_num_columns); - if (c==0xfe && pkt->size < 13) { - if (mybe->server_myds->myprot.current_PreStmt->pending_num_params+mybe->server_myds->myprot.current_PreStmt->pending_num_columns) { - mybe->server_myds->DSS=STATE_EOF1; - } else { - mybe->server_myds->DSS=STATE_READY; - status=WAITING_CLIENT_DATA; - client_myds->DSS=STATE_SLEEP; - } - } else { - if (mybe->server_myds->myprot.current_PreStmt->pending_num_params) { - --mybe->server_myds->myprot.current_PreStmt->pending_num_params; - } else { - if (mybe->server_myds->myprot.current_PreStmt->pending_num_columns) { - --mybe->server_myds->myprot.current_PreStmt->pending_num_columns; - } - } - } - client_myds->PSarrayOUT->add(pkt->ptr, pkt->size); -} - - void MySQL_Session::handler___status_CHANGING_USER_CLIENT___STATE_CLIENT_HANDSHAKE(PtrSize_t *pkt, bool *wrong_pass) { // FIXME: no support for SSL yet if ( diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index c38ba32c2..ef20bdc7e 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -3280,13 +3280,24 @@ SQLite3_result * ProxySQL_Admin::generate_show_fields_from(const char *tablename char *pta[6]; pta[1]=(char *)"varchar(255)"; pta[2]=(char *)"NO"; - pta[3]=(char *)""; pta[4]=(char *)""; pta[5]=(char *)""; free(q2); for (std::vector::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { SQLite3_row *r=*it; - pta[0]=r->fields[0]; + pta[0]=r->fields[1]; + pta[2]=(char *)"YES"; + if (r->fields[3]) { + if (strcmp(r->fields[3],"1")==0) { + pta[2]=(char *)"NO"; + } + } + pta[3]=(char *)""; + if (r->fields[5]) { + if (strcmp(r->fields[5],"0")) { + pta[3]=(char *)"PRI"; + } + } result->add_row(pta); } delete resultset; @@ -3311,7 +3322,7 @@ SQLite3_result * ProxySQL_Admin::generate_show_table_status(const char *tablenam tn[j]=0; SQLite3_result *resultset=NULL; char *q1=(char *)"PRAGMA table_info(%s)"; - char *q2=(char *)malloc(strlen(q1)+strlen(tn)); + char *q2=(char *)malloc(strlen(q1)+strlen(tn)+32); sprintf(q2,q1,tn); int affected_rows; int cols; @@ -3340,7 +3351,6 @@ SQLite3_result * ProxySQL_Admin::generate_show_table_status(const char *tablenam *err=strdup((char *)"Table does not exist"); return NULL; } - free(q2); SQLite3_result *result=new SQLite3_result(18); result->add_column_definition(SQLITE_TEXT,"Name"); result->add_column_definition(SQLITE_TEXT,"Engine"); @@ -3364,7 +3374,14 @@ SQLite3_result * ProxySQL_Admin::generate_show_table_status(const char *tablenam pta[1]=(char *)"SQLite"; pta[2]=(char *)"10"; pta[3]=(char *)"Dynamic"; - pta[4]=(char *)"10"; + delete resultset; + sprintf(q2,"SELECT COUNT(*) FROM %s",tn); + admindb->execute_statement(q2, &error , &cols , &affected_rows , &resultset); + char buf[20]; + sprintf(buf,"%d",resultset->rows_count); + pta[4]=buf; + delete resultset; + free(q2); pta[5]=(char *)"0"; pta[6]=(char *)"0"; pta[7]=(char *)"0"; @@ -3933,7 +3950,7 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) { query_length=strlen(query)+1; goto __run_query; } - if (!strncmp("show table status like '", query_no_space, strlen("show table status like '"))) { + if (!strncasecmp("show table status like '", query_no_space, strlen("show table status like '"))) { char *strA=query_no_space+24; int strAl=strlen(strA); if (strAl<2) { // error @@ -3947,9 +3964,16 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) { run_query=false; goto __run_query; } - if (!strncmp("show fields from `", query_no_space, strlen("show fields from `"))) { - char *strA=query_no_space+18; + if (!strncasecmp("show fields from ", query_no_space, strlen("show fields from "))) { + char *strA=query_no_space+17; int strAl=strlen(strA); + if (strAl==0) { // error + goto __run_query; + } + if (strA[0]=='`') { + strA++; + strAl--; + } if (strAl<2) { // error goto __run_query; } diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index b2bcda431..7589798e7 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -204,8 +204,6 @@ void Variable::fill_client_internal_session(json &j, int idx) { } } -#define PROXYSQL_USE_RESULT - static int mysql_status(short event, short cont) { int status= 0; @@ -922,6 +920,7 @@ void MySQL_Connection::stmt_execute_store_result_cont(short event) { async_exit_status = mysql_stmt_store_result_cont(&interr , query.stmt , mysql_status(event, true)); } +#ifndef PROXYSQL_USE_RESULT void MySQL_Connection::store_result_start() { PROXY_TRACE(); async_exit_status = mysql_store_result_start(&mysql_result, mysql); @@ -931,6 +930,7 @@ void MySQL_Connection::store_result_cont(short event) { proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL, 6,"event=%d\n", event); async_exit_status = mysql_store_result_cont(&mysql_result , mysql , mysql_status(event, true)); } +#endif // PROXYSQL_USE_RESULT void MySQL_Connection::set_is_client() { local_stmts->set_is_client(myds->sess); @@ -1346,7 +1346,7 @@ handler_again: case ASYNC_NEXT_RESULT_END: break; - +#ifndef PROXYSQL_USE_RESULT case ASYNC_STORE_RESULT_START: if (mysql_errno(mysql)) { NEXT_IMMEDIATE(ASYNC_QUERY_END); @@ -1366,6 +1366,7 @@ handler_again: NEXT_IMMEDIATE(ASYNC_QUERY_END); } break; +#endif // PROXYSQL_USE_RESULT case ASYNC_USE_RESULT_START: if (mysql_errno(mysql)) { NEXT_IMMEDIATE(ASYNC_QUERY_END); diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index a8a1c63f3..46b39b473 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -1308,88 +1308,6 @@ int MySQL_Data_Stream::array2buffer_full() { return rc; } -int MySQL_Data_Stream::myds_connect(char *address, int connect_port, int *pending_connect) { - //assert(myconn==NULL); - - assert(myconn); // this assert() is to remove the next condition - if (myconn==NULL) myconn= new MySQL_Connection(); // FIXME: why here? // 20141011 /// should be removed - - myconn->last_time_used=sess->thread->curtime; - struct sockaddr_un u; - struct sockaddr_in a; - int s=0; - int len=0; - int rc=0; - - - if (connect_port) { - // TCP socket - if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - perror("socket"); - close(s); - return -1; - } -#ifdef FD_CLOEXEC - int f_=fcntl(s, F_GETFL); - // asynchronously set also FD_CLOEXEC , this to prevent then when a fork happens the FD are duplicated to new process - fcntl(s, F_SETFL, f_|FD_CLOEXEC); -#endif /* FD_CLOEXEC */ - ioctl_FIONBIO(s, 1); - memset(&a, 0, sizeof(a)); - a.sin_port = htons(connect_port); - a.sin_family = AF_INET; - - if (!inet_aton(address, (struct in_addr *) &a.sin_addr.s_addr)) { - perror("bad IP address format"); - close(s); - return -1; - } - } else { - // UNIX socket domain - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - perror("socket"); - close(s); - return -1; - } -#ifdef FD_CLOEXEC - int f_=fcntl(s, F_GETFL); - // asynchronously set also FD_CLOEXEC , this to prevent then when a fork happens the FD are duplicated to new process - fcntl(s, F_SETFL, f_|FD_CLOEXEC); -#endif /* FD_CLOEXEC */ - ioctl_FIONBIO(s, 1); - memset(u.sun_path,0,UNIX_PATH_MAX); - u.sun_family = AF_UNIX; - strncpy(u.sun_path, address, UNIX_PATH_MAX-1); - len=strlen(u.sun_path)+sizeof(u.sun_family); - } - - if (connect_port) { - rc=connect(s, (struct sockaddr *) &a, sizeof(a)); - int arg_on=1; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &arg_on, sizeof(int)); -#ifdef __APPLE__ - setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char *) &arg_on, sizeof(int)); -#endif - } else { - rc=connect(s, (struct sockaddr *) &u, len); - } - if (rc==-1) { - if (errno!=EINPROGRESS) { - perror("connect()"); - shutdown(s, SHUT_RDWR); - close(s); - return -1; - } - } else { - *pending_connect=0; - } - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p, old_mysql_net_fd=%d, fd=%d\n", this->sess, this, myconn->fd, s); - myconn->fd=s; - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p, new_mysql_net_fd=%d, fd=%d\n", this->sess, this, myconn->fd, s); - return s; - -} - int MySQL_Data_Stream::assign_fd_from_mysql_conn() { assert(myconn); //proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p, oldFD=%d, newFD=%d\n", this->sess, this, fd, myconn->myconn.net.fd); @@ -1407,11 +1325,6 @@ void MySQL_Data_Stream::unplug_backend() { fd=0; } -void MySQL_Data_Stream::clean_net_failure() { - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p\n", this->sess, this); - net_failure=false; -} - void MySQL_Data_Stream::set_net_failure() { proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p , myds_type:%d\n", this->sess, this, myds_type); #ifdef DEBUG diff --git a/lib/network.cpp b/lib/network.cpp index 63dc1e575..23f641fda 100644 --- a/lib/network.cpp +++ b/lib/network.cpp @@ -125,7 +125,9 @@ int listen_on_unix(char *path, int backlog) { - +/* +// THIS CODE IS BEING COMMENTED BECAUSED UNUSED (probably since 2015) +// int connect_socket(char *address, int connect_port) { struct sockaddr_in a; @@ -155,3 +157,4 @@ int connect_socket(char *address, int connect_port) } return s; } +*/ diff --git a/lib/sqlite3db.cpp b/lib/sqlite3db.cpp index bad43c0c8..d97ccf485 100644 --- a/lib/sqlite3db.cpp +++ b/lib/sqlite3db.cpp @@ -519,6 +519,7 @@ void SQLite3_result::dump_to_stderr() { } SQLite3_result::SQLite3_result(SQLite3_result *src) { + enabled_mutex = false; // default rows_count=0; columns=src->columns; if (src->enabled_mutex) { @@ -620,6 +621,7 @@ int SQLite3_result::add_row(SQLite3_row *old_row) { } SQLite3_result::SQLite3_result(sqlite3_stmt *stmt) { + enabled_mutex = false; // default rows_count=0; columns=(*proxy_sqlite3_column_count)(stmt); for (int i=0; i +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::string; + +/* this test: + * enables mysql-have_ssl + * retrieves all tables in the most important schemas + * for each table, it connects with SSL *and* compression, then retrieves all rows +*/ + +int main() { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, 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(proxysql_admin)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "SET mysql-have_ssl='true'"); + MYSQL_QUERY(proxysql_admin, "SET mysql-have_compress='true'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + std::vector tables; + std::vector schemas = { "main", "stats", "disk", "monitor" }; + for (std::vector::iterator s = schemas.begin(); s != schemas.end(); s++) { + std::string q = "SHOW TABLES FROM " + *s; + MYSQL_QUERY(proxysql_admin, q.c_str()); + + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + MYSQL_ROW row; + while ((row = mysql_fetch_row(proxy_res))) { + std::string table1(row[0]); + table1 = *s + "." + table1; + tables.push_back(table1); + std::string table2(row[0]); + table2 = "`" + *s + "`.`" + table2 + "`"; + tables.push_back(table2); + } + mysql_free_result(proxy_res); + } + mysql_close(proxysql_admin); + plan(tables.size() + 1); + ok(tables.size() > 40 , "Number of tables to check: %ld" , tables.size()); + + + proxysql_admin = mysql_init(NULL); // redefined locally + mysql_ssl_set(proxysql_admin, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, CLIENT_SSL|CLIENT_COMPRESS)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + const char * c = mysql_get_ssl_cipher(proxysql_admin); + for (std::vector::iterator it = tables.begin(); it != tables.end(); it++) { + std::string q = "SHOW CREATE TABLE " + *it; + MYSQL_QUERY(proxysql_admin, q.c_str()); + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + unsigned long rows = proxy_res->row_count; + ok(c != NULL && proxysql_admin->net.compress == 1 && rows==1, "cipher %s and compression (%d) used while reading %lu row(s) from %s", c, proxysql_admin->net.compress, rows, it->c_str()); + MYSQL_ROW row; + while ((row = mysql_fetch_row(proxy_res))) { + diag(row[1]); + } + mysql_free_result(proxy_res); + } + mysql_close(proxysql_admin); + + return exit_status(); +} diff --git a/test/tap/tests/admin_show_fields_from-t.cpp b/test/tap/tests/admin_show_fields_from-t.cpp new file mode 100644 index 000000000..11d66d5d3 --- /dev/null +++ b/test/tap/tests/admin_show_fields_from-t.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::string; + +/* this test: + * enables mysql-have_ssl + * retrieves all tables in the most important schemas +*/ + +int main() { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, 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(proxysql_admin)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "SET mysql-have_ssl='true'"); + MYSQL_QUERY(proxysql_admin, "SET mysql-have_compress='true'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + std::vector tables; + std::string q = "SHOW TABLES"; + MYSQL_QUERY(proxysql_admin, q.c_str()); + + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + MYSQL_ROW row; + while ((row = mysql_fetch_row(proxy_res))) { + std::string table(row[0]); + tables.push_back(table); + } + mysql_free_result(proxy_res); + mysql_close(proxysql_admin); + std::vector queries = { + "show fields from `%s`", + "ShOw fields FrOm `%s`", + "show fields from %s", + "ShOw fields FrOm %s", + }; + plan(tables.size()*queries.size()); + + + for (std::vector::iterator it = tables.begin(); it != tables.end(); it++) { + MYSQL* proxysql_admin = mysql_init(NULL); // redefined locally + mysql_ssl_set(proxysql_admin, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, CLIENT_SSL|CLIENT_COMPRESS)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + char *query = (char *) malloc(strlen(queries[0]) + it->length() + 8); + for (std::vector::iterator it2 = queries.begin(); it2 != queries.end(); it2++) { + sprintf(query,*it2, it->c_str()); + MYSQL_QUERY(proxysql_admin, query); + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + unsigned long rows = proxy_res->row_count; + ok(rows > 0 , "Number of rows in %s = %d", it->c_str(), rows); + mysql_free_result(proxy_res); + } + free(query); + mysql_close(proxysql_admin); + } + + return exit_status(); +} diff --git a/test/tap/tests/admin_show_table_status-t.cpp b/test/tap/tests/admin_show_table_status-t.cpp new file mode 100644 index 000000000..ca191ac86 --- /dev/null +++ b/test/tap/tests/admin_show_table_status-t.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::string; + +/* this test: + * enables mysql-have_ssl + * retrieves all tables in the most important schemas +*/ + +int main() { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, 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(proxysql_admin)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "SET mysql-have_ssl='true'"); + MYSQL_QUERY(proxysql_admin, "SET mysql-have_compress='true'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + std::vector tables; + std::string q = "SHOW TABLES"; + MYSQL_QUERY(proxysql_admin, q.c_str()); + + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + MYSQL_ROW row; + while ((row = mysql_fetch_row(proxy_res))) { + std::string table(row[0]); + tables.push_back(table); + } + mysql_free_result(proxy_res); + mysql_close(proxysql_admin); + std::vector queries = { + "show table status like '%s'", + "show TABLE status like '%s'", + "SHOW table status like '%s'", + "show TABLE status LIKE '%s'", + }; + plan(tables.size()*queries.size()); + + + for (std::vector::iterator it = tables.begin(); it != tables.end(); it++) { + MYSQL* proxysql_admin = mysql_init(NULL); // redefined locally + mysql_ssl_set(proxysql_admin, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, CLIENT_SSL|CLIENT_COMPRESS)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + char *query = (char *) malloc(strlen(queries[0]) + it->length() + 8); + for (std::vector::iterator it2 = queries.begin(); it2 != queries.end(); it2++) { + sprintf(query,*it2, it->c_str()); + MYSQL_QUERY(proxysql_admin, query); + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + unsigned long rows = proxy_res->row_count; + ok(rows = 1 , "SHOW TABLE STATUS %s generated %lu row(s)", it->c_str(), rows); + mysql_free_result(proxy_res); + } + free(query); + mysql_close(proxysql_admin); + } + + return exit_status(); +} diff --git a/test/tap/tests/admin_various_commands-t.cpp b/test/tap/tests/admin_various_commands-t.cpp new file mode 100644 index 000000000..152a95f72 --- /dev/null +++ b/test/tap/tests/admin_various_commands-t.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::string; + +/* this test: + * enables mysql-have_ssl + * retrieves all tables in the most important schemas +*/ + +int main() { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, 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(proxysql_admin)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "SET mysql-have_ssl='true'"); + MYSQL_QUERY(proxysql_admin, "SET mysql-have_compress='true'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + std::vector tables; + std::string q = "SHOW TABLES"; + MYSQL_QUERY(proxysql_admin, q.c_str()); + + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + MYSQL_ROW row; + while ((row = mysql_fetch_row(proxy_res))) { + std::string table(row[0]); + tables.push_back(table); + } + mysql_free_result(proxy_res); + mysql_close(proxysql_admin); + std::vector> queries = { // number of rows + query + { 1 , "SELECT version()" }, + { 1 , "select VERSION()" }, + { 4 , "SHOW VARIABLES WHERE Variable_name in ('max_allowed_packet','system_time_zone','time_zone','sql_mode')" }, + { 4 , "SHOW VARIABLES WHERE Variable_name in ('max_allowed_packet','system_time_zone','time_zone','auto_increment_increment')" }, + { 1 , "select @@version_comment limit 1" }, + { 1 , "select DATABASE(), USER() limit 1" }, + { 1 , "SELECT DATABASE(), USER() LIMIT 1" }, + { 1 , "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1" }, + { 1 , "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database LIMIT 1" }, + { 1 , "SHOW GLOBAL VARIABLES LIKE 'version'" }, + { 40 , "SHOW CHARSET" }, + { 200 , "SHOW COLLATION" }, + { 1 , "show GLOBAL VARIABLES LIKE 'version'" }, + { 40 , "show CHARSET" }, + { 200 , "show COLLATION" }, + { 1 , "SHOW mysql USERS" }, + { 1 , "show MYSQL servers" }, + { 1 , "SHOW global VARIABLES" }, + { 1 , "show VARIABLES" }, + { 1 , "show ALL variables" }, + { 1 , "show MYSQL variables" }, + { 1 , "SHOW admin VARIABLES" }, + { 3 , "sHoW DATABASES" }, + { 3 , "sHoW SCHEMAS" }, +/* + { , "" }, + { , "" }, + { , "" }, +*/ + }; + plan(1+queries.size()); + + + proxysql_admin = mysql_init(NULL); + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + mysql_ssl_set(proxysql_admin, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, CLIENT_SSL|CLIENT_COMPRESS)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + const char * c = mysql_get_ssl_cipher(proxysql_admin); + ok(c != NULL && proxysql_admin->net.compress == 1, "cipher %s and compression (%d) used", c, proxysql_admin->net.compress); + for (std::vector>::iterator it2 = queries.begin(); it2 != queries.end(); it2++) { + MYSQL_QUERY(proxysql_admin, it2->second); + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + unsigned long rows = proxy_res->row_count; + ok(rows >= it2->first , "Number of rows: %lu . Minimum expected %d for command: %s", rows, it2->first, it2->second); + mysql_free_result(proxy_res); + } + mysql_close(proxysql_admin); + + return exit_status(); +} diff --git a/test/tap/tests/test_simple_embedded_HTTP_server-t.cpp b/test/tap/tests/test_simple_embedded_HTTP_server-t.cpp new file mode 100644 index 000000000..bd92e3514 --- /dev/null +++ b/test/tap/tests/test_simple_embedded_HTTP_server-t.cpp @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::string; + + +struct memory { + char *response; + size_t size; +}; + +static size_t cb(void *data, size_t size, size_t nmemb, void *userp) { + size_t realsize = size * nmemb; + struct memory *mem = (struct memory *)userp; + + char *ptr = (char *)realloc((void *)mem->response, mem->size + realsize + 1); + if(ptr == NULL) + return 0; /* out of memory! */ + + mem->response = ptr; + memcpy(&(mem->response[mem->size]), data, realsize); + mem->size += realsize; + mem->response[mem->size] = 0; + + return realsize; +} + + +void run_request(const char *url) { + struct memory chunk; + chunk.response = NULL; + chunk.size = 0; + + CURL *curl_handle; + char errbuf[CURL_ERROR_SIZE]; + unsigned int ret = 0; + curl_global_init(CURL_GLOBAL_ALL); + curl_handle = curl_easy_init(); + + curl_easy_setopt(curl_handle, CURLOPT_URL, url); + curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, cb); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl_handle, CURLOPT_USERPWD, "stats:stats"); + curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); + curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errbuf); + + CURLcode res1; + res1 = curl_easy_perform(curl_handle); + if(res1 == CURLE_OK) { + long response_code; + curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &response_code); + ok(response_code==200,"Response code: %ld for %s", response_code, url); + } else { + size_t len = strlen(errbuf); + diag("libcurl: (%d) ", res1); + if(len) + diag("%s%s", errbuf, ((errbuf[len - 1] != '\n') ? "\n" : "")); + else + diag("%s", curl_easy_strerror(res1)); + ok(0,"Failure for %s", url); + } + curl_easy_cleanup(curl_handle); +} + +int main() { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + plan(4); + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, 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(proxysql_admin)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "SET admin-web_enabled='true'"); + MYSQL_QUERY(proxysql_admin, "SET admin-web_port=6080"); + MYSQL_QUERY(proxysql_admin, "LOAD ADMIN VARIABLES TO RUNTIME"); + + run_request("https://127.0.0.1:6080"); + run_request("https://127.0.0.1:6080/stats?metric=system"); + run_request("https://127.0.0.1:6080/stats?metric=mysql"); + run_request("https://127.0.0.1:6080/stats?metric=cache"); + return exit_status(); +} diff --git a/test/tap/tests/test_ssl_connect-t.cpp b/test/tap/tests/test_ssl_connect-t.cpp new file mode 100644 index 000000000..8e8713825 --- /dev/null +++ b/test/tap/tests/test_ssl_connect-t.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" + +using std::string; + +/* this test: + * enables mysql-have_ssl + * retrieves all tables in the most important schemas + * for each table, it connects with SSL *and* compression, then retrieves all rows +*/ + +int main() { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + + MYSQL* proxysql_admin = mysql_init(NULL); + // Initialize connections + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + + if (!mysql_real_connect(proxysql_admin, 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(proxysql_admin)); + return -1; + } + + MYSQL_QUERY(proxysql_admin, "SET mysql-have_ssl='true'"); + MYSQL_QUERY(proxysql_admin, "SET mysql-have_compress='true'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + std::vector tables; + std::vector schemas = { "main", "stats", "disk", "monitor" }; + for (std::vector::iterator s = schemas.begin(); s != schemas.end(); s++) { + std::string q = "SHOW TABLES FROM " + *s; + MYSQL_QUERY(proxysql_admin, q.c_str()); + + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + MYSQL_ROW row; + while ((row = mysql_fetch_row(proxy_res))) { + std::string table(row[0]); + table = *s + "." + table; + tables.push_back(table); + } + mysql_free_result(proxy_res); + } + mysql_close(proxysql_admin); + plan(tables.size()); + + + for (std::vector::iterator it = tables.begin(); it != tables.end(); it++) { + MYSQL* proxysql_admin = mysql_init(NULL); // redefined locally + mysql_ssl_set(proxysql_admin, NULL, NULL, NULL, NULL, NULL); + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, CLIENT_SSL|CLIENT_COMPRESS)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return -1; + } + const char * c = mysql_get_ssl_cipher(proxysql_admin); + std::string q = "SELECT * FROM " + *it; + MYSQL_QUERY(proxysql_admin, q.c_str()); + MYSQL_RES* proxy_res = mysql_store_result(proxysql_admin); + unsigned long rows = proxy_res->row_count; + mysql_free_result(proxy_res); + ok(c != NULL && proxysql_admin->net.compress == 1, "cipher %s and compression (%d) used while reading %lu from table %s", c, proxysql_admin->net.compress, rows, it->c_str()); + mysql_close(proxysql_admin); + } + + return exit_status(); +}