diff --git a/CMakeLists.txt b/CMakeLists.txt index 855b60294..00604caa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ add_custom_target(buildtests add_custom_target(testall COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DBUILD_TYPE=Debug -DINSTALL_DIR=${CMAKE_BINARY_DIR} -DINSTALL_SYSTEM_FILES=N ${CMAKE_SOURCE_DIR} COMMAND make install - COMMAND cp ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null" COMMAND /bin/sh -c "make test || echo \"Test results written to: ${CMAKE_BINARY_DIR}/Testing/Temporary/\"" COMMAND killall maxscale diff --git a/query_classifier/test/canonical_tests/canonizer.c b/query_classifier/test/canonical_tests/canonizer.c index 7983c9041..d44478399 100644 --- a/query_classifier/test/canonical_tests/canonizer.c +++ b/query_classifier/test/canonical_tests/canonizer.c @@ -57,7 +57,7 @@ int main(int argc, char** argv) { fgets(readbuff,4092,infile); psize = strlen(readbuff); - if(psize < 0 || psize > 4092){ + if(psize > 4092){ continue; } qbuff = gwbuf_alloc(psize + 7); diff --git a/server/core/config.c b/server/core/config.c index b0aa25178..153bf1640 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -1393,11 +1393,11 @@ SERVER *server; user, auth); if (enable_root_user) - serviceEnableRootUser(service, atoi(enable_root_user)); + serviceEnableRootUser(obj->element, atoi(enable_root_user)); - if (allow_localhost_match_wildcard_host && service) + if (allow_localhost_match_wildcard_host) serviceEnableLocalhostMatchWildcardHost( - service, + obj->element, atoi(allow_localhost_match_wildcard_host)); } } diff --git a/server/modules/include/mysql_client_server_protocol.h b/server/modules/include/mysql_client_server_protocol.h index 15817527e..b2b78cf56 100644 --- a/server/modules/include/mysql_client_server_protocol.h +++ b/server/modules/include/mysql_client_server_protocol.h @@ -281,6 +281,7 @@ typedef struct { * created or received */ unsigned long tid; /*< MySQL Thread ID, in * handshake */ + unsigned int charset; /*< MySQL character set at connect time */ #if defined(SS_DEBUG) skygw_chk_t protocol_chk_tail; #endif diff --git a/server/modules/monitor/galera_mon.c b/server/modules/monitor/galera_mon.c index d41e79ea5..a06e08cc4 100644 --- a/server/modules/monitor/galera_mon.c +++ b/server/modules/monitor/galera_mon.c @@ -157,6 +157,9 @@ MYSQL_MONITOR *handle; handle->interval = MONITOR_INTERVAL; handle->disableMasterFailback = 0; handle->master = NULL; + handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; + handle->read_timeout=DEFAULT_READ_TIMEOUT; + handle->write_timeout=DEFAULT_READ_TIMEOUT; spinlock_init(&handle->lock); } handle->tid = (THREAD)thread_start(monitorMain, handle); @@ -275,6 +278,9 @@ char *sep; dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval); dcb_printf(dcb,"\tMaster Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on"); + dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout); + dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout); + dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout); dcb_printf(dcb, "\tMonitored servers: "); db = handle->databases; @@ -312,16 +318,18 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; /** * Monitor an individual server * - * @param database The database to probe + * @param handle The MySQL Monitor object + * @param database The database to probe */ static void -monitorDatabase(MONITOR_SERVERS *database, char *defaultUser, char *defaultPasswd) +monitorDatabase(MYSQL_MONITOR *handle, MONITOR_SERVERS *database) { MYSQL_ROW row; MYSQL_RES *result; int num_fields; int isjoined = 0; -char *uname = defaultUser, *passwd = defaultPasswd; +char *uname = handle->defaultUser; +char *passwd = handle->defaultPasswd; unsigned long int server_version = 0; char *server_string; @@ -341,12 +349,15 @@ char *server_string; { char *dpwd = decryptPassword(passwd); int rc; - int read_timeout = 1; - int connect_timeout = 2; + int connect_timeout = handle->connect_timeout; + int read_timeout = handle->read_timeout; + int write_timeout = handle->write_timeout;; database->con = mysql_init(NULL); + rc = mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout); rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); + rc = mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); if (mysql_real_connect(database->con, database->server->name, uname, dpwd, NULL, database->server->port, NULL, 0) == NULL) @@ -489,7 +500,7 @@ int master_stickiness = handle->disableMasterFailback; { unsigned int prev_status = ptr->server->status; - monitorDatabase(ptr, handle->defaultUser, handle->defaultPasswd); + monitorDatabase(handle, ptr); /* clear bits for non member nodes */ if ( ! SERVER_IN_MAINT(ptr->server) && (ptr->server->node_id < 0 || ! SERVER_IS_JOINED(ptr->server))) { diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index c48e0ad5c..957866b30 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -181,9 +181,9 @@ MYSQL_MONITOR *handle; handle->replicationHeartbeat = 0; handle->detectStaleMaster = 0; handle->master = NULL; - handle->connect_timeout=3; - handle->read_timeout=1; - handle->write_timeout=2; + handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; + handle->read_timeout=DEFAULT_READ_TIMEOUT; + handle->write_timeout=DEFAULT_WRITE_TIMEOUT; spinlock_init(&handle->lock); } handle->tid = (THREAD)thread_start(monitorMain, handle); @@ -388,11 +388,15 @@ char *server_string; { char *dpwd = decryptPassword(passwd); int rc; - int read_timeout = 1; + int connect_timeout = handle->connect_timeout; + int read_timeout = handle->read_timeout; + int write_timeout = handle->write_timeout; database->con = mysql_init(NULL); + rc = mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout); rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); + rc = mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); if (mysql_real_connect(database->con, database->server->name, @@ -874,6 +878,13 @@ static void set_master_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *databas char heartbeat_insert_query[512]=""; char heartbeat_purge_query[512]=""; + if (handle->master == NULL) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "[mysql_mon]: set_master_heartbeat called without an available Master server"))); + return; + } + /* create the maxscale_schema database */ if (mysql_query(database->con, "CREATE DATABASE IF NOT EXISTS maxscale_schema")) { LOGIF(LE, (skygw_log_write_flush( @@ -979,6 +990,13 @@ static void set_slave_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database MYSQL_RES *result; int num_fields; + if (handle->master == NULL) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "[mysql_mon]: set_slave_heartbeat called without an available Master server"))); + return; + } + /* Get the master_timestamp value from maxscale_schema.replication_heartbeat table */ sprintf(select_heartbeat_query, "SELECT master_timestamp " @@ -1243,6 +1261,7 @@ int new_timeout = max_timeout -1; ", lowering to %i seconds", value, max_timeout, new_timeout))); } break; + case MONITOR_READ_TIMEOUT: if (value < max_timeout) { memcpy(&handle->read_timeout, &value, sizeof(int)); @@ -1254,6 +1273,7 @@ int new_timeout = max_timeout -1; ", lowering to %i seconds", value, max_timeout, new_timeout))); } break; + case MONITOR_WRITE_TIMEOUT: if (value < max_timeout) { memcpy(&handle->write_timeout, &value, sizeof(int)); diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 462a77c48..fcb75e004 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -44,6 +44,7 @@ * 12/09/2013 Massimiliano Pinto Added checks in gw_read_backend_event() for gw_read_backend_handshake * 27/09/2013 Massimiliano Pinto Changed in gw_read_backend_event the check for dcb_read(), now is if rc < 0 * 24/10/2014 Massimiliano Pinto Added Mysql user@host @db authentication support + * 10/11/2014 Massimiliano Pinto Client charset is passed to backend * */ #include @@ -914,6 +915,9 @@ static int gw_create_backend_connection( /** Copy client flags to backend protocol */ protocol->client_capabilities = ((MySQLProtocol *)(backend_dcb->session->client->protocol))->client_capabilities; + /** Copy client charset to backend protocol */ + protocol->charset = + ((MySQLProtocol *)(backend_dcb->session->client->protocol))->charset; /*< if succeed, fd > 0, -1 otherwise */ rv = gw_do_connect_to_backend(server->name, server->port, &fd); @@ -1262,6 +1266,16 @@ static int gw_change_user( /* get new database name */ strcpy(database, (char *)client_auth_packet); + /* get character set */ + if (strlen(database)) { + client_auth_packet += strlen(database) + 1; + } else { + client_auth_packet++; + } + + if (client_auth_packet && *client_auth_packet) + memcpy(&backend_protocol->charset, client_auth_packet, sizeof(int)); + /* save current_database name */ strcpy(current_database, current_session->db); @@ -1515,4 +1529,4 @@ static bool sescmd_response_complete( succp = false; } return succp; -} \ No newline at end of file +} diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index e8824b957..f67edb7f3 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -36,6 +36,7 @@ * 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake * 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path * 13/10/2014 Massimiliano Pinto Added: dbname authentication check + * 10/11/2014 Massimiliano Pinto Added: client charset added to protocol struct * */ #include @@ -444,6 +445,9 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) { return 1; } + /* get charset */ + memcpy(&protocol->charset, client_auth_packet + 4 + 4 + 4, sizeof (int)); + /* get the auth token len */ memcpy(&auth_token_len, client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) + 1, diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index ce8d275b0..374cabfb5 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -35,6 +35,7 @@ * x.y.z.%, x.y.%.%, x.%.%.% * 03/10/2014 Massimiliano Pinto Added netmask for wildcard in IPv4 hosts. * 24/10/2014 Massimiliano Pinto Added Mysql user@host @db authentication support + * 10/11/2014 Massimiliano Pinto Charset at connect is passed to backend during authentication * */ @@ -563,6 +564,7 @@ int gw_send_authentication_to_backend( char *curr_db = NULL; uint8_t *curr_passwd = NULL; + unsigned int charset; if (strlen(dbname)) curr_db = dbname; @@ -574,7 +576,10 @@ int gw_send_authentication_to_backend( final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities); /** Copy client's flags to backend */ - final_capabilities |= conn->client_capabilities;; + final_capabilities |= conn->client_capabilities; + + /* get charset the client sent and use it for connection auth */ + charset = conn->charset; if (compress) { final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS; @@ -668,7 +673,7 @@ int gw_send_authentication_to_backend( // set the charset payload += 4; - *payload = '\x08'; + *payload = charset; payload++; @@ -1079,6 +1084,7 @@ int gw_send_change_user_to_backend( char *curr_db = NULL; uint8_t *curr_passwd = NULL; + unsigned int charset; if (strlen(dbname)) curr_db = dbname; @@ -1091,7 +1097,10 @@ int gw_send_change_user_to_backend( final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities); /** Copy client's flags to backend */ - final_capabilities |= conn->client_capabilities;; + final_capabilities |= conn->client_capabilities; + + /* get charset the client sent and use it for connection auth */ + charset = conn->charset; if (compress) { final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS; @@ -1217,7 +1226,7 @@ int gw_send_change_user_to_backend( } // set the charset, 2 bytes!!!! - *payload = '\x08'; + *payload = charset; payload++; *payload = '\x00'; payload++; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index ad30b831a..6b475a4e9 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1636,10 +1636,13 @@ void check_create_tmp_table( if (h != NULL) { rses_prop_tmp->rses_prop_data.temp_tables = h; - } + }else{ + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error : Failed to allocate a new hashtable."))); + } + } - if (hkey && + if (hkey && rses_prop_tmp->rses_prop_data.temp_tables && hashtable_add(rses_prop_tmp->rses_prop_data.temp_tables, (void *)hkey, (void *)is_temp) == 0) /*< Conflict in hash table */