diff --git a/etc/postrm.in b/etc/postrm.in index a11ffb66d..2824942c8 100755 --- a/etc/postrm.in +++ b/etc/postrm.in @@ -7,6 +7,7 @@ if [ "$1" = "0" ] || [ "$1" = "remove" ] then if [ -f /etc/init.d/maxscale ] then + /etc/init.d/maxscale stop rm /etc/init.d/maxscale fi diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index e0276b8a6..f0086c632 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -1022,6 +1022,9 @@ add_test_executable(mxs2621_lower_case_tables.cpp mxs2621_lower_case_tables mxs2 # MXS-2631: Duplicate system tables not ignored add_test_executable(mxs2631_ignore_system_tables.cpp mxs2631_ignore_system_tables mxs2631_ignore_system_tables LABELS schemarouter BREAKS_REPL REPL_BACKEND) +# MXS-2878: Verify that TLS is required +add_test_executable(mxs2878_monitor_ssl.cpp mxs2878_monitor_ssl mxs2878_monitor_ssl LABELS REPL_BACKEND) + ############################################ # END: Normal tests # ############################################ diff --git a/maxscale-system-test/cnf/maxscale.cnf.template.mxs2878_monitor_ssl b/maxscale-system-test/cnf/maxscale.cnf.template.mxs2878_monitor_ssl new file mode 100644 index 000000000..e27f8da02 --- /dev/null +++ b/maxscale-system-test/cnf/maxscale.cnf.template.mxs2878_monitor_ssl @@ -0,0 +1,47 @@ +[maxscale] +threads=###threads### + +[server1] +type=server +address=###node_server_IP_1### +port=###node_server_port_1### +protocol=MySQLBackend +ssl=true + +[server2] +type=server +address=###node_server_IP_2### +port=###node_server_port_2### +protocol=MySQLBackend +ssl=true + +[server3] +type=server +address=###node_server_IP_3### +port=###node_server_port_3### +protocol=MySQLBackend +ssl=true + +[server4] +type=server +address=###node_server_IP_4### +port=###node_server_port_4### +protocol=MySQLBackend +ssl=true + +[MySQL-Monitor] +type=monitor +module=mysqlmon +servers=server1,server2,server3,server4 +user=maxskysql +password=skysql + +[CLI] +type=service +router=cli + +[CLI-Listener] +type=listener +service=CLI +protocol=maxscaled +socket=default diff --git a/maxscale-system-test/mxs2878_monitor_ssl.cpp b/maxscale-system-test/mxs2878_monitor_ssl.cpp new file mode 100644 index 000000000..a86495ae3 --- /dev/null +++ b/maxscale-system-test/mxs2878_monitor_ssl.cpp @@ -0,0 +1,35 @@ +/** + * Covers the following bugs: + * MXS-2878: Monitor connections do not insist on SSL being used + * MXS-2896: Server wrongly in Running state after failure to connect + */ + +#include "testconnections.h" +#include + +std::string join(StringSet st) +{ + std::ostringstream ss; + + for (const auto& a : st) + { + ss << a << " "; + } + + return ss.str(); +} + +int main(int argc, char** argv) +{ + TestConnections test(argc, argv); + + for (auto srv : {"server1", "server2", "server3", "server4"}) + { + StringSet expected = {"Down"}; + auto status = test.maxscales->get_server_status(srv); + test.expect(status == expected, + "Expected '%s' but got '%s'", join(expected).c_str(), join(status).c_str()); + } + + return test.global_result; +} diff --git a/server/core/monitor.cc b/server/core/monitor.cc index 9485006a7..f3a1f6e46 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -1143,49 +1143,48 @@ Monitor::ping_or_connect_to_db(const MonitorServer::ConnectionSettings& sett, SE } /** Otherwise close the handle. */ mysql_close(pConn); + pConn = nullptr; } ConnectResult conn_result = ConnectResult::REFUSED; - if ((pConn = mysql_init(NULL)) != nullptr) - { - string uname = sett.username; - string passwd = sett.password; - const Server& srv = static_cast(server); // Clean this up later. - string server_specific_monuser = srv.monitor_user(); - if (!server_specific_monuser.empty()) - { - uname = server_specific_monuser; - passwd = srv.monitor_password(); - } - char* dpwd = decrypt_password(passwd.c_str()); + string uname = sett.username; + string passwd = sett.password; + const Server& srv = static_cast(server); // Clean this up later. + string server_specific_monuser = srv.monitor_user(); + if (!server_specific_monuser.empty()) + { + uname = server_specific_monuser; + passwd = srv.monitor_password(); + } + + char* dpwd = decrypt_password(passwd.c_str()); + + for (int i = 0; i < sett.connect_attempts; i++) + { + pConn = mysql_init(NULL); mysql_optionsv(pConn, MYSQL_OPT_CONNECT_TIMEOUT, &sett.connect_timeout); mysql_optionsv(pConn, MYSQL_OPT_READ_TIMEOUT, &sett.read_timeout); mysql_optionsv(pConn, MYSQL_OPT_WRITE_TIMEOUT, &sett.write_timeout); mysql_optionsv(pConn, MYSQL_PLUGIN_DIR, get_connector_plugindir()); + time_t start = time(NULL); - time_t start = 0; - time_t end = 0; - for (int i = 0; i < sett.connect_attempts; i++) + if (mxs_mysql_real_connect(pConn, &server, uname.c_str(), dpwd)) { - start = time(NULL); - bool result = (mxs_mysql_real_connect(pConn, &server, uname.c_str(), dpwd) != NULL); - end = time(NULL); - - if (result) - { - conn_result = ConnectResult::NEWCONN_OK; - break; - } + conn_result = ConnectResult::NEWCONN_OK; + break; } - - if (conn_result == ConnectResult::REFUSED && difftime(end, start) >= sett.connect_timeout) + else if (conn_result == ConnectResult::REFUSED + && difftime(time(NULL), start) >= sett.connect_timeout) { conn_result = ConnectResult::TIMEOUT; } - MXS_FREE(dpwd); + + mysql_close(pConn); + pConn = nullptr; } + MXS_FREE(dpwd); *ppConn = pConn; return conn_result; }