MXS-1714 Use local_address also with MaxScale connections

If local address has been specified, then all connections created
using mxs_mysql_real_connect() will use that same local address as
well.

A system test has not been created as our VMs do not have more than
one usable IP-address. Locally it has been verified to work as
expected.
This commit is contained in:
Johan Wikman 2018-03-12 11:02:11 +02:00
parent f54bbdf73b
commit c5345d34ca
3 changed files with 197 additions and 0 deletions

View File

@ -163,6 +163,18 @@ MYSQL *mxs_mysql_real_connect(MYSQL *con, SERVER *server, const char *user, cons
mysql_optionsv(con, MYSQL_OPT_RECONNECT, &yes);
mysql_optionsv(con, MYSQL_INIT_COMMAND, "SET SQL_MODE=''");
MXS_CONFIG* config = config_get_global_options();
if (config->local_address)
{
if (mysql_optionsv(con, MYSQL_OPT_BIND, config->local_address) != 0)
{
MXS_ERROR("'local_address' specified in configuration file, but could not "
"configure MYSQL handle. MaxScale will try to connect using default "
"address.");
}
}
MYSQL* mysql = mysql_real_connect(con, server->name, user, passwd, NULL, server->port, NULL, 0);
if (mysql)

View File

@ -4,6 +4,7 @@ add_executable(test_dcb testdcb.c)
add_executable(test_filter testfilter.c)
add_executable(test_hash testhash.c)
add_executable(test_hint testhint.c)
add_executable(test_local_address test_local_address.cc)
add_executable(test_log testlog.c)
add_executable(test_logorder testlogorder.c)
add_executable(test_logthrottling testlogthrottling.cc)
@ -28,6 +29,7 @@ target_link_libraries(test_dcb maxscale-common)
target_link_libraries(test_filter maxscale-common)
target_link_libraries(test_hash maxscale-common)
target_link_libraries(test_hint maxscale-common)
target_link_libraries(test_local_address maxscale-common)
target_link_libraries(test_log maxscale-common)
target_link_libraries(test_logorder maxscale-common)
target_link_libraries(test_logthrottling maxscale-common)

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <maxscale/config.h>
#include <maxscale/mysql_utils.h>
using namespace std;
char USAGE[] =
"usage: test_local_address -u user [-p password] [-a address] [-h host] [-s success]\n"
"\n"
"user : The user to connect as.\n"
"password: The password of the user, default none.\n"
"address : The address to connect from, default none specified.\n"
"host : The address of the host to connect to, default 127.0.0.1.\n"
"success : (0|1), whether the connection attempt is expected to succeed or not, defaul 1.\n"
"\n"
"Example:\n"
"\n"
"MariaDB [(none)]> create user 'l1'@'192.168.1.254';\n"
"MariaDB [(none)]> create user 'l2'@'127.0.0.1';\n"
"\n"
"$ ./test_local_address -s 1 -u l1 -a 192.168.1.254\n"
"User : l1\n"
"Password: (none)\n"
"Server : 127.0.0.1\n"
"Address : 192.168.1.254\n"
"Success : 1\n"
"\n"
"Could connect, as expected.\n"
"$ ./test_local_address -s 0 -u l1 -a 127.0.0.1\n"
"User : l1\n"
"Password: (none)\n"
"Server : 127.0.0.1\n"
"Address : 127.0.0.1\n"
"Success : 0\n"
"\n"
"Could not connect, as expected. "
"Reported error: Access denied for user 'l1'@'localhost' (using password: NO)\n"
"$ ./test_local_address -s 1 -u l2 -a 127.0.0.1\n"
"User : l2\n"
"Password: (none)\n"
"Server : 127.0.0.1\n"
"Address : 127.0.0.1\n"
"Success : 1\n"
"\n"
"Could connect, as expected.\n"
"$ ./test_local_address -s 0 -u l2 -a 192.168.1.254\n"
"User : l2\n"
"Password: (none)\n"
"Server : 127.0.0.1\n"
"Address : 192.168.1.254\n"
"Success : 0\n"
"\n"
"Could not connect, as expected. "
"Reported error: Access denied for user 'l2'@'192.168.1.254' (using password: NO)\n";
namespace
{
int test(bool success, const char* zHost, const char* zUser, const char* zPassword, const char* zAddress)
{
int rv = EXIT_FAILURE;
MXS_CONFIG* config = config_get_global_options();
config->local_address = const_cast<char*>(zAddress);
SERVER server;
memset(&server, 0, sizeof(server));
strcpy(server.name, zHost);
server.port = 3306;
MYSQL* pMysql = mysql_init(NULL);
MYSQL* pConn = mxs_mysql_real_connect(pMysql, &server, zUser, zPassword);
if (pConn)
{
if (success)
{
cout << "Could connect, as expected." << endl;
rv = EXIT_SUCCESS;
}
else
{
cerr << "Error: Connection succeeded, although expected not to." << endl;
}
mysql_close(pConn);
}
else
{
if (!success)
{
cout << "Could not connect, as expected. Reported error: " << mysql_error(pMysql) << endl;
rv = EXIT_SUCCESS;
}
else
{
cerr << "Error: " << mysql_error(pMysql) << endl;
}
mysql_close(pMysql);
}
return rv;
}
}
int main(int argc, char* argv[])
{
int rv = EXIT_SUCCESS;
int opt;
const char* zUser = NULL;
const char* zPassword = NULL;
const char* zAddress = NULL;
const char* zHost = "127.0.0.1";
bool success = true;
while ((opt = getopt(argc, argv, "a:h:p:s:u:")) != -1)
{
switch (opt)
{
case 'a':
zAddress = optarg;
break;
case 'h':
zHost = optarg;
break;
case 'p':
zPassword = optarg;
break;
case 's':
success = (atoi(optarg) == 0) ? false : true;
break;
case 'u':
zUser = optarg;
break;
default:
rv = EXIT_FAILURE;
}
}
if ((rv == EXIT_SUCCESS) && zUser)
{
cout << "User : " << zUser << endl;
cout << "Password: " << (zPassword ? zPassword : "(none)") << endl;
cout << "Server : " << zHost << endl;
cout << "Address : " << (zAddress ? zAddress : "(default)") << endl;
cout << "Success : " << success << endl;
cout << endl;
rv = test(success, zHost, zUser, zPassword, zAddress);
}
else
{
cerr << USAGE << endl;
}
return rv;
}