1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

merge from 3.0.0 fixes

This commit is contained in:
Georg Richter
2015-12-29 21:06:23 +01:00
parent c8648cf4b2
commit a3bb1d2009
50 changed files with 2499 additions and 388 deletions

View File

@@ -4,6 +4,8 @@
# This is the LGPL libmariadb project.
PROJECT(mariadb-connector-c C)
SET(PACKAGE_STATUS_SUFFIX "alpha")
SET(CPACK_PACKAGE_VERSION_MAJOR 3)
SET(CPACK_PACKAGE_VERSION_MINOR 0)
SET(CPACK_PACKAGE_VERSION_PATCH 0)
@@ -154,6 +156,10 @@ IF(CMAKE_HAVE_PTHREAD_H)
SET(CMAKE_REQUIRED_INCLUDES pthread.h)
ENDIF()
IF(DBUG_OFF)
ADD_DEFINITIONS(-DDBUG_OFF=1)
ENDIF()
IF(WIN32)
SET(HAVE_THREADS 1)
ADD_DEFINITIONS(-DHAVE_DLOPEN)
@@ -271,12 +277,16 @@ SET(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab")
SET(CPACK_PACKAGE_DESCRIPTION "MariaDB Connector/C. A library for connecting to MariaDB and MySQL servers")
SET(CPACK_PACKAGE_NAME "mariadb_connector_c")
STRING(TOLOWER ${CMAKE_SYSTEM_NAME} system_name)
SET(CPACK_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-${system_name}-${CMAKE_SYSTEM_PROCESSOR}")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.LIB")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
INCLUDE(cmake/ConnectorName.cmake)
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-src")
IF(NOT PACKAGE_STATUS_SUFFIX)
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-src")
SET(CPACK_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-${system_name}-${CMAKE_SYSTEM_PROCESSOR}")
ELSE()
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-${PACKAGE_STATUS_SUFFIX}-src")
SET(CPACK_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-${PACKAGE_STATUS_SUFFIX}-${system_name}-${CMAKE_SYSTEM_PROCESSOR}")
ENDIF()
# Build source packages
IF(GIT_BUILD_SRCPKG)
# get branch name
@@ -285,10 +295,10 @@ IF(GIT_BUILD_SRCPKG)
STRING(REGEX REPLACE "\\[|\\]" "" GIT_BRANCH ${git_branch})
MESSAGE(STATUS "${GIT_BRANCH}")
IF(WIN32)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip)
ELSE()
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=tar --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=tar --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar)
EXECUTE_PROCESS(COMMAND gzip -9 -f ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar)
ENDIF()
ENDIF()

29
appveyor.yml Normal file
View File

@@ -0,0 +1,29 @@
version: 3.0.0.{build}
branches:
only:
- master
os: Visual Studio 2015
configuration: RelWithDebInfo
platform: x64
clone_folder: c:\projects\mariadb-connector-c
environment:
MYSQL_TEST_USER: root
MYSQL_TEST_HOST: 127.0.0.1
MYSQL_TEST_PASSWD: Password12!
services: mysql56
before_build:
- ps: >-
cd c:\projects\mariadb-connector-c
echo running cmake
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE=RelWithDebInfo
build:
project: mariadb-connector-c.sln
parallel: true
verbosity: minimal
test_script:
- cmd: >-
cd c:\projects\mariadb-connector-c\unittest\libmariadb
ctest -V

View File

@@ -1,12 +1,16 @@
# plugin configuration
MACRO(REGISTER_PLUGIN name source struct type target allow)
SET(PLUGIN_TYPE ${${name}})
IF(NOT PLUGIN_TYPE STREQUAL "OFF")
SET(PLUGIN_TYPE ${type})
ENDIF()
IF(PLUGINS)
LIST(REMOVE_ITEM PLUGINS ${name})
ENDIF()
SET(${name}_PLUGIN_SOURCE ${source})
MARK_AS_ADVANCED(${name}_PLUGIN_SOURCE})
SET(${name}_PLUGIN_TYPE ${type})
SET(${name}_PLUGIN_TYPE ${PLUGIN_TYPE})
IF(NOT ${target} STREQUAL "")
SET(${name}_PLUGIN_TARGET ${target})
ENDIF()
@@ -40,7 +44,8 @@ ENDIF()
REGISTER_PLUGIN("TRACE_EXAMPLE" "${CMAKE_SOURCE_DIR}/plugins/trace/trace_example.c" "trace_example_plugin" "DYNAMIC" "trace_example" 1)
#Connection
REGISTER_PLUGIN("REPLICATION" "${CMAKE_SOURCE_DIR}/plugins/connection/replication.c" "connection_replication_plugin" "STATIC" "" 1)
REGISTER_PLUGIN("REPLICATION" "${CMAKE_SOURCE_DIR}/plugins/connection/replication.c" "connection_replication_plugin" "DYNAMIC" "" 1)
REGISTER_PLUGIN("AURORA" "${CMAKE_SOURCE_DIR}/plugins/connection/aurora.c" "connection_aurora_plugin" "DYNAMIC" "" 1)
# Allow registration of additional plugins
IF(PLUGIN_CONF_FILE)
@@ -50,7 +55,7 @@ ENDIF()
SET(LIBMARIADB_SOURCES "")
MESSAGE(STATUS "Plugin configuration")
MESSAGE(STATUS "Plugin configuration:")
FOREACH(PLUGIN ${PLUGINS})
IF(WITH_${PLUGIN}_PLUGIN AND ${${PLUGIN}_PLUGIN_CHG} GREATER 0)
SET(${PLUGIN}_PLUGIN_TYPE ${WITH_${PLUGIN}_PLUGIN})
@@ -72,6 +77,6 @@ ENDIF()
LIST(REMOVE_DUPLICATES LIBMARIADB_SOURCES)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/libmariadb/client_plugin.c.in
${CMAKE_BINARY_DIR}/libmariadb/client_plugin.c)
${CMAKE_BINARY_DIR}/libmariadb/client_plugin.c)
MARK_AS_ADVANCED(LIBMARIADB_SOURCES)

View File

@@ -84,7 +84,8 @@ extern const char *mariadb_client_errors[]; /* Error messages */
#define CR_EVENT_CREATE_FAILED 5000
#define CR_BIND_ADDR_FAILED 5001
#define CR_FUNCTION_NOT_SUPPORTED 5002
#define CR_ASYNC_NOT_SUPPORTED 5002
#define CR_FUNCTION_NOT_SUPPORTED 5003
#define SQLSTATE_UNKNOWN "HY000"

View File

@@ -48,12 +48,15 @@ struct st_mysql_options_extension {
double progress,
const char *proc_info,
unsigned int proc_info_length);
MARIADB_DB_DRIVER *db_driver;
MARIADB_DB_DRIVER *db_driver;
char *ssl_fp; /* finger print of server certificate */
char *ssl_fp_list; /* white list of finger prints */
char *ssl_pw; /* password for encrypted certificates */
my_bool multi_command; /* indicates if client wants to send multiple
commands in one packet */
char *url; /* for connection handler we need to save URL for reconnect */
my_bool read_only;
HASH userdata;
};
#define OPT_HAS_EXT_VAL(a,key) \

View File

@@ -50,7 +50,8 @@ enum enum_pvio_io_event
enum enum_pvio_type {
PVIO_TYPE_UNIXSOCKET= 0,
PVIO_TYPE_SOCKET,
PVIO_TYPE_NAMEDPIPE
PVIO_TYPE_NAMEDPIPE,
PVIO_TYPE_SHAREDMEM,
};
enum enum_pvio_operation {

View File

@@ -16,6 +16,11 @@ typedef struct st_ma_pvio_ssl {
void *ssl;
} MARIADB_SSL;
struct st_ssl_version {
unsigned int iversion;
char *cversion;
};
/* Function prototypes */
/* ma_ssl_start
@@ -124,6 +129,17 @@ const char *ma_ssl_get_cipher(MARIADB_SSL *ssl);
*/
unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsigned int fp_len);
/* ma_ssl_get_protocol_version
returns protocol version in use
Parameter:
MARIADB_SSL MariaDB SSL container
version pointer to ssl version info
Returns:
0 success
1 error
*/
my_bool ma_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version);
/* Function prototypes */
MARIADB_SSL *ma_pvio_ssl_init(MYSQL *mysql);
my_bool ma_pvio_ssl_connect(MARIADB_SSL *cssl);
@@ -134,5 +150,6 @@ int ma_pvio_ssl_verify_server_cert(MARIADB_SSL *cssl);
const char *ma_pvio_ssl_cipher(MARIADB_SSL *cssl);
my_bool ma_pvio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, const char *fp_list);
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio);
my_bool ma_pvio_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version);
#endif /* _ma_ssl_h_ */

View File

@@ -112,7 +112,6 @@ struct my_context {
};
#endif
/*
Initialize an asynchroneous context object.
Returns 0 on success, non-zero on failure.

View File

@@ -165,6 +165,7 @@ struct st_mysqlnd_stmt_methods
my_bool (*get_attribute)(const MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * value);
my_bool (*set_attribute)(const MYSQL_STMT * stmt, enum enum_stmt_attr_type attr_type, const void * value);
void (*set_error)(MYSQL_STMT *stmt, unsigned int error_nr, const char *sqlstate, const char *format, ...);
};
typedef int (*mysql_stmt_fetch_row_func)(MYSQL_STMT *stmt, unsigned char **row);

View File

@@ -215,7 +215,38 @@ extern unsigned int mariadb_deinitialize_ssl;
MARIADB_OPT_SSL_FP_LIST, /* finger print white list for server certificate verification */
MARIADB_OPT_SSL_PASSWORD, /* password for encrypted certificates */
MARIADB_OPT_COM_MULTI,
MARIADB_OPT_CONNECTION_READ_ONLY
MARIADB_OPT_CONNECTION_READ_ONLY,
MYSQL_OPT_CONNECT_ATTRS, /* for mysql_get_optionv */
MARIADB_OPT_USERDATA
};
enum mariadb_value {
MARIADB_CHARSET_ID,
MARIADB_CHARSET_INFO,
MARIADB_CHARSET_NAME,
MARIADB_CLIENT_ERRORS,
MARIADB_CLIENT_VERSION,
MARIADB_CLIENT_VERSION_ID,
MARIADB_CONNECTION_ASYNC_TIMEOUT,
MARIADB_CONNECTION_ASYNC_TIMEOUT_MS,
MARIADB_CONNECTION_HOST,
MARIADB_CONNECTION_INFO,
MARIADB_CONNECTION_PORT,
MARIADB_CONNECTION_PROTOCOL_VERSION_ID,
MARIADB_CONNECTION_PVIO_TYPE,
MARIADB_CONNECTION_SCHEMA,
MARIADB_CONNECTION_SERVER_TYPE,
MARIADB_CONNECTION_SERVER_VERSION,
MARIADB_CONNECTION_SERVER_VERSION_ID,
MARIADB_CONNECTION_SOCKET,
MARIADB_CONNECTION_SSL_CIPHER,
MARIADB_CONNECTION_SSL_VERSION,
MARIADB_CONNECTION_SSL_VERSION_ID,
MARIADB_CONNECTION_TYPE,
MARIADB_CONNECTION_UNIX_SOCKET,
MARIADB_CONNECTION_USER,
MARIADB_MAX_ALLOWED_PACKET,
MARIADB_NET_BUFFER_LENGTH
};
enum mysql_status { MYSQL_STATUS_READY,
@@ -407,12 +438,13 @@ const char * STDCALL mysql_character_set_name(MYSQL *mysql);
void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *cs);
int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname);
my_bool STDCALL mariadb_get_infov(MYSQL *mysql, enum mariadb_value value, void *arg, ...);
my_bool STDCALL mariadb_get_info(MYSQL *mysql, enum mariadb_value value, void *arg);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
const char *capath, const char *cipher);
const char * STDCALL mysql_get_ssl_cipher(MYSQL *mysql);
int STDCALL mysql_ssl_clear(MYSQL *mysql);
MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
const char *user, const char *passwd);
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
@@ -471,7 +503,6 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
void STDCALL mysql_debug(const char *debug);
#define mysql_debug_init(A) mysql_debug((A));
void STDCALL mysql_debug_end(void);
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
const char * STDCALL mysql_sqlstate(MYSQL *mysql);
@@ -485,16 +516,19 @@ const char * STDCALL mysql_get_client_info(void);
unsigned long STDCALL mysql_get_client_version(void);
my_bool STDCALL mariadb_connection(MYSQL *mysql);
const char * STDCALL mysql_get_server_name(MYSQL *mysql);
CHARSET_INFO * STDCALL mysql_get_charset_by_name(const char *csname);
CHARSET_INFO * STDCALL mysql_get_charset_by_nr(unsigned int csnr);
CHARSET_INFO * STDCALL mariadb_get_charset_by_name(const char *csname);
CHARSET_INFO * STDCALL mariadb_get_charset_by_nr(unsigned int csnr);
size_t STDCALL mariadb_convert_string(const char *from, size_t *from_len, CHARSET_INFO *from_cs,
char *to, size_t *to_len, CHARSET_INFO *to_cs, int *errorcode);
int STDCALL mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...);
int STDCALL mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...);
int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option, void *arg);
MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void);
unsigned long STDCALL mysql_hex_string(char *to, const char *from, size_t len);
my_socket STDCALL mysql_get_socket(const MYSQL *mysql);
my_socket STDCALL mysql_get_socket(MYSQL *mysql);
unsigned int STDCALL mysql_get_timeout_value(const MYSQL *mysql);
unsigned int STDCALL mysql_get_timeout_value_ms(const MYSQL *mysql);
my_bool STDCALL mysql_reconnect(MYSQL *mysql);
/* Async API */
int STDCALL mysql_close_start(MYSQL *sock);
@@ -607,6 +641,128 @@ int STDCALL mysql_stmt_send_long_data_cont(my_bool *ret, MYSQL_STMT *stmt,
int status);
/* API function calls (used by dynmic plugins) */
struct st_mariadb_api {
my_ulonglong (STDCALL *mysql_num_rows)(MYSQL_RES *res);
unsigned int (STDCALL *mysql_num_fields)(MYSQL_RES *res);
my_bool (STDCALL *mysql_eof)(MYSQL_RES *res);
MYSQL_FIELD *(STDCALL *mysql_fetch_field_direct)(MYSQL_RES *res, unsigned int fieldnr);
MYSQL_FIELD * (STDCALL *mysql_fetch_fields)(MYSQL_RES *res);
MYSQL_ROWS * (STDCALL *mysql_row_tell)(MYSQL_RES *res);
unsigned int (STDCALL *mysql_field_tell)(MYSQL_RES *res);
unsigned int (STDCALL *mysql_field_count)(MYSQL *mysql);
my_bool (STDCALL *mysql_more_results)(MYSQL *mysql);
int (STDCALL *mysql_next_result)(MYSQL *mysql);
my_ulonglong (STDCALL *mysql_affected_rows)(MYSQL *mysql);
my_bool (STDCALL *mysql_autocommit)(MYSQL *mysql, my_bool mode);
my_bool (STDCALL *mysql_commit)(MYSQL *mysql);
my_bool (STDCALL *mysql_rollback)(MYSQL *mysql);
my_ulonglong (STDCALL *mysql_insert_id)(MYSQL *mysql);
unsigned int (STDCALL *mysql_errno)(MYSQL *mysql);
char * (STDCALL *mysql_error)(MYSQL *mysql);
char * (STDCALL *mysql_info)(MYSQL *mysql);
unsigned long (STDCALL *mysql_thread_id)(MYSQL *mysql);
const char * (STDCALL *mysql_character_set_name)(MYSQL *mysql);
void (STDCALL *mysql_get_character_set_info)(MYSQL *mysql, MY_CHARSET_INFO *cs);
int (STDCALL *mysql_set_character_set)(MYSQL *mysql, const char *csname);
my_bool (STDCALL *mariadb_get_infov)(MYSQL *mysql, enum mariadb_value value, void *arg, ...);
my_bool (STDCALL *mariadb_get_info)(MYSQL *mysql, enum mariadb_value value, void *arg);
MYSQL * (STDCALL *mysql_init)(MYSQL *mysql);
int (STDCALL *mysql_ssl_set)(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher);
const char * (STDCALL *mysql_get_ssl_cipher)(MYSQL *mysql);
MYSQL * (STDCALL *mysql_connect)(MYSQL *mysql, const char *host, const char *user, const char *passwd);
my_bool (STDCALL *mysql_change_user)(MYSQL *mysql, const char *user, const char *passwd, const char *db);
MYSQL * (STDCALL *mysql_real_connect)(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag);
void (STDCALL *mysql_close)(MYSQL *sock);
int (STDCALL *mysql_select_db)(MYSQL *mysql, const char *db);
int (STDCALL *mysql_query)(MYSQL *mysql, const char *q);
int (STDCALL *mysql_send_query)(MYSQL *mysql, const char *q, size_t length);
my_bool (STDCALL *mysql_read_query_result)(MYSQL *mysql);
int (STDCALL *mysql_real_query)(MYSQL *mysql, const char *q, size_t length);
int (STDCALL *mysql_create_db)(MYSQL *mysql, const char *DB);
int (STDCALL *mysql_drop_db)(MYSQL *mysql, const char *DB);
int (STDCALL *mysql_shutdown)(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level);
int (STDCALL *mysql_dump_debug_info)(MYSQL *mysql);
int (STDCALL *mysql_refresh)(MYSQL *mysql, unsigned int refresh_options);
int (STDCALL *mysql_kill)(MYSQL *mysql,unsigned long pid);
int (STDCALL *mysql_ping)(MYSQL *mysql);
char * (STDCALL *mysql_stat)(MYSQL *mysql);
char * (STDCALL *mysql_get_server_info)(MYSQL *mysql);
unsigned long (STDCALL *mysql_get_server_version)(MYSQL *mysql);
char * (STDCALL *mysql_get_host_info)(MYSQL *mysql);
unsigned int (STDCALL *mysql_get_proto_info)(MYSQL *mysql);
MYSQL_RES * (STDCALL *mysql_list_dbs)(MYSQL *mysql,const char *wild);
MYSQL_RES * (STDCALL *mysql_list_tables)(MYSQL *mysql,const char *wild);
MYSQL_RES * (STDCALL *mysql_list_fields)(MYSQL *mysql, const char *table, const char *wild);
MYSQL_RES * (STDCALL *mysql_list_processes)(MYSQL *mysql);
MYSQL_RES * (STDCALL *mysql_store_result)(MYSQL *mysql);
MYSQL_RES * (STDCALL *mysql_use_result)(MYSQL *mysql);
int (STDCALL *mysql_options)(MYSQL *mysql,enum mysql_option option, const void *arg);
void (STDCALL *mysql_free_result)(MYSQL_RES *result);
void (STDCALL *mysql_data_seek)(MYSQL_RES *result, my_ulonglong offset);
MYSQL_ROW_OFFSET (STDCALL *mysql_row_seek)(MYSQL_RES *result, MYSQL_ROW_OFFSET);
MYSQL_FIELD_OFFSET (STDCALL *mysql_field_seek)(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset);
MYSQL_ROW (STDCALL *mysql_fetch_row)(MYSQL_RES *result);
unsigned long * (STDCALL *mysql_fetch_lengths)(MYSQL_RES *result);
MYSQL_FIELD * (STDCALL *mysql_fetch_field)(MYSQL_RES *result);
unsigned long (STDCALL *mysql_escape_string)(char *to,const char *from, unsigned long from_length);
unsigned long (STDCALL *mysql_real_escape_string)(MYSQL *mysql, char *to,const char *from, unsigned long length);
void (STDCALL *mysql_debug)(const char *debug);
void (STDCALL *mysql_debug_end)(void);
unsigned int (STDCALL *mysql_thread_safe)(void);
unsigned int (STDCALL *mysql_warning_count)(MYSQL *mysql);
const char * (STDCALL *mysql_sqlstate)(MYSQL *mysql);
int (STDCALL *mysql_server_init)(int argc, char **argv, char **groups);
void (STDCALL *mysql_server_end)(void);
void (STDCALL *mysql_thread_end)(void);
my_bool (STDCALL *mysql_thread_init)(void);
int (STDCALL *mysql_set_server_option)(MYSQL *mysql, enum enum_mysql_set_option option);
const char * (STDCALL *mysql_get_client_info)(void);
unsigned long (STDCALL *mysql_get_client_version)(void);
my_bool (STDCALL *mariadb_connection)(MYSQL *mysql);
const char * (STDCALL *mysql_get_server_name)(MYSQL *mysql);
CHARSET_INFO * (STDCALL *mariadb_get_charset_by_name)(const char *csname);
CHARSET_INFO * (STDCALL *mariadb_get_charset_by_nr)(unsigned int csnr);
size_t (STDCALL *mariadb_convert_string)(const char *from, size_t *from_len, CHARSET_INFO *from_cs, char *to, size_t *to_len, CHARSET_INFO *to_cs, int *errorcode);
int (STDCALL *mysql_optionsv)(MYSQL *mysql,enum mysql_option option, ...);
int (STDCALL *mysql_get_optionv)(MYSQL *mysql, enum mysql_option option, void *arg, ...);
int (STDCALL *mysql_get_option)(MYSQL *mysql, enum mysql_option option, void *arg);
MYSQL_PARAMETERS *(STDCALL *mysql_get_parameters)(void);
unsigned long (STDCALL *mysql_hex_string)(char *to, const char *from, size_t len);
my_socket (STDCALL *mysql_get_socket)(MYSQL *mysql);
unsigned int (STDCALL *mysql_get_timeout_value)(const MYSQL *mysql);
unsigned int (STDCALL *mysql_get_timeout_value_ms)(const MYSQL *mysql);
my_bool (STDCALL *mysql_reconnect)(MYSQL *mysql);
MYSQL_STMT * (STDCALL *mysql_stmt_init)(MYSQL *mysql);
int (STDCALL *mysql_stmt_prepare)(MYSQL_STMT *stmt, const char *query, size_t length);
int (STDCALL *mysql_stmt_execute)(MYSQL_STMT *stmt);
int (STDCALL *mysql_stmt_fetch)(MYSQL_STMT *stmt);
int (STDCALL *mysql_stmt_fetch_column)(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, unsigned int column, unsigned long offset);
int (STDCALL *mysql_stmt_store_result)(MYSQL_STMT *stmt);
unsigned long (STDCALL *mysql_stmt_param_count)(MYSQL_STMT * stmt);
my_bool (STDCALL *mysql_stmt_attr_set)(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, const void *attr);
my_bool (STDCALL *mysql_stmt_attr_get)(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, void *attr);
my_bool (STDCALL *mysql_stmt_bind_param)(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
my_bool (STDCALL *mysql_stmt_bind_result)(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
my_bool (STDCALL *mysql_stmt_close)(MYSQL_STMT * stmt);
my_bool (STDCALL *mysql_stmt_reset)(MYSQL_STMT * stmt);
my_bool (STDCALL *mysql_stmt_free_result)(MYSQL_STMT *stmt);
my_bool (STDCALL *mysql_stmt_send_long_data)(MYSQL_STMT *stmt, unsigned int param_number, const char *data, size_t length);
MYSQL_RES *(STDCALL *mysql_stmt_result_metadata)(MYSQL_STMT *stmt);
MYSQL_RES *(STDCALL *mysql_stmt_param_metadata)(MYSQL_STMT *stmt);
unsigned int (STDCALL *mysql_stmt_errno)(MYSQL_STMT * stmt);
const char *(STDCALL *mysql_stmt_error)(MYSQL_STMT * stmt);
const char *(STDCALL *mysql_stmt_sqlstate)(MYSQL_STMT * stmt);
MYSQL_ROW_OFFSET (STDCALL *mysql_stmt_row_seek)(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset);
MYSQL_ROW_OFFSET (STDCALL *mysql_stmt_row_tell)(MYSQL_STMT *stmt);
void (STDCALL *mysql_stmt_data_seek)(MYSQL_STMT *stmt, my_ulonglong offset);
my_ulonglong (STDCALL *mysql_stmt_num_rows)(MYSQL_STMT *stmt);
my_ulonglong (STDCALL *mysql_stmt_affected_rows)(MYSQL_STMT *stmt);
my_ulonglong (STDCALL *mysql_stmt_insert_id)(MYSQL_STMT *stmt);
unsigned int (STDCALL *mysql_stmt_field_count)(MYSQL_STMT *stmt);
int (STDCALL *mysql_stmt_next_result)(MYSQL_STMT *stmt);
my_bool (STDCALL *mysql_stmt_more_results)(MYSQL_STMT *stmt);
};
/* these methods can be overwritten by db plugins */
struct st_mysql_methods {
@@ -630,6 +786,8 @@ struct st_mysql_methods {
int (*db_stmt_fetch_to_bind)(MYSQL_STMT *stmt, unsigned char *row);
void (*db_stmt_flush_unbuffered)(MYSQL_STMT *stmt);
void (*set_error)(MYSQL *mysql, unsigned int error_nr, const char *sqlstate, const char *format, ...);
void (*invalidate_stmts)(MYSQL *mysql, const char *function_name);
struct st_mariadb_api *api;
};
/* synonyms/aliases functions */

View File

@@ -95,6 +95,7 @@ typedef struct st_ma_connection_plugin
int (*options)(MYSQL *mysql, enum mysql_option, void *arg);
int (*set_connection)(MYSQL *mysql,enum enum_server_command command, const char *arg,
size_t length, my_bool skipp_check, void *opt_arg);
my_bool (*reconnect)(MYSQL *mysql);
} MARIADB_CONNECTION_PLUGIN;
#define MARIADB_DB_DRIVER(a) ((a)->ext_db)

View File

@@ -240,6 +240,7 @@ typedef struct st_connection_handler
{
struct st_ma_connection_plugin *plugin;
void *data;
my_bool active;
my_bool free_data;
} MA_CONNECTION_HANDLER;
@@ -375,6 +376,12 @@ typedef struct st_udf_init
my_bool const_item; /* 0 if result is independent of arguments */
} UDF_INIT;
/* Connection types */
#define MARIADB_CONNECTION_UNIXSOCKET 0
#define MARIADB_CONNECTION_TCP 1
#define MARIADB_CONNECTION_NAMEDPIPE 2
#define MARIADB_CONNECTION_SHAREDMEM 3
/* Constants when using compression */
#define NET_HEADER_SIZE 4 /* standard header size */
#define COMP_HEADER_SIZE 3 /* compression header extra size */

View File

@@ -35,7 +35,10 @@ SET(EXPORT_SYMBOLS
mariadb_dyncol_val_long
mariadb_dyncol_val_str
mariadb_flush_multi_command
myodbc_remove_escape
mariadb_get_charset_by_name
mariadb_get_charset_by_nr
mariadb_get_info
mariadb_get_infov
mysql_affected_rows
mysql_autocommit
mysql_autocommit_cont
@@ -80,6 +83,8 @@ SET(EXPORT_SYMBOLS
mysql_get_client_info
mysql_get_client_version
mysql_get_host_info
mysql_get_option
mysql_get_optionv
mysql_get_parameters
mysql_get_proto_info
mysql_get_server_info
@@ -125,6 +130,7 @@ SET(EXPORT_SYMBOLS
mysql_query
mysql_query_cont
mysql_query_start
mysql_reconnect
mysql_read_query_result
mysql_read_query_result_cont
mysql_read_query_result_start

View File

@@ -149,7 +149,8 @@ const char *mariadb_client_errors[] =
{
/* 5000 */ "Creating an event failed (Errorcode: %d)",
/* 5001 */ "Bind to local interface '-.%64s' failed (Errorcode: %d)",
/* 5002 */ "Server doesn't support function '%s'",
/* 5002 */ "Connection type doesn't support asynchronous IO operations",
/* 5003 */ "Server doesn't support function '%s'",
""
};

File diff suppressed because it is too large Load Diff

View File

@@ -1114,7 +1114,7 @@ dynamic_column_string_read(DYNAMIC_COLUMN_VALUE *store_it_here,
#ifndef LIBMARIADB
store_it_here->x.string.charset= get_charset_by_nr(charset_nr);
#else
store_it_here->x.string.charset= mysql_get_charset_by_nr(charset_nr);
store_it_here->x.string.charset= mariadb_get_charset_by_nr(charset_nr);
#endif
if (store_it_here->x.string.charset == NULL)
return ER_DYNCOL_UNKNOWN_CHARSET;

View File

@@ -71,7 +71,7 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo)
* pvio_socket
* pvio_namedpipe
*/
char *pvio_plugins[] = {"pvio_socket", "pvio_npipe"};
char *pvio_plugins[] = {"pvio_socket", "pvio_npipe", "pvio_shmem"};
int type;
MARIADB_PVIO_PLUGIN *pvio_plugin;
MARIADB_PVIO *pvio= NULL;
@@ -86,6 +86,9 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo)
case PVIO_TYPE_NAMEDPIPE:
type= 1;
break;
case PVIO_TYPE_SHAREDMEM:
type= 2;
break;
#endif
default:
return NULL;
@@ -96,7 +99,6 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo)
pvio_plugins[type],
MARIADB_CLIENT_PVIO_PLUGIN)))
{
/* error handling */
return NULL;
}
@@ -111,6 +113,7 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo)
/* register error routine and methods */
pvio->methods= pvio_plugin->methods;
pvio->set_error= my_set_error;
pvio->type= cinfo->type;
/* set tineouts */
if (pvio->methods->set_timeout)
@@ -180,9 +183,14 @@ static size_t ma_pvio_read_async(MARIADB_PVIO *pvio, uchar *buffer, size_t lengt
struct mysql_async_context *b= pvio->mysql->options.extension->async_context;
int timeout= pvio->timeout[PVIO_READ_TIMEOUT];
if (!pvio->methods->async_read)
{
PVIO_SET_ERROR(pvio->mysql, CR_ASYNC_NOT_SUPPORTED, unknown_sqlstate, 0);
return -1;
}
for (;;)
{
/* todo: async */
if (pvio->methods->async_read)
res= pvio->methods->async_read(pvio, buffer, length);
if (res >= 0 || IS_BLOCKING_ERROR())
@@ -482,7 +490,7 @@ my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
/* check if we still have unread data in cache */
if (pvio->cache)
if (pvio->cache_pos > pvio->cache)
return pvio->cache_pos - pvio->cache;
return test(pvio->cache_pos - pvio->cache);
if (pvio && pvio->methods->has_data)
return pvio->methods->has_data(pvio, data_len);
return 1;

View File

@@ -51,6 +51,8 @@
my_bool ma_ssl_initialized= FALSE;
unsigned int mariadb_deinitialize_ssl= 1;
char *ssl_protocol_version[5]= {"unknown", "SSL3", "TLS1.0", "TLS1.1", "TLS1.2"};
MARIADB_SSL *ma_pvio_ssl_init(MYSQL *mysql)
{
MARIADB_SSL *cssl= NULL;
@@ -104,6 +106,11 @@ const char *ma_pvio_ssl_cipher(MARIADB_SSL *cssl)
return ma_ssl_get_cipher(cssl);
}
my_bool ma_pvio_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version)
{
return ma_ssl_get_protocol_version(cssl, version);
}
static my_bool ma_pvio_ssl_compare_fp(char *fp1, unsigned int fp1_len,
char *fp2, unsigned int fp2_len)
{

View File

@@ -73,8 +73,6 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */
size_t lCurMemory = 0L; /* Current memory usage */
size_t lMaxMemory = 0L; /* Maximum memory usage */
uint cNewCount = 0; /* Number of times NEW() was called */
unsigned char *sf_min_adress= (unsigned char*) ~(unsigned long) 0L,
*sf_max_adress= (unsigned char*) 0L;
/* Root of the linked list of remembers */
struct remember *pRememberRoot = NULL;

View File

@@ -61,7 +61,6 @@ extern uint my_once_extra;
extern int _my_tempnam_used;
#endif
extern unsigned char *sf_min_adress,*sf_max_adress;
extern uint cNewCount;
extern struct remember *pRememberRoot;

View File

@@ -416,7 +416,6 @@ int store_param(MYSQL_STMT *stmt, int column, unsigned char **p)
{
DBUG_ENTER("store_param");
DBUG_PRINT("info", ("column: %d type: %d", column, stmt->params[column].buffer_type));
printf("type: %d\n", column, stmt->params[column].buffer_type);
switch (stmt->params[column].buffer_type) {
case MYSQL_TYPE_TINY:
int1store(*p, *(uchar *)stmt->params[column].buffer);

View File

@@ -394,7 +394,7 @@ MK_ASYNC_CONT_BODY(
struct mysql_real_query_params {
MYSQL *mysql;
const char *stmt_str;
unsigned long length;
size_t length;
};
static void
mysql_real_query_start_internal(void *d)
@@ -578,7 +578,7 @@ MK_ASYNC_CONT_BODY(
struct mysql_send_query_params {
MYSQL *mysql;
const char *q;
unsigned long length;
size_t length;
};
static void
mysql_send_query_start_internal(void *d)
@@ -1311,7 +1311,7 @@ MK_ASYNC_CONT_BODY(
struct mysql_stmt_prepare_params {
MYSQL_STMT *stmt;
const char *query;
unsigned long length;
size_t length;
};
static void
mysql_stmt_prepare_start_internal(void *d)
@@ -1614,7 +1614,7 @@ struct mysql_stmt_send_long_data_params {
MYSQL_STMT *stmt;
unsigned int param_number;
const char *data;
unsigned long length;
size_t length;
};
static void
mysql_stmt_send_long_data_start_internal(void *d)

View File

@@ -193,10 +193,11 @@ static my_bool net_realloc(NET *net, my_bool is_multi, size_t length)
}
/* Remove unwanted characters from connection */
void net_clear(NET *net)
{
size_t len;
DBUG_ENTER("net_clear");
ma_pvio_has_data(net->pvio, &len);
net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
net->write_pos=net->buff;
if (net->mbuff)
@@ -204,13 +205,12 @@ void net_clear(NET *net)
DBUG_VOID_RETURN;
}
/* Flush write_buffer if not empty. */
int net_flush(NET *net)
{
int error=0;
DBUG_ENTER("net_flush");
if (net->buff != net->write_pos)
{
error=net_real_write(net,(char*) net->buff,
@@ -222,12 +222,10 @@ int net_flush(NET *net)
DBUG_RETURN(error);
}
/*****************************************************************************
** Write something to server/client buffer
*****************************************************************************/
/*
** Write a logical packet with packet header
** Format: Packet length (3 bytes), packet number(1 byte)

View File

@@ -423,5 +423,13 @@ unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsig
}
}
#endif /* HAVE_GNUTLS */
my_bool ma_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version)
{
if (!cssl || !cssl->ssl)
return 1;
version->iversion= gnutls_protocol_get_version(cssl->ssl);
version->cversion= (char *)gnutls_protocol_get_name(version->iversion);
return 0;
}
#endif /* HAVE_GNUTLS */

View File

@@ -338,7 +338,7 @@ my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, CERT_CONTEXT *ctx, char
goto end;
}
/* ... and import the private key */
if (!CryptImportKey(crypt_prov, priv_key, priv_key_len, NULL, 0, (HCRYPTKEY *)&crypt_key))
if (!CryptImportKey(crypt_prov, priv_key, priv_key_len, 0, 0, (HCRYPTKEY *)&crypt_key))
{
ma_schannel_set_win_error(pvio);
goto end;
@@ -427,7 +427,7 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
{
if(fDoRead)
{
cbData = pvio->methods->read(pvio, IoBuffer + cbIoBuffer, (size_t)(SC_IO_BUFFER_SIZE - cbIoBuffer));
cbData = (DWORD)pvio->methods->read(pvio, IoBuffer + cbIoBuffer, (size_t)(SC_IO_BUFFER_SIZE - cbIoBuffer));
if (cbData == SOCKET_ERROR || cbData == 0)
{
rc = SEC_E_INTERNAL_ERROR;
@@ -486,7 +486,7 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
{
if(OutBuffers[0].cbBuffer && OutBuffers[0].pvBuffer)
{
cbData= pvio->methods->write(pvio, (uchar *)OutBuffers[0].pvBuffer, (size_t)OutBuffers[0].cbBuffer);
cbData= (DWORD)pvio->methods->write(pvio, (uchar *)OutBuffers[0].pvBuffer, (size_t)OutBuffers[0].cbBuffer);
if(cbData == SOCKET_ERROR || cbData == 0)
{
FreeContextBuffer(OutBuffers[0].pvBuffer);
@@ -626,18 +626,10 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl)
return sRet;
}
/* Allocate IO-Buffer */
sctx->IoBufferSize= 2 * net_buffer_length;
if (!(sctx->IoBuffer= (PUCHAR)LocalAlloc(LMEM_ZEROINIT, sctx->IoBufferSize)))
{
sRet= SEC_E_INSUFFICIENT_MEMORY;
goto end;
}
/* send client hello packaet */
if(BuffersOut[0].cbBuffer != 0 && BuffersOut[0].pvBuffer != NULL)
{
r= pvio->methods->write(pvio, (uchar *)BuffersOut[0].pvBuffer, (size_t)BuffersOut[0].cbBuffer);
r= (DWORD)pvio->methods->write(pvio, (uchar *)BuffersOut[0].pvBuffer, (size_t)BuffersOut[0].cbBuffer);
if (r <= 0)
{
sRet= SEC_E_INTERNAL_ERROR;
@@ -646,11 +638,17 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_SSL *cssl)
}
sRet= ma_schannel_handshake_loop(pvio, TRUE, &ExtraData);
/* Reallocate IO-Buffer for write operations: After handshake
/* allocate IO-Buffer for write operations: After handshake
was successfull, we are able now to calculate payload */
QueryContextAttributes( &sctx->ctxt, SECPKG_ATTR_STREAM_SIZES, &sctx->Sizes );
if ((sRet = QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_STREAM_SIZES, &sctx->Sizes )))
goto end;
sctx->IoBufferSize= SCHANNEL_PAYLOAD(sctx->Sizes);
sctx->IoBuffer= LocalReAlloc(sctx->IoBuffer, sctx->IoBufferSize, LMEM_ZEROINIT);
if (!(sctx->IoBuffer= (PUCHAR)LocalAlloc(0, sctx->IoBufferSize)))
{
sRet= SEC_E_INSUFFICIENT_MEMORY;
goto end;
}
return sRet;
end:
@@ -697,7 +695,6 @@ SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,
SECURITY_STATUS sRet= 0;
SecBufferDesc Msg;
SecBuffer Buffers[4],
ExtraBuffer,
*pData, *pExtra;
int i;
@@ -711,18 +708,18 @@ SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,
{
if (!dwBytesRead || sRet == SEC_E_INCOMPLETE_MESSAGE)
{
dwBytesRead= pvio->methods->read(pvio, sctx->IoBuffer + dwOffset, (size_t)(sctx->IoBufferSize - dwOffset));
dwBytesRead= (DWORD)pvio->methods->read(pvio, sctx->IoBuffer + dwOffset, (size_t)(sctx->IoBufferSize - dwOffset));
if (dwBytesRead == 0)
{
/* server closed connection */
// todo: error
return NULL;
return SEC_E_INVALID_HANDLE;
}
if (dwBytesRead < 0)
{
/* socket error */
// todo: error
return NULL;
return SEC_E_INVALID_HANDLE;
}
dwOffset+= dwBytesRead;
}
@@ -777,6 +774,7 @@ SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,
dwOffset= 0;
}
}
/* }}} */
my_bool ma_schannel_verify_certs(SC_CTX *sctx, DWORD dwCertFlags)
{
@@ -863,7 +861,7 @@ size_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
SECURITY_STATUS scRet;
SecBufferDesc Message;
SecBuffer Buffers[4];
DWORD cbMessage, cbData;
DWORD cbMessage;
PBYTE pbMessage;
SC_CTX *sctx= (SC_CTX *)pvio->cssl->ssl;
size_t payload;
@@ -903,3 +901,40 @@ size_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
}
/* }}} */
extern char *ssl_protocol_version[5];
/* {{{ ma_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version) */
my_bool ma_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version)
{
SC_CTX *sctx;
SecPkgContext_ConnectionInfo ConnectionInfo;
if (!cssl->ssl)
return 1;
sctx= (SC_CTX *)cssl->ssl;
if (QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_CONNECTION_INFO, &ConnectionInfo) != SEC_E_OK)
return 1;
switch(ConnectionInfo.dwProtocol)
{
case SP_PROT_SSL3_CLIENT:
version->iversion= 1;
break;
case SP_PROT_TLS1_CLIENT:
version->iversion= 2;
break;
case SP_PROT_TLS1_1_CLIENT:
version->iversion= 3;
break;
case SP_PROT_TLS1_2_CLIENT:
version->iversion= 4;
break;
default:
version->iversion= 0;
break;
}
version->cversion= ssl_protocol_version[version->iversion];
return 0;
}
/* }}} */

View File

@@ -177,8 +177,11 @@ int ma_ssl_start(char *errmsg, size_t errmsg_len)
SSL_load_error_strings();
/* digests and ciphers */
OpenSSL_add_all_algorithms();
if (!(SSL_context= SSL_CTX_new(TLSv1_client_method())))
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
if (!(SSL_context= SSL_CTX_new(TLS_client_method())))
#else
if (!(SSL_context= SSL_CTX_new(SSLv23_client_method())))
#endif
{
ma_ssl_get_error(errmsg, errmsg_len);
goto end;
@@ -464,9 +467,13 @@ int ma_ssl_verify_server_cert(MARIADB_SSL *cssl)
{
X509 *cert;
MYSQL *mysql;
MARIADB_PVIO *pvio;
X509_NAME *x509sn;
int cn_pos;
X509_NAME_ENTRY *cn_entry;
ASN1_STRING *cn_asn1;
const char *cn_str;
SSL *ssl;
char *p1, *p2, buf[256];
MARIADB_PVIO *pvio;
if (!cssl || !cssl->ssl)
return 1;
@@ -477,33 +484,46 @@ int ma_ssl_verify_server_cert(MARIADB_SSL *cssl)
if (!mysql->host)
{
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0,
"Invalid (empty) hostname");
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), "Invalid (empty) hostname");
return 1;
}
if (!(cert= SSL_get_peer_certificate(ssl)))
{
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0,
"Unable to get server certificate");
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), "Unable to get server certificate");
return 1;
}
X509_NAME_oneline(X509_get_subject_name(cert), buf, 256);
x509sn= X509_get_subject_name(cert);
if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0)
goto error;
if (!(cn_entry= X509_NAME_get_entry(x509sn, cn_pos)))
goto error;
if (!(cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry)))
goto error;
cn_str = (char *)ASN1_STRING_data(cn_asn1);
/* Make sure there is no embedded \0 in the CN */
if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn_str))
goto error;
if (strcmp(cn_str, mysql->host))
goto error;
X509_free(cert);
/* Extract the server name from buffer:
Format: ....CN=/hostname/.... */
if ((p1= strstr(buf, "/CN=")))
{
p1+= 4;
if ((p2= strchr(p1, '/')))
*p2= 0;
if (!strcmp(mysql->host, p1))
return(0);
}
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0,
"Validation of SSL server certificate failed");
return 0;
error:
X509_free(cert);
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), "Validation of SSL server certificate failed");
return 1;
}
@@ -552,3 +572,37 @@ unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsig
}
return (fp_len);
}
extern char *ssl_protocol_version[5];
my_bool ma_ssl_get_protocol_version(MARIADB_SSL *cssl, struct st_ssl_version *version)
{
SSL *ssl;
if (!cssl || !cssl->ssl)
return 1;
ssl = (SSL *)cssl->ssl;
switch(ssl->version)
{
case SSL3_VERSION:
version->iversion= 1;
break;
case TLS1_VERSION:
version->iversion= 2;
break;
case TLS1_1_VERSION:
version->iversion= 3;
break;
case TLS1_2_VERSION:
version->iversion= 4;
break;
default:
version->iversion= 0;
break;
}
version->cversion= ssl_protocol_version[version->iversion];
return 0;
}

View File

@@ -284,7 +284,7 @@ my_bool ma_ssl_connect(MARIADB_SSL *cssl)
Cred.cCreds = 1;
Cred.paCred = &sctx->client_cert_ctx;
}
Cred.grbitEnabledProtocols= SP_PROT_TLS1;
Cred.grbitEnabledProtocols= SP_PROT_TLS1_1PLUS;
if ((sRet= AcquireCredentialsHandleA(NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND,
NULL, &Cred, NULL, NULL, &sctx->CredHdl, NULL)) != SEC_E_OK)

View File

@@ -0,0 +1,19 @@
#
# pkg_config.pc.in
#
# pkg_config configuration file
# For a detailled description of options, please visit
# Dan Nicholsons Guide to pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config/)
#
includedir=@PREFIX_INSTALL_DIR@/@INCLUDE_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@
libdir=@PREFIX_INSTALL_DIR@/@INCLUDE_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@
prefix=@PREFIX_INSTALL_DIR@
Name: libmariadb
Version: @LIBMARIADB_VERSION@
Description: MariaDB Connector/C dynamic library
Cflags: -I@PREFIX_INSTALL_DIR@/@INCLUDE_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@ @CMAKE_C_FLAGS@
Libs: -L@PREFIX_INSTALL_DIR@/@LIB_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@ -lmariadb @extra_dynamic_LDFLAGS@

View File

@@ -13,10 +13,30 @@ IF(REPLICATION_PLUGIN_TYPE MATCHES "DYNAMIC")
"FILE_DESCRIPTION:Connection plugin for master/slave environment")
ENDIF()
ADD_DEFINITIONS(-DHAVE_REPLICATION_DYNAMIC=1)
ADD_LIBRARY(replication SHARED replication.c ${EXPORT_FILE})
ADD_LIBRARY(replication SHARED ${replication_RC} replication.c ${EXPORT_FILE})
IF(WIN32)
TARGET_LINK_LIBRARIES(replication libmariadb)
ENDIF()
SET(INSTALL_LIBS replication)
ENDIF()
IF(REPLICATION_PLUGIN_TYPE MATCHES "DYNAMIC")
IF(WIN32)
SET_VERSION_INFO("TARGET:aurora"
"FILE_TYPE:VFT_DLL"
"SOURCE_FILE:plugins/connection/aurora.c"
"ORIGINAL_FILE_NAME:aurora.dll"
"FILE_DESCRIPTION:Connection plugin for Amazon AWS Aurora")
ENDIF()
ADD_DEFINITIONS(-DHAVE_AURORA_DYNAMIC=1)
ADD_LIBRARY(aurora SHARED ${aurora_RC} aurora.c ${EXPORT_FILE})
IF(WIN32)
TARGET_LINK_LIBRARIES(aurora libmariadb)
ENDIF()
SET(INSTALL_LIBS ${INSTALL_LIBS} aurora)
ENDIF()
IF(INSTALL_LIBS)
INSTALL(TARGETS
${INSTALL_LIBS}

819
plugins/connection/aurora.c Normal file
View File

@@ -0,0 +1,819 @@
/************************************************************************************
Copyright (C) 2015 MariaDB Corporation AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
Part of this code includes code from the PHP project which
is freely available from http://www.php.net
*************************************************************************************/
/* MariaDB Connection plugin for Aurora failover */
#include <my_global.h>
#include <my_sys.h>
#include <errmsg.h>
#include <ma_common.h>
#include <mysql.h>
#include <mysql/client_plugin.h>
#include <string.h>
#include <m_string.h>
#ifndef WIN32
#include <sys/time.h>
#endif
/* function prototypes */
int aurora_init(char *errormsg, size_t errormsg_size,
int unused __attribute__((unused)),
va_list unused1 __attribute__((unused)));
MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag);
void aurora_close(MYSQL *mysql);
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
size_t length, my_bool skipp_check, void *opt_arg);
int aurora_set_options(MYSQL *msql, enum mysql_option option, void *arg);
my_bool aurora_reconnect(MYSQL *mysql);
#define AURORA_MAX_INSTANCES 16
#define AURORA_UNKNOWN -1
#define AURORA_PRIMARY 0
#define AURORA_REPLICA 1
#define AURORA_UNAVAILABLE 2
#define ENABLE_AURORA(mysql)\
(mysql)->net.conn_hdlr->active= 1;
#define DISABLE_AURORA(mysql)\
(mysql)->net.conn_hdlr->active= 0;
#ifndef HAVE_AURORA_DYNAMIC
MARIADB_CONNECTION_PLUGIN connection_aurora_plugin =
#else
MARIADB_CONNECTION_PLUGIN _mysql_client_plugin_declaration_ =
#endif
{
MARIADB_CLIENT_CONNECTION_PLUGIN,
MARIADB_CLIENT_CONNECTION_PLUGIN_INTERFACE_VERSION,
"aurora",
"Georg Richter",
"MariaDB connection plugin for Aurora failover",
{1, 0, 0},
"LGPL",
aurora_init,
NULL,
aurora_connect,
aurora_close,
aurora_set_options,
aurora_command,
aurora_reconnect
};
struct st_mariadb_api *mariadb_api= NULL;
typedef struct st_aurora_instance {
char *host;
int port;
time_t blacklisted;
int type;
} AURORA_INSTANCE;
typedef struct st_conn_aurora {
MARIADB_PVIO *pvio[2];
MYSQL *mysql[2];
my_bool active[2];
char *url;
unsigned int num_instances;
AURORA_INSTANCE instance[AURORA_MAX_INSTANCES];
char *username, *password, *database;
unsigned int port;
unsigned long client_flag;
unsigned int last_instance_type; /* Primary or Replica */
char primary_id[100];
} AURORA;
#define AURORA_BLACKLIST_TIMEOUT 150
#define AURORA_IS_BLACKLISTED(a, i) \
((time(NULL) - (a)->instance[(i)].blacklisted) < AURORA_BLACKLIST_TIMEOUT)
/* {{{ my_bool aurora_swutch_connection */
my_bool aurora_switch_connection(MYSQL *mysql, AURORA *aurora, int type)
{
switch (type)
{
case AURORA_REPLICA:
if (aurora->mysql[AURORA_REPLICA])
{
mysql->net.pvio= aurora->pvio[AURORA_REPLICA];
aurora->pvio[AURORA_REPLICA]->mysql= mysql;
mysql->thread_id= aurora->mysql[AURORA_REPLICA]->thread_id;
aurora->last_instance_type= AURORA_REPLICA;
}
break;
case AURORA_PRIMARY:
if (aurora->mysql[AURORA_PRIMARY])
{
if (aurora->mysql[AURORA_REPLICA])
aurora->mysql[AURORA_REPLICA]->net.pvio->mysql= aurora->mysql[AURORA_REPLICA];
mysql->net.pvio= aurora->pvio[AURORA_PRIMARY];
mysql->thread_id= aurora->mysql[AURORA_PRIMARY]->thread_id;
aurora->last_instance_type= AURORA_PRIMARY;
}
break;
default:
return 1;
}
return 0;
}
/* }}} */
/* {{{ int aurora_init
*
* plugin initialization function
*/
int aurora_init(char *errormsg, size_t errormsg_size,
int unused __attribute__((unused)),
va_list unused1 __attribute__((unused)))
{
/* random generator initialization */
#ifndef WIN32
struct timeval tp;
gettimeofday(&tp,NULL);
srand(tp.tv_usec / 1000 + tp.tv_sec * 1000);
#else
srand(GetTickCount());
#endif
return 0;
}
/* }}} */
/* {{{ void aurora_close_memory */
void aurora_close_memory(AURORA *aurora)
{
free(aurora->url);
free(aurora->username);
free(aurora->password);
free(aurora->database);
free(aurora);
}
/* }}} */
/* {{{ my_bool aurora_parse_url
*
* parse url
* Url has the following format:
* instance1:port, instance2:port, .., instanceN:port
*
*/
my_bool aurora_parse_url(const char *url, AURORA *aurora)
{
char *p, *c;
unsigned int i;
if (!url || url[0] == 0)
return 1;
bzero(aurora->instance, (AURORA_MAX_INSTANCES + 1) * sizeof(char *));
bzero(&aurora->port, (AURORA_MAX_INSTANCES + 1) * sizeof(int));
if (aurora->url)
free(aurora->url);
aurora->url= strdup(url);
c= aurora->url;
/* get instances */
while((c))
{
if (p= strchr(c, ','))
{
*p= '\0';
p++;
}
if (*c)
{
aurora->instance[aurora->num_instances].host= c;
aurora->num_instances++;
}
c= p;
}
if (!aurora->num_instances)
return 0;
/* check ports */
for (i=0; i < aurora->num_instances && aurora->instance[i].host; i++)
{
aurora->instance[i].type= AURORA_UNKNOWN;
/* We need to be aware of IPv6 addresses: According to RFC3986 sect. 3.2.2
hostnames have to be enclosed in square brackets if a port is given */
if (aurora->instance[i].host[0]== '[' &&
strchr(aurora->instance[i].host, ':') &&
(p= strchr(aurora->instance[i].host,']')))
{
/* ignore first square bracket */
memmove(aurora->instance[i].host,
aurora->instance[i].host+1,
strlen(aurora->instance[i].host) - 1);
p= strchr(aurora->instance[i].host,']');
*p= 0;
p++;
}
else
p= aurora->instance[i].host;
if (p && (p= strchr(p, ':')))
{
*p= '\0';
p++;
aurora->instance[i].port= atoi(p);
}
}
return 0;
}
/* }}} */
/* {{{ int aurora_get_instance_type
*
* RETURNS:
*
* AURORA_PRIMARY
* AURORA_REPLICA
* -1 on error
*/
int aurora_get_instance_type(MYSQL *mysql)
{
int rc;
char *query= "select variable_value from information_schema.global_variables where variable_name='INNODB_READ_ONLY' AND variable_value='OFF'";
if (!mariadb_api->mysql_query(mysql, query))
{
MYSQL_RES *res= mysql_store_result(mysql);
rc= mysql_num_rows(res) ? AURORA_PRIMARY : AURORA_REPLICA;
mysql_free_result(res);
return rc;
}
return -1;
}
/* }}} */
/* {{{ my_bool aurora_get_primary_id
*
* try to find primary instance from slave by retrieving
* primary_id information_schema.replica_host_status information
*
* If the function succeeds, primary_id will be copied into
* aurora->primary_id
*
* Returns:
* 1 on success
* 0 if an error occured or primary_id couldn't be
* found
*/
my_bool aurora_get_primary_id(MYSQL *mysql, AURORA *aurora)
{
my_bool rc= 0;
if (!mariadb_api->mysql_query(mysql, "select server_id from information_schema.replica_host_status "
"where session_id = 'MASTER_SESSION_ID'"))
{
MYSQL_RES *res;
MYSQL_ROW row;
if ((res= mysql_store_result(mysql)))
{
if ((row= mysql_fetch_row(res)))
{
if (row[0])
{
strcpy(aurora->primary_id, row[0]);
rc= 1;
}
}
mysql_free_result(res);
}
}
return rc;
}
/* }}} */
/* {{{ unsigned int aurora_get_valid_instances
*
* returns the number of instances which are
* not blacklisted or don't have a type assigned.
*/
static unsigned int aurora_get_valid_instances(AURORA *aurora, AURORA_INSTANCE **instances)
{
unsigned int i, valid_instances= 0;
memset(instances, 0, sizeof(AURORA_INSTANCE *) * AURORA_MAX_INSTANCES);
for (i=0; i < aurora->num_instances; i++)
{
if (aurora->instance[i].type != AURORA_UNAVAILABLE)
{
if (aurora->instance[i].type == AURORA_PRIMARY && aurora->active[AURORA_PRIMARY])
continue;
instances[valid_instances]= &aurora->instance[i];
valid_instances++;
}
}
return valid_instances;
}
/* }}} */
/* {{{ void aurora_refresh_blacklist() */
void aurora_refresh_blacklist(AURORA *aurora)
{
unsigned int i;
for (i=0; i < aurora->num_instances; i++)
{
if (aurora->instance[i].blacklisted &&
!(AURORA_IS_BLACKLISTED(aurora, i)))
{
aurora->instance[i].blacklisted= 0;
aurora->instance[i].type= AURORA_UNKNOWN;
}
}
}
/* }}} */
/* {{{ MYSQL *aurora_connect_instance() */
MYSQL *aurora_connect_instance(AURORA *aurora, AURORA_INSTANCE *instance, MYSQL *mysql)
{
if (!mysql->methods->db_connect(mysql,
instance->host,
aurora->username,
aurora->password,
aurora->database,
instance->port ? instance->port : aurora->port,
NULL,
aurora->client_flag))
{
/* connection not available */
instance->blacklisted= time(NULL);
instance->type= AURORA_UNAVAILABLE;
return NULL;
}
/* check if we are slave or master */
switch (aurora_get_instance_type(mysql))
{
case AURORA_PRIMARY:
instance->type= AURORA_PRIMARY;
return mysql;
break;
case AURORA_REPLICA:
instance->type= AURORA_REPLICA;
break;
default:
instance->type= AURORA_UNAVAILABLE;
instance->blacklisted= time(NULL);
return NULL;
}
if (!aurora->primary_id[0])
aurora_get_primary_id(mysql, aurora);
return mysql;
}
/* }}} */
/* {{{ void aurora_copy_mysql() */
void aurora_copy_mysql(MYSQL *from, MYSQL *to)
{
/* invalidate statements */
to->methods->invalidate_stmts(to, "aurora connect/reconnect");
from->free_me= to->free_me;
from->reconnect= to->reconnect;
from->net.conn_hdlr= to->net.conn_hdlr;
from->stmts= to->stmts;
to->stmts= NULL;
memset(&to->options, 0, sizeof(to->options));
to->free_me= 0;
to->net.conn_hdlr= 0;
mariadb_api->mysql_close(to);
*to= *from;
to->net.pvio= from->net.pvio;
to->net.pvio->mysql= to;
from->net.pvio= NULL;
}
/* }}} */
/* {{{ my_bool aurora_find_replica() */
my_bool aurora_find_replica(AURORA *aurora)
{
int valid_instances;
my_bool replica_found= 0;
AURORA_INSTANCE *instance[AURORA_MAX_INSTANCES];
MYSQL mysql;
if (aurora->num_instances < 2)
return 0;
mariadb_api->mysql_init(&mysql);
mysql.options= aurora->mysql[AURORA_PRIMARY]->options;
/* don't execute init_command on slave */
mysql.net.conn_hdlr= aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr;
valid_instances= aurora_get_valid_instances(aurora, instance);
while (valid_instances && !replica_found)
{
int random_pick= rand() % valid_instances;
if ((aurora_connect_instance(aurora, instance[random_pick], &mysql)))
{
switch (instance[random_pick]->type) {
case AURORA_REPLICA:
if (!aurora->mysql[AURORA_REPLICA])
{
aurora->mysql[AURORA_REPLICA]= mysql_init(NULL);
}
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_REPLICA]);
aurora->active[AURORA_REPLICA]= 1;
return 1;
break;
case AURORA_PRIMARY:
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
aurora->pvio[AURORA_PRIMARY]= aurora->mysql[AURORA_PRIMARY]->net.pvio;
aurora->active[AURORA_PRIMARY]= 1;
continue;
break;
default:
mysql_close(&mysql);
return 0;
break;
}
}
valid_instances= aurora_get_valid_instances(aurora, instance);
}
return 0;
}
/* }}} */
/* {{{ AURORA_INSTANCE aurora_get_primary_id_instance() */
AURORA_INSTANCE *aurora_get_primary_id_instance(AURORA *aurora)
{
unsigned int i;
if (!aurora->primary_id[0])
return 0;
for (i=0; i < aurora->num_instances; i++)
{
if (!strncmp(aurora->instance[i].host, aurora->primary_id, strlen(aurora->primary_id)))
return &aurora->instance[i];
}
return NULL;
}
/* }}} */
/* {{{ my_bool aurora_find_primary() */
my_bool aurora_find_primary(AURORA *aurora)
{
unsigned int i;
AURORA_INSTANCE *instance= NULL;
MYSQL mysql;
my_bool check_primary= 1;
if (!aurora->num_instances)
return 0;
mariadb_api->mysql_init(&mysql);
mysql.options= aurora->mysql[AURORA_PRIMARY]->options;
mysql.net.conn_hdlr= aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr;
for (i=0; i < aurora->num_instances; i++)
{
if (check_primary && aurora->primary_id[0])
{
if ((instance= aurora_get_primary_id_instance(aurora)) &&
aurora_connect_instance(aurora, instance, &mysql) &&
instance->type == AURORA_PRIMARY)
{
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
aurora->active[AURORA_PRIMARY]= 1;
return 1;
}
/* primary id connect failed, don't try again */
aurora->primary_id[0]= 0;
check_primary= 0;
}
if (aurora->instance[i].type != AURORA_UNAVAILABLE)
{
if (aurora_connect_instance(aurora, &aurora->instance[i], &mysql)
&& aurora->instance[i].type == AURORA_PRIMARY)
{
aurora_copy_mysql(&mysql, aurora->mysql[AURORA_PRIMARY]);
aurora->active[AURORA_PRIMARY]= 1;
return 1;
}
}
}
return 0;
}
/* }}} */
/* {{{ void aurora_close_replica() */
void aurora_close_replica(MYSQL *mysql, AURORA *aurora)
{
if (aurora->mysql[AURORA_REPLICA])
{
aurora->mysql[AURORA_REPLICA]->net.pvio->mysql= aurora->mysql[AURORA_REPLICA];
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
mariadb_api->mysql_close(aurora->mysql[AURORA_REPLICA]);
aurora->pvio[AURORA_REPLICA]= 0;
aurora->mysql[AURORA_REPLICA]= NULL;
}
}
/* }}} */
/* {{{ MYSQL *aurora_connect */
MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
{
AURORA *aurora= NULL;
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
my_bool is_reconnect= 0;
if (!mariadb_api)
mariadb_api= mysql->methods->api;
mariadb_api->mariadb_get_info(mysql, MARIADB_CLIENT_ERRORS, &client_errors);
if ((aurora= (AURORA *)hdlr->data))
{
aurora_refresh_blacklist(aurora);
if (aurora->mysql[aurora->last_instance_type]->net.pvio)
{
SET_CLIENT_ERROR(mysql, CR_ALREADY_CONNECTED, SQLSTATE_UNKNOWN, 0);
return NULL;
}
is_reconnect= 1;
}
else
{
if (!(aurora= (AURORA *)calloc(1, sizeof(AURORA))))
{
mysql->methods->set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return NULL;
}
mysql->net.conn_hdlr->data= (void *)aurora;
aurora->mysql[AURORA_PRIMARY]= mysql;
if (aurora_parse_url(host, aurora))
{
goto error;
}
if (user)
aurora->username= strdup(user);
if (passwd)
aurora->password= strdup(passwd);
if (db)
aurora->database= strdup(db);
aurora->port= port;
aurora->client_flag= client_flag;
aurora->pvio[AURORA_PRIMARY]= aurora->pvio[AURORA_REPLICA]= NULL;
hdlr->data= aurora;
}
/* In case of reconnect, close broken connection first */
if (is_reconnect)
{
DISABLE_AURORA(mysql);
switch (aurora->last_instance_type) {
case AURORA_REPLICA:
aurora_close_replica(mysql, aurora);
aurora->pvio[AURORA_REPLICA]= NULL;
break;
case AURORA_PRIMARY:
/* pvio will be closed in mysql_reconnect() */
aurora->pvio[AURORA_PRIMARY]= NULL;
aurora->primary_id[0]= 0;
break;
}
aurora->active[aurora->last_instance_type]= 0;
}
if (!aurora->active[AURORA_REPLICA])
{
if (aurora_find_replica(aurora))
{
aurora->pvio[AURORA_REPLICA]= aurora->mysql[AURORA_REPLICA]->net.pvio;
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= mysql->net.conn_hdlr;
}
else
aurora->pvio[AURORA_REPLICA]= NULL;
}
if (!aurora->active[AURORA_PRIMARY])
{
if (aurora_find_primary(aurora))
{
aurora->active[AURORA_PRIMARY]= 1;
aurora->pvio[AURORA_PRIMARY]= aurora->mysql[AURORA_PRIMARY]->net.pvio;
}
}
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
ENABLE_AURORA(mysql);
return mysql;
error:
aurora_close_memory(aurora);
return NULL;
}
/* }}} */
/* {{{ my_bool aurora_reconnect */
my_bool aurora_reconnect(MYSQL *mysql)
{
AURORA *aurora;
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
my_bool rc= 1;
aurora= (AURORA *)hdlr->data;
DISABLE_AURORA(mysql);
switch (aurora->last_instance_type)
{
case AURORA_REPLICA:
if (!(rc= mariadb_api->mysql_reconnect(aurora->mysql[aurora->last_instance_type])))
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
break;
case AURORA_PRIMARY:
if (!(rc= mysql_reconnect(aurora->mysql[aurora->last_instance_type])))
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
break;
default:
/* todo: error message */
break;
}
ENABLE_AURORA(mysql);
return rc;
}
/* }}} */
/* {{{ void aurora_close */
void aurora_close(MYSQL *mysql)
{
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
AURORA *aurora= (AURORA *)hdlr->data;
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
/* if the connection is not active yet, just return */
if (!aurora->active[1])
return;
if (aurora->mysql[AURORA_REPLICA])
{
/* we got options from primary, so don't free it twice */
memset(&aurora->mysql[AURORA_REPLICA]->options, 0, sizeof(mysql->options));
/* connection handler wull be freed in mariadb_api->mysql_close() */
aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0;
mysql_close(aurora->mysql[AURORA_REPLICA]);
}
if (aurora->mysql[AURORA_PRIMARY])
{
/* connection handler wull be freed in mysql_close() */
aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr= 0;
aurora->mysql[AURORA_PRIMARY]->net.pvio= aurora->pvio[AURORA_PRIMARY];
mysql_close(aurora->mysql[AURORA_PRIMARY]);
}
/*
if (aurora->mysql[AURORA_PRIMARY])
{
aurora->mysql[AURORA_PRIMARY]->net.pvio= aurora->pvio[AURORA_PRIMARY];
aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr= 0;
mysql_close(aurora->mysql[AURORA_PRIMARY]);
}
*/
/* free masrwe information */
aurora_close_memory(aurora);
}
/* }}} */
/* {{{ my_bool is_replica_command */
my_bool is_replica_command(const char *buffer, size_t buffer_len)
{
const char *buffer_end= buffer + buffer_len;
for (; buffer < buffer_end; ++buffer)
{
char c;
if (isalpha(c=*buffer))
{
if (tolower(c) == 's')
return 1;
return 0;
}
}
return 0;
}
/* }}} */
/* {{{ my_bool is_replica_stmt */
my_bool is_replica_stmt(MYSQL *mysql, const char *buffer)
{
unsigned long stmt_id= uint4korr(buffer);
LIST *stmt_list= mysql->stmts;
for (; stmt_list; stmt_list= stmt_list->next)
{
MYSQL_STMT *stmt= (MYSQL_STMT *)stmt_list->data;
if (stmt->stmt_id == stmt_id)
return 1;
}
return 0;
}
/* }}} */
/* {{{ int aurora_command */
int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
size_t length, my_bool skipp_check, void *opt_arg)
{
AURORA *aurora= (AURORA *)mysql->net.conn_hdlr->data;
/* if we don't have slave or slave became unavailable root traffic to master */
if (!aurora->mysql[AURORA_REPLICA] || !OPT_HAS_EXT_VAL(mysql, read_only))
{
if (command != COM_INIT_DB)
{
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
return 0;
}
}
switch(command) {
case COM_INIT_DB:
/* we need to change default database on primary and replica */
if (aurora->mysql[AURORA_REPLICA] && aurora->last_instance_type != AURORA_REPLICA)
{
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
DISABLE_AURORA(mysql);
mariadb_api->mysql_select_db(aurora->mysql[AURORA_REPLICA], arg);
ENABLE_AURORA(mysql);
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
}
break;
case COM_QUERY:
case COM_STMT_PREPARE:
if (aurora->mysql[AURORA_REPLICA] && aurora->last_instance_type != AURORA_REPLICA)
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
break;
case COM_STMT_EXECUTE:
case COM_STMT_FETCH:
if (aurora->pvio[AURORA_REPLICA]->mysql->stmts && is_replica_stmt(aurora->pvio[AURORA_REPLICA]->mysql, arg))
{
if (aurora->last_instance_type != AURORA_REPLICA)
aurora_switch_connection(mysql, aurora, AURORA_REPLICA);
}
else
{
if (aurora->last_instance_type != AURORA_PRIMARY)
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
}
default:
aurora_switch_connection(mysql, aurora, AURORA_PRIMARY);
break;
}
return 0;
}
/* }}} */
/* {{{ int aurora_set_options() */
int aurora_set_options(MYSQL *mysql, enum mysql_option option, void *arg)
{
switch(option) {
default:
return -1;
}
}
/* }}} */

View File

@@ -42,16 +42,11 @@ int repl_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
size_t length, my_bool skipp_check, void *opt_arg);
int repl_set_options(MYSQL *msql, enum mysql_option option, void *arg);
#ifdef HAVE_REPLICATION_DYNAMIC
#undef my_free
#define my_malloc(a,b) malloc(a)
#define my_free(a) free(a)
#endif
#define MARIADB_MASTER 0
#define MARIADB_SLAVE 1
struct st_mariadb_api *mariadb_api= NULL;
#ifndef HAVE_REPLICATION_DYNAMIC
MARIADB_CONNECTION_PLUGIN connection_replication_plugin =
#else
@@ -70,7 +65,8 @@ MARIADB_CONNECTION_PLUGIN _mysql_client_plugin_declaration_ =
repl_connect,
repl_close,
repl_set_options,
repl_command
repl_command,
NULL
};
typedef struct st_conn_repl {
@@ -81,10 +77,20 @@ typedef struct st_conn_repl {
char *url;
char *host[2];
int port[2];
unsigned int current_type;
} REPL_DATA;
#define SET_SLAVE(mysql, data) mysql->net.pvio= data->pvio[MARIADB_SLAVE]
#define SET_MASTER(mysql, data) mysql->net.pvio= data->pvio[MARIADB_MASTER]
#define SET_SLAVE(mysql, data)\
{\
mysql->net.pvio= data->pvio[MARIADB_SLAVE]; \
data->current_type= MARIADB_SLAVE;\
}
#define SET_MASTER(mysql, data)\
{\
mysql->net.pvio= data->pvio[MARIADB_MASTER];\
data->current_type= MARIADB_MASTER;\
}
/* parse url
@@ -108,10 +114,8 @@ my_bool repl_parse_url(const char *url, REPL_DATA *data)
memset(data->host, 0, 2 * sizeof(char *));
memset(data->port, 0, 2 * sizeof(int));
if (data->url)
my_free(data->url);
data->url= my_strdup(url, MYF(0));
if (!data->url)
data->url= strdup(url);
data->host[MARIADB_MASTER]= p= data->url;
/* get slaves */
@@ -150,10 +154,11 @@ my_bool repl_parse_url(const char *url, REPL_DATA *data)
{
/* We need to be aware of IPv6 addresses: According to RFC3986 sect. 3.2.2
hostnames have to be enclosed in square brackets if a port is given */
if (data->host[i][0]= '[' && strchr(data->host[i], ':') && (p= strchr(data->host[i],']')))
if (data->host[i][0]== '[' && strchr(data->host[i], ':') && (p= strchr(data->host[i],']')))
{
/* ignore first square bracket */
data->host[i]++;
memmove(data->host[i], data->host[i]+1, strlen(data->host[i]) - 1);
p= strchr(data->host[i],']');
*p= 0;
p++;
}
@@ -176,12 +181,21 @@ MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char
REPL_DATA *data= NULL;
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
if (!mariadb_api)
mariadb_api= mysql->methods->api;
if ((data= (REPL_DATA *)hdlr->data))
{
data->pvio[MARIADB_MASTER]->methods->close(data->pvio[MARIADB_MASTER]);
data->pvio[MARIADB_MASTER]= 0;
repl_close(mysql);
}
if (!(data= calloc(1, sizeof(REPL_DATA))))
{
mysql->methods->set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return NULL;
}
memset(data->pvio, 0, 2 * sizeof(MARIADB_PVIO *));
if (repl_parse_url(host, data))
@@ -194,17 +208,18 @@ MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char
data->pvio[MARIADB_MASTER]= mysql->net.pvio;
hdlr->data= data;
SET_MASTER(mysql, data);
/* to allow immediate access without connection delay, we will start
* connecting to slave(s) in background */
/* if slave connection will fail, we will not return error but use master instead */
if (!(data->slave_mysql= mysql_init(NULL)) ||
if (!(data->slave_mysql= mariadb_api->mysql_init(NULL)) ||
!(mysql->methods->db_connect(data->slave_mysql, data->host[MARIADB_SLAVE], user, passwd, db,
data->port[MARIADB_SLAVE] ? data->port[MARIADB_SLAVE] : port, unix_socket, clientflag)))
{
if (data->slave_mysql)
mysql_close(data->slave_mysql);
mariadb_api->mysql_close(data->slave_mysql);
data->pvio[MARIADB_SLAVE]= NULL;
}
else
@@ -217,8 +232,8 @@ error:
if (data)
{
if (data->url)
my_free(data->url);
my_free(data);
free(data->url);
free(data);
}
return NULL;
}
@@ -236,16 +251,15 @@ void repl_close(MYSQL *mysql)
{
/* restore mysql */
data->pvio[MARIADB_SLAVE]->mysql= data->slave_mysql;
mysql_close(data->slave_mysql);
mariadb_api->mysql_close(data->slave_mysql);
data->pvio[MARIADB_SLAVE]= NULL;
data->slave_mysql= NULL;
}
/* free masrwe information and close connection */
my_free(data->url);
my_free(data);
free(data->url);
free(data);
mysql->net.conn_hdlr->data= NULL;
mysql_close(mysql);
}
static my_bool is_slave_command(const char *buffer, size_t buffer_len)
@@ -295,20 +309,20 @@ int repl_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
case COM_QUERY:
case COM_STMT_PREPARE:
if (is_slave_command(arg, length))
SET_SLAVE(mysql, data);
SET_SLAVE(mysql, data)
else
SET_MASTER(mysql,data);
SET_MASTER(mysql,data)
break;
case COM_STMT_EXECUTE:
case COM_STMT_FETCH:
if (data->pvio[MARIADB_SLAVE]->mysql->stmts && is_slave_stmt(data->pvio[MARIADB_SLAVE]->mysql, arg))
SET_SLAVE(mysql, data);
SET_SLAVE(mysql, data)
else
SET_MASTER(mysql,data);
SET_MASTER(mysql,data)
break;
default:
SET_MASTER(mysql,data);
SET_MASTER(mysql,data)
break;
}
return 0;

View File

@@ -34,7 +34,9 @@
my_bool pvio_npipe_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout);
int pvio_npipe_get_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type);
size_t pvio_npipe_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
size_t pvio_npipe_async_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
size_t pvio_npipe_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
size_t pvio_npipe_async_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int pvio_npipe_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout);
my_bool pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
@@ -118,10 +120,10 @@ size_t pvio_npipe_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
goto end;
}
if (GetLastError() == ERROR_IO_PENDING)
r= pvio_npipe_wait_io_or_timeout(pvio, 1, 0);
if (!r)
r= cpipe->rw_size;
{
if (!pvio_npipe_wait_io_or_timeout(pvio, 1, 0))
r= cpipe->rw_size;
}
end:
return r;
}
@@ -143,10 +145,10 @@ size_t pvio_npipe_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
goto end;
}
if (GetLastError() == ERROR_IO_PENDING)
r= pvio_npipe_wait_io_or_timeout(pvio, 1, 0);
if (!r)
r= cpipe->rw_size;
{
if (!pvio_npipe_wait_io_or_timeout(pvio, 1, 0))
r= cpipe->rw_size;
}
end:
return r;
}
@@ -216,7 +218,7 @@ my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
if (!pvio || !cinfo)
return 1;
if (!(cpipe= (struct st_pvio_npipe *)LocalAlloc(sizeof(struct st_pvio_npipe), 0)))
if (!(cpipe= (struct st_pvio_npipe *)LocalAlloc(LMEM_ZEROINIT, sizeof(struct st_pvio_npipe))))
{
PVIO_SET_ERROR(cinfo->mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0, "");
return 1;
@@ -249,7 +251,7 @@ my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
0, /* no sharing */
NULL, /* default security attributes */
OPEN_EXISTING,
0, /* default attributes */
FILE_FLAG_OVERLAPPED,
NULL)) != INVALID_HANDLE_VALUE)
break;

View File

@@ -948,7 +948,7 @@ my_bool pvio_socket_is_alive(MARIADB_PVIO *pvio)
my_bool pvio_socket_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
{
struct st_pvio_socket *csock= NULL;
char tmp_buf[1024];
char tmp_buf;
ssize_t len;
my_bool mode;

View File

@@ -21,7 +21,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/unittest/mytap)
ADD_DEFINITIONS(-DLIBMARIADB)
SET(API_TESTS "features-10_2" "async" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs"
SET(API_TESTS "t_aurora" "async" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs"
"sp" "result" "connection" "misc" "ps_new" "sqlite3" "thread" "dyncol")
# Get finger print from server certificate
@@ -31,18 +31,15 @@ IF(WITH_SSL)
IF(EXISTS "${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs/server-cert.pem")
MESSAGE(STATUS "certificates already exist")
ELSE()
MESSAGE(STATUS "cerating certificates")
EXECUTE_PROCESS(COMMAND openssl req -x509 -newkey rsa:1024 -keyout server-key-enc.pem -out server-cert.pem -subj "/DC=com/DC=example/CN=server" -passout pass:qwerty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs)
EXECUTE_PROCESS(COMMAND openssl rsa -in server-key-enc.pem -out server-key.pem -passin pass:qwerty -passout pass:
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs)
EXECUTE_PROCESS(COMMAND openssl req -x509 -newkey rsa:1024 -keyout client-key-enc.pem -out client-cert.pem -subj "/DC=com/DC=example/CN=client" -passout pass:qwerty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs)
EXECUTE_PROCESS(COMMAND openssl rsa -in client-key-enc.pem -out client-key.pem -passin pass:qwerty -passout pass:
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs)
FILE(READ ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs/server-cert.pem F1)
FILE(READ ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs/client-cert.pem F2)
FILE(WRITE ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs/ca-cert.pem ${F1} ${F2})
MESSAGE(STATUS "creating certificates")
IF(WIN32)
EXECUTE_PROCESS(COMMAND create_certs.bat
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs
OUTPUT_FILE x.1 ERROR_FILE x.2)
ELSE()
EXECUTE_PROCESS(COMMAND ./create_certs.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs)
ENDIF()
ENDIF()
EXECUTE_PROCESS(COMMAND openssl x509 -in server-cert.pem -sha1 -fingerprint -noout
@@ -60,8 +57,8 @@ IF(WITH_SSL)
ENDIF()
FOREACH(API_TEST ${API_TESTS})
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c)
TARGET_LINK_LIBRARIES(${API_TEST} mytap mariadbclient )
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c ${CMAKE_SOURCE_DIR}/libmariadb/getopt.c)
TARGET_LINK_LIBRARIES(${API_TEST} mytap libmariadb)
ADD_TEST(${API_TEST} ${EXECUTABLE_OUTPUT_PATH}/${API_TEST})
SET_TESTS_PROPERTIES(${API_TEST} PROPERTIES TIMEOUT 120)
ENDFOREACH(API_TEST)

View File

@@ -30,6 +30,20 @@
#define SL(s) (s), sizeof(s)
my_bool skip_async= 0;
static int test_async(MYSQL *mysql)
{
int type;
mariadb_get_info(mysql, MARIADB_CONNECTION_PVIO_TYPE, &type);
if (type > MARIADB_CONNECTION_TCP)
{
skip_async= 1;
diag("Asnyc IO not supported");
}
return OK;
}
static int
wait_for_mysql(MYSQL *mysql, int status)
{
@@ -126,6 +140,9 @@ static int async1(MYSQL *my)
uint default_timeout;
int i;
if (skip_async)
return SKIP;
for (i=0; i < 100; i++)
{
@@ -196,7 +213,12 @@ static int test_conc131(MYSQL *my)
{
int rc;
/* this test needs to run under valgrind */
MYSQL *mysql=mysql_init(NULL);
MYSQL *mysql;
if (skip_async)
return SKIP;
mysql= mysql_init(NULL);
rc= mysql_options(mysql, MYSQL_OPT_NONBLOCK, 0);
check_mysql_rc(rc, mysql);
mysql_close(mysql);
@@ -205,13 +227,19 @@ static int test_conc131(MYSQL *my)
static int test_conc129(MYSQL *my)
{
MYSQL *mysql= mysql_init(NULL);
MYSQL *mysql;
if (skip_async)
return SKIP;
mysql= mysql_init(NULL);
FAIL_IF(mysql_close_start(mysql), "No error expected");
return OK;
}
struct my_tests_st my_tests[] = {
{"test_async", test_async, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"async1", async1, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc131", test_conc131, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_conc129", test_conc129, TEST_CONNECTION_NONE, 0, NULL, NULL},

View File

@@ -55,13 +55,17 @@ static int test_conc75(MYSQL *my)
{
ulong thread_id= mysql_thread_id(mysql);
/* force reconnect */
mysql->reconnect= 1;
diag("killing connection");
mysql_kill(my, thread_id);
sleep(1);
sleep(2);
mysql_ping(mysql);
rc= mysql_query(mysql, "load data local infile './nonexistingfile.csv' into table a (`a`)");
FAIL_IF(!test(mysql->options.client_flag | CLIENT_LOCAL_FILES), "client_flags not correct");
diag("thread1: %d %d", thread_id, mysql_thread_id(mysql));
FAIL_IF(thread_id == mysql_thread_id(mysql), "new thread id expected");
diag("cs: %s", mysql->charset->csname);
FAIL_IF(strcmp(mysql->charset->csname, "utf8"), "wrong character set");
//diag("cs: %s", mysql->charset->csname);
//FAIL_IF(strcmp(mysql->charset->csname, "utf8"), "wrong character set");
}
mysql_close(mysql);
return OK;
@@ -76,7 +80,12 @@ static int test_conc74(MYSQL *my)
mysql= mysql_init(NULL);
mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS);
if (!mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS))
{
diag("Error: %s", mysql_error(mysql));
mysql_close(mysql);
return FAIL;
}
rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
check_mysql_rc(rc, mysql);
@@ -128,7 +137,11 @@ static int test_conc70(MYSQL *my)
int rc;
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL *mysql= mysql_init(NULL);
MYSQL *mysql;
SKIP_CONNECTION_HANDLER;
mysql= mysql_init(NULL);
rc= mysql_query(my, "SET @a:=@@max_allowed_packet");
check_mysql_rc(rc, my);
@@ -148,6 +161,14 @@ static int test_conc70(MYSQL *my)
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (REPEAT('A', 1024 * 1024 * 20))");
check_mysql_rc(rc, mysql);
if (mysql_warning_count(mysql))
{
diag("server doesn't accept package size");
return SKIP;
}
sleep(20);
rc= mysql_query(mysql, "SELECT a FROM t1");
check_mysql_rc(rc, mysql);
@@ -175,7 +196,11 @@ static int test_conc68(MYSQL *my)
int rc;
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL *mysql= mysql_init(NULL);
MYSQL *mysql;
SKIP_CONNECTION_HANDLER;
mysql= mysql_init(NULL);
rc= mysql_query(my, "SET @a:=@@max_allowed_packet");
check_mysql_rc(rc, my);
@@ -193,6 +218,11 @@ static int test_conc68(MYSQL *my)
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (REPEAT('A', 1024 * 1024 * 20))");
check_mysql_rc(rc, mysql);
if (mysql_warning_count(mysql))
{
diag("server doesn't accept package size");
return SKIP;
}
rc= mysql_query(mysql, "SELECT a FROM t1");
check_mysql_rc(rc, mysql);
@@ -427,7 +457,7 @@ static int test_mysql_insert_id(MYSQL *mysql)
FAIL_UNLESS(res == 400, "");
/* table with auto_increment column */
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255)) engine=MyISAM");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "insert into t2 values (1,'a')");
check_mysql_rc(rc, mysql);
@@ -504,12 +534,13 @@ static int test_mysql_insert_id(MYSQL *mysql)
according to the manual, this might be 20 or 300, but it looks like
auto_increment column takes priority over last_insert_id().
*/
diag("res: %d", res);
FAIL_UNLESS(res == 20, "");
/* If first autogenerated number fails and 2nd works: */
rc= mysql_query(mysql, "drop table t2");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
"auto_increment, f2 varchar(255), unique (f2))");
"auto_increment, f2 varchar(255), unique (f2)) engine=MyISAM");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "insert into t2 values (null,'e')");
res= mysql_insert_id(mysql);
@@ -618,12 +649,9 @@ static int bug_conc1(MYSQL *mysql)
{
mysql_real_connect(mysql, hostname, username, password, schema,
port, socketname, 0);
diag("errno: %d", mysql_errno(mysql));
FAIL_IF(mysql_errno(mysql) != CR_ALREADY_CONNECTED,
"Expected errno=CR_ALREADY_CONNECTED");
FAIL_IF(strcmp(mysql_error(mysql), ER(CR_ALREADY_CONNECTED)) != 0,
"Wrong error message");
FAIL_IF(strcmp(ER(CR_ALREADY_CONNECTED), "Can't connect twice. Already connected") != 0,
"wrong error message");
return OK;
}
@@ -668,11 +696,14 @@ static int test_reconnect_maxpackage(MYSQL *my)
{
int rc;
ulong max_packet= 0;
MYSQL *mysql= mysql_init(NULL);
MYSQL *mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char *query;
SKIP_CONNECTION_HANDLER;
mysql= mysql_init(NULL);
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
port, socketname,
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
@@ -770,6 +801,8 @@ int main(int argc, char **argv)
get_envvars();
diag("user: %s", username);
run_tests(my_tests);
return(exit_status());

View File

@@ -1,15 +0,0 @@
openssl req -x509 -newkey rsa:1024 \
-keyout server-key-enc.pem -out server-cert.pem \
-subj '/DC=com/DC=example/CN=server' -passout pass:qwerty
openssl rsa -in server-key-enc.pem -out server-key.pem \
-passin pass:qwerty -passout pass:
openssl req -x509 -newkey rsa:1024 \
-keyout client-key-enc.pem -out client-cert.pem \
-subj '/DC=com/DC=example/CN=client' -passout pass:qwerty
openssl rsa -in client-key-enc.pem -out client-key.pem \
-passin pass:qwerty -passout pass:
cat server-cert.pem client-cert.pem > ca-cert.pem

View File

@@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAL4tmDe5DR0sMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzEwMjAyMDI4WhcNMTYwMzA5MjAyMDI4WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApV9UfWmeXYdexOEn+adOm6FdJUhKMrjTiycwETmDXRVpY4wl+LNGsANp
ohSRovDjFiFO+Ti0bUhpf552oE23wYw+P6f0UY0KkV/PgSght1Ezfffe0BaEjI0X
tA5zdNmxzL3OUWJVcg+I4UE3rbYFHUgymu72P0IRXjmJv1tToNxUxbTBLxU/KAlq
Uy49upB3q3/IPOdP9UzAZDHnRv1gjwUzNgumfcc5d5lSsGpwLDYCQs4I539fCkBD
MfU2BN/qpmPhb/nm5ZUdFUFYGN+XxVPVpJLmeWVRwMSQR2LN5CkqnK9e2Q/QaJ53
G3AAng+fpfEGPpjQdFWuhFjQozOD0wIDAQABo1AwTjAdBgNVHQ4EFgQUyg6WfzL2
JhhjKm1Ex28s4Y3vNGQwHwYDVR0jBBgwFoAUyg6WfzL2JhhjKm1Ex28s4Y3vNGQw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAIrj/bHiRf8UJIfv8hyZ1
dXEqvqjxUMXtJ/QhhCQs42p9pHv+mPTkeXh0K18Oj6k/Vp4J1/0mp/kqiQUHt9yO
/3pJPc+JordTjlVLgb95cfBIs4yiPT9biGaA7j0Dh9EcDBOCT4v56Z9BLqGMfBUK
YeZ7ZecWmZCZOYk/X+CPB30GxLy5Wm9D50qEUXXBPZ9Bie6FYaQYOFlQlqxYuLX0
NVqLDvX6zz6FMsgqoyDJ1BMuMsjPDUUUrwGY+R3YqiqkPRbDkr8zvzpqiYvjTZi0
LTJO7GRfwzfhkeEPL/hl/TYdB1GZHixMrAKx1HGKHAa0sgWTWxQGYhfclH8DI7AR
Tw==
-----END CERTIFICATE-----

View File

@@ -679,7 +679,7 @@ static int test_utf16_utf32_noboms(MYSQL *mysql)
for (i= 0; i < sizeof(csname)/sizeof(char*); ++i)
{
csinfo[i]= mysql_find_charset_name(csname[i]);
csinfo[i]= mariadb_get_charset_by_name(csname[i]);
if (csinfo[i] == NULL)
{

View File

@@ -32,6 +32,7 @@ static int test_conc66(MYSQL *my)
MYSQL *mysql= mysql_init(NULL);
int rc;
FILE *fp;
char query[1024];
if (!(fp= fopen("./my.cnf", "w")))
return FAIL;
@@ -47,7 +48,8 @@ static int test_conc66(MYSQL *my)
rc= mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, "./my.cnf");
check_mysql_rc(rc, mysql);
rc= mysql_query(my, "GRANT ALL ON test.* TO 'conc66'@'localhost' IDENTIFIED BY 'test\";#test'");
sprintf(query, "GRANT ALL ON %s.* TO 'conc66'@'%s' IDENTIFIED BY 'test\";#test'", schema, hostname);
rc= mysql_query(my, query);
check_mysql_rc(rc, my);
rc= mysql_query(my, "FLUSH PRIVILEGES");
check_mysql_rc(rc, my);
@@ -57,7 +59,8 @@ static int test_conc66(MYSQL *my)
diag("Error: %s", mysql_error(mysql));
return FAIL;
}
rc= mysql_query(my, "DROP USER conc66@localhost");
sprintf(query, "DROP user conc66@%s", hostname);
rc= mysql_query(my, query);
check_mysql_rc(rc, my);
mysql_close(mysql);
@@ -561,6 +564,8 @@ static int test_reconnect(MYSQL *mysql)
mysql_kill(mysql, mysql_thread_id(mysql1));
sleep(4);
mysql_ping(mysql1);
rc= mysql_query(mysql1, "SELECT 1 FROM DUAL LIMIT 0");
check_mysql_rc(rc, mysql1);
diag("Thread_id after kill: %lu", mysql_thread_id(mysql1));
@@ -649,6 +654,8 @@ static int test_conc118(MYSQL *mysql)
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(2);
mysql_ping(mysql);
rc= mysql_query(mysql, "SET @a:=1");
check_mysql_rc(rc, mysql);
@@ -657,12 +664,7 @@ static int test_conc118(MYSQL *mysql)
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(2);
mysql->host= "foo";
rc= mysql_query(mysql, "SET @a:=1");
FAIL_IF(!rc, "error expected");
mysql->host= hostname;
mysql_ping(mysql);
rc= mysql_query(mysql, "SET @a:=1");
check_mysql_rc(rc, mysql);
@@ -740,7 +742,92 @@ static int test_bind_address(MYSQL *my)
return OK;
}
static int test_get_options(MYSQL *my)
{
MYSQL *mysql= mysql_init(NULL);
int options_int[]= {MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_RECONNECT, MYSQL_OPT_PROTOCOL, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, 0};
my_bool options_bool[]= {MYSQL_OPT_COMPRESS, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_SECURE_AUTH,
#ifdef _WIN32
MYSQL_OPT_NAMED_PIPE,
#endif
0};
int options_char[]= {MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_SET_CHARSET_NAME,
MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CAPATH,
MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_BIND, MARIADB_OPT_SSL_FP, MARIADB_OPT_SSL_FP_LIST,
MARIADB_OPT_SSL_PASSWORD, 0};
char *init_command[3]= {"SET @a:=1", "SET @b:=2", "SET @c:=3"};
int elements= 0;
char **command;
int intval[2]= {1, 0};
my_bool boolval[2]= {1, 0};
char *char1= "test", *char2;
int i;
MYSQL *userdata;
char *attr_key[] = {"foo1", "foo2", "foo3"};
char *attr_val[] = {"bar1", "bar2", "bar3"};
char **key, **val;
for (i=0; options_int[i]; i++)
{
mysql_options(mysql, options_int[i], &intval[0]);
intval[1]= 0;
mysql_get_optionv(mysql, options_int[i], &intval[1]);
FAIL_IF(intval[0] != intval[1], "mysql_get_optionv (int) failed");
}
for (i=0; options_bool[i]; i++)
{
mysql_options(mysql, options_bool[i], &boolval[0]);
intval[1]= 0;
mysql_get_optionv(mysql, options_bool[i], &boolval[1]);
FAIL_IF(boolval[0] != boolval[1], "mysql_get_optionv (my_bool) failed");
}
for (i=0; options_char[i]; i++)
{
mysql_options(mysql, options_char[i], char1);
char2= NULL;
mysql_get_optionv(mysql, options_char[i], (void *)&char2);
FAIL_IF(strcmp(char1, char2), "mysql_get_optionv (char) failed");
}
for (i=0; i < 3; i++)
mysql_options(mysql, MYSQL_INIT_COMMAND, init_command[i]);
mysql_get_optionv(mysql, MYSQL_INIT_COMMAND, &command, &elements);
FAIL_IF(elements != 3, "expected 3 elements");
for (i=0; i < 3; i++)
FAIL_IF(strcmp(init_command[i], command[i]), "wrong init command");
for (i=0; i < 3; i++)
mysql_optionsv(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, attr_key[i], attr_val[i]);
mysql_get_optionv(mysql, MYSQL_OPT_CONNECT_ATTRS, NULL, NULL, &elements);
FAIL_IF(elements != 3, "expected 3 connection attributes");
key= (char **)malloc(sizeof(char *) * elements);
val= (char **)malloc(sizeof(char *) * elements);
mysql_get_optionv(mysql, MYSQL_OPT_CONNECT_ATTRS, &key, &val, &elements);
for (i=0; i < elements; i++)
{
diag("%s => %s", key[i], val[i]);
}
free(key);
free(val);
mysql_optionsv(mysql, MARIADB_OPT_USERDATA, "my_app", (void *)mysql);
mysql_get_optionv(mysql, MARIADB_OPT_USERDATA, "my_app", &userdata);
FAIL_IF(mysql != userdata, "wrong userdata");
mysql_close(mysql);
return OK;
}
struct my_tests_st my_tests[] = {
{"test_get_options", test_get_options, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_wrong_bind_address", test_wrong_bind_address, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_bind_address", test_bind_address, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc118", test_conc118, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},

View File

@@ -59,12 +59,12 @@ MYSQL_STMT *open_cursor(MYSQL *mysql, const char *query)
fetch buffers.
*/
int stmt_fetch_init(MYSQL *mysql, Stmt_fetch *fetch, unsigned stmt_no_arg,
int stmt_fetch_init(MYSQL *mysql, Stmt_fetch *fetch, unsigned int stmt_no_arg,
const char *query_arg)
{
unsigned long type= CURSOR_TYPE_READ_ONLY;
int rc;
unsigned i;
unsigned int i;
MYSQL_RES *metadata;
/* Save query and statement number for error messages */
@@ -180,7 +180,7 @@ int fetch_n(MYSQL *mysql, const char **query_list, unsigned query_count,
for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
{
if (stmt_fetch_init(mysql, fetch, fetch - fetch_array,
if (stmt_fetch_init(mysql, fetch, (unsigned int)(fetch - fetch_array),
query_list[fetch - fetch_array]))
return FAIL;
}
@@ -322,7 +322,7 @@ static int test_bug21206(MYSQL *mysql)
for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
{
if ((retcode= stmt_fetch_init(mysql, fetch, fetch - fetch_array, query)))
if ((retcode= stmt_fetch_init(mysql, fetch, (unsigned int)(fetch - fetch_array), query)))
break;
}

View File

@@ -89,7 +89,7 @@ static int test_logs(MYSQL *mysql)
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
my_bind[1].buffer= (void *)&data;
my_bind[1].buffer_length= 255;
my_bind[1].length= &length;
my_bind[1].length= (unsigned long *)&length;
id= 9876;
strcpy((char *)data, "MySQL - Open Source Database");

View File

@@ -266,7 +266,7 @@ static int test_frm_bug(MYSQL *mysql)
sprintf(test_frm, "%s/%s/test_frm_bug.frm", data_dir, schema);
if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
if (!(test_file= fopen(test_frm, "rw")))
{
mysql_stmt_close(stmt);
diag("Can't write to file %s -> SKIP", test_frm);
@@ -294,7 +294,7 @@ static int test_frm_bug(MYSQL *mysql)
mysql_free_result(result);
mysql_stmt_close(stmt);
my_fclose(test_file, MYF(0));
fclose(test_file);
mysql_query(mysql, "drop table if exists test_frm_bug");
return OK;
}
@@ -1021,11 +1021,74 @@ static int test_remote2(MYSQL *my)
}
#endif
static int test_get_info(MYSQL *mysql)
{
size_t sval;
unsigned int ival;
char *cval;
int rc;
MY_CHARSET_INFO cs;
CHARSET_INFO *ci;
char **errors;
rc= mariadb_get_infov(mysql, MARIADB_MAX_ALLOWED_PACKET, &sval);
FAIL_IF(rc, "mysql_get_info failed");
diag("max_allowed_packet: %d", sval);
rc= mariadb_get_infov(mysql, MARIADB_NET_BUFFER_LENGTH, &sval);
FAIL_IF(rc, "mysql_get_info failed");
diag("net_buffer_length: %d", sval);
rc= mariadb_get_infov(mysql, MARIADB_CLIENT_VERSION_ID, &sval);
FAIL_IF(rc, "mysql_get_info failed");
diag("client_version_id: %d", sval);
rc= mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_VERSION_ID, &sval);
FAIL_IF(rc, "mysql_get_info failed");
diag("server_version_id: %d", sval);
rc= mariadb_get_infov(mysql, MARIADB_CHARSET_INFO, &cs);
FAIL_IF(rc, "mysql_get_info failed");
diag("charset name: %s", cs.csname);
rc= mariadb_get_infov(mysql, MARIADB_CONNECTION_PVIO_TYPE, &ival);
FAIL_IF(rc, "mysql_get_info failed");
diag("connection type: %d", ival);
rc= mariadb_get_infov(mysql, MARIADB_CONNECTION_PROTOCOL_VERSION_ID, &ival);
FAIL_IF(rc, "mysql_get_info failed");
diag("protocol_version: %d", ival);
rc= mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_TYPE, &cval);
FAIL_IF(rc, "mysql_get_info failed");
diag("server_type: %s", cval);
rc= mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_VERSION, &cval);
FAIL_IF(rc, "mysql_get_info failed");
diag("server_version: %s", cval);
rc= mariadb_get_infov(mysql, MARIADB_CLIENT_VERSION, &cval);
FAIL_IF(rc, "mysql_get_info failed");
diag("client_version: %s", cval);
rc= mariadb_get_infov(mysql, MARIADB_CHARSET_NAME, &ci, "utf8");
FAIL_IF(rc, "mysql_get_info failed");
diag("charset_name: %s", ci->csname);
diag("charset_nr: %d", ci->nr);
rc= mariadb_get_infov(mysql, MARIADB_CHARSET_ID, &ci, 63);
FAIL_IF(rc, "mysql_get_info failed");
diag("charset_name: %s", ci->csname);
rc= mariadb_get_infov(mysql, MARIADB_CLIENT_ERRORS, &errors);
FAIL_IF(rc, "mysql_get_info failed");
diag("error[0]: %s", errors[0]);
rc= mysql_query(mysql, "DROP TABLE IF exists t1");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1),(2)");
check_mysql_rc(rc, mysql);
rc= mariadb_get_infov(mysql, MARIADB_CONNECTION_INFO, &cval);
FAIL_IF(rc, "mysql_get_info failed");
diag("mariadb_info: %s", cval);
return OK;
}
struct my_tests_st my_tests[] = {
#ifdef HAVE_REMOTEIO
{"test_remote1", test_remote1, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_remote2", test_remote2, TEST_CONNECTION_NEW, 0, NULL, NULL},
#endif
{"test_get_info", test_get_info, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc117", test_conc117, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc_114", test_conc_114, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_connect_attrs", test_connect_attrs, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},

View File

@@ -82,6 +82,13 @@ if (!(expr))\
return FAIL;\
}
#define SKIP_CONNECTION_HANDLER \
if (hostname && strstr(hostname, "://"))\
{\
diag("Test skipped (connection handler)");\
return SKIP;\
}
/* connection options */
#define TEST_CONNECTION_DEFAULT 1 /* default connection */
#define TEST_CONNECTION_NONE 2 /* tests creates own connection */
@@ -104,7 +111,7 @@ struct my_tests_st
char *skipmsg;
};
static char *schema = "test_c";
static char *schema = 0;
static char *hostname = 0;
static char *password = 0;
static unsigned int port = 0;
@@ -368,18 +375,19 @@ int check_variable(MYSQL *mysql, char *variable, char *value)
MYSQL *test_connect(struct my_tests_st *test) {
MYSQL *mysql;
char query[255];
int i= 1;
int i= 0;
int timeout= 10;
int truncation_report= 1;
if (!(mysql = mysql_init(NULL))) {
diag("%s", "mysql_init failed - exiting");
return(NULL);
}
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, &i);
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&i);
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, &truncation_report);
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
/* option handling */
if (test && test->options) {
int i=0;
while (test->options[i].option)
{
@@ -403,6 +411,8 @@ MYSQL *test_connect(struct my_tests_st *test) {
/* change database or create if it doesn't exist */
if (mysql_select_db(mysql, schema)) {
diag("Error number: %d", mysql_errno(mysql));
if(mysql_errno(mysql) == 1049) {
sprintf(query, "CREATE DATABASE %s", schema);
if (mysql_query(mysql, query)) {
@@ -425,11 +435,6 @@ static int reset_connection(MYSQL *mysql) {
rc= mysql_change_user(mysql, username, password, schema);
check_mysql_rc(rc, mysql);
if (mysql_get_server_version(mysql) < 50400)
rc= mysql_query(mysql, "SET table_type='MyISAM'");
else
rc= mysql_query(mysql, "SET storage_engine='MyISAM'");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "SET sql_mode=''");
check_mysql_rc(rc, mysql);
@@ -452,6 +457,8 @@ void get_envvars() {
password= envvar;
if (!schema && (envvar= getenv("MYSQL_TEST_DB")))
schema= envvar;
if (!schema)
schema= "testc";
if (!port && (envvar= getenv("MYSQL_TEST_PORT")))
port= atoi(envvar);
if (!socketname && (envvar= getenv("MYSQL_TEST_SOCKET")))
@@ -470,7 +477,8 @@ void run_tests(struct my_tests_st *test) {
if ((mysql_default= test_connect(NULL)))
{
diag("Testing against MySQL Server %s", mysql_get_server_info(mysql_default));
diag("Host %s", mysql_get_host_info(mysql_default));
diag("Host: %s", mysql_get_host_info(mysql_default));
diag("Client library: %s", mysql_get_client_info());
}
else
{

View File

@@ -64,7 +64,10 @@ static int test_conc83(MYSQL *my)
/* 1. Status is inited, so prepare should work */
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(2);
sleep(5);
rc= mysql_ping(mysql);
check_mysql_rc(rc, mysql);
rc= mysql_stmt_prepare(stmt, query, strlen(query));
check_stmt_rc(rc, stmt);
@@ -1383,7 +1386,7 @@ static int test_long_data_str1(MYSQL *mysql)
my_bind[0].buffer= data; /* string data */
my_bind[0].buffer_length= sizeof(data);
my_bind[0].length= &length1;
my_bind[0].length= (unsigned long *)&length1;
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
length1= 0;
@@ -1482,7 +1485,7 @@ static int test_long_data_str1(MYSQL *mysql)
my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
my_bind[0].buffer_length= 16;
my_bind[0].length= &blob_length;
my_bind[0].length= (unsigned long *)&blob_length;
my_bind[0].error= &my_bind[0].error_value;
rc= mysql_stmt_bind_result(stmt, my_bind);
data[16]= 0;
@@ -1498,7 +1501,7 @@ static int test_long_data_str1(MYSQL *mysql)
my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
my_bind[1].buffer_length= sizeof(data);
my_bind[1].length= &blob_length;
my_bind[1].length= (unsigned long *)&blob_length;
memset(data, '\0', sizeof(data));
mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
FAIL_UNLESS(strlen(data) == max_blob_length, "strlen(data) != max_blob_length");

View File

@@ -528,9 +528,8 @@ static int test_bug12744(MYSQL *mysql)
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, "1");
check_mysql_rc(rc, mysql);
rc= mysql_kill(mysql, mysql_thread_id(mysql));
check_mysql_rc(rc, mysql);
sleep(2);
sleep(4);
rc= mysql_ping(mysql);
check_mysql_rc(rc, mysql);
@@ -644,7 +643,7 @@ static int test_bug1500(MYSQL *mysql)
data= "Grave";
my_bind[0].buffer_type= MYSQL_TYPE_STRING;
my_bind[0].buffer= (void *) data;
my_bind[0].buffer_length= strlen(data);
my_bind[0].buffer_length= (unsigned long)strlen(data);
rc= mysql_stmt_bind_param(stmt, my_bind);
check_stmt_rc(rc, stmt);
@@ -2652,7 +2651,7 @@ static int test_bug5194(MYSQL *mysql)
for (i= 1; i < COLUMN_COUNT; ++i)
strcat(param_str, "?, ");
strcat(param_str, "?)");
param_str_length= strlen(param_str);
param_str_length= (int)strlen(param_str);
/* setup bind array */
memset(my_bind, '\0', MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
@@ -3230,7 +3229,7 @@ static int test_mem_overun(MYSQL *mysql)
sprintf(field, "c%d int, ", i);
strcat(buffer, field);
}
length= strlen(buffer);
length= (int)strlen(buffer);
buffer[length-2]= ')';
buffer[--length]= '\0';
@@ -3242,7 +3241,7 @@ static int test_mem_overun(MYSQL *mysql)
{
strcat(buffer, "1, ");
}
length= strlen(buffer);
length= (int)strlen(buffer);
buffer[length-2]= ')';
buffer[--length]= '\0';

View File

@@ -51,12 +51,20 @@ static int check_cipher(MYSQL *mysql)
char *cipher= (char *)mysql_get_ssl_cipher(mysql);
if (!cipher)
return 1;
diag("cipher: %s", cipher);
#ifdef HAVE_GNUTLS
return strcmp(cipher, "AES-128-GCM");
#endif
#ifdef HAVE_OPENSSL
return strcmp(cipher, "DHE-RSA-AES256-SHA");
{
return strcmp(cipher, "AES-128-GCM");
}
#elif HAVE_OPENSSL
if (!strcmp(cipher, "DHE-RSA-AES256-SHA") ||
!strcmp(cipher, "DHE-RSA-AES256-GCM-SHA384"))
return 0;
#elif HAVE_SCHANNEL
return strcmp(cipher, "CALG_AES_256");
#endif
return 1;
}
static int create_ssl_user(const char *ssluser, my_bool is_X509)
@@ -105,6 +113,14 @@ static int test_ssl(MYSQL *mysql)
}
mysql_free_result(res);
#ifdef HAVE_GNUTLS
diag("SSL library: GNUTLS");
#elif HAVE_OPENSSL
diag("SSL library: OPENSSL");
#elif HAVE_SCHANNEL
diag("SSL library: SCHANNEL");
#endif
sslhost[0]= 0;
if (!skip_ssl)
@@ -127,6 +143,9 @@ static int test_ssl(MYSQL *mysql)
static int test_ssl_cipher(MYSQL *unused)
{
MYSQL *my;
MYSQL_RES *res;
MYSQL_ROW row;
int rc;
if (check_skip_ssl())
return SKIP;
@@ -139,6 +158,14 @@ static int test_ssl_cipher(MYSQL *unused)
FAIL_IF(!mysql_real_connect(my, hostname, ssluser, sslpw, schema,
port, socketname, 0), mysql_error(my));
rc= mysql_query(my, "SHOW session status like 'Ssl_version'");
check_mysql_rc(rc, my);
res= mysql_store_result(my);
row= mysql_fetch_row(res);
diag("%s: %s", row[0], row[1]);
diag("cipher: %s", mysql_get_ssl_cipher(my));
mysql_free_result(res);
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
mysql_close(my);
return OK;
@@ -268,6 +295,7 @@ DWORD WINAPI ssl_thread(void *dummy)
mysql_close(mysql);
mysql_thread_end();
pthread_exit(0);
return;
}
static int test_ssl_threads(MYSQL *mysql)
@@ -291,6 +319,7 @@ static int test_ssl_threads(MYSQL *mysql)
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT into ssltest VALUES (0)");
check_mysql_rc(rc, mysql);
pthread_mutex_init(&LOCK_test, NULL);
pthread_mutex_init(&LOCK_test, NULL);
@@ -478,7 +507,7 @@ static int test_conc50_3(MYSQL *my)
mysql_ssl_set(mysql, NULL, NULL, "@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/ca-cert.pem", NULL, NULL);
mysql_real_connect(mysql, hostname, "ssltest", NULL, schema,
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
port, socketname, 0);
diag("Error: %s<", mysql_error(mysql));
FAIL_IF(mysql_errno(mysql), "No error expected");
@@ -640,12 +669,16 @@ static int test_conc_102(MYSQL *mysql)
DWORD threads[50];
#endif
if (check_skip_ssl())
return SKIP;
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t_conc102");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE t_conc102 ( a int)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO t_conc102 VALUES (0)");
check_mysql_rc(rc, mysql);
pthread_mutex_init(&LOCK_test, NULL);
for (i=0; i < 50; i++)
{
@@ -665,6 +698,7 @@ static int test_conc_102(MYSQL *mysql)
WaitForSingleObject(hthreads[i], INFINITE);
#endif
}
pthread_mutex_destroy(&LOCK_test);
rc= mysql_query(mysql, "SELECT a FROM t_conc102");
check_mysql_rc(rc, mysql);
res= mysql_store_result(mysql);
@@ -699,10 +733,10 @@ static int test_ssl_fp(MYSQL *unused)
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
mysql_query(my, "SET @a:=1");
rc= mysql_query(my, "SET @a:=1");
check_mysql_rc(rc, my);
mysql_query(my, "SELECT @a");
rc= mysql_query(my, "SELECT @a");
check_mysql_rc(rc, my);
if ((res= mysql_store_result(my)))
@@ -738,6 +772,32 @@ static int test_ssl_fp_list(MYSQL *unused)
return OK;
}
static int test_ssl_version(MYSQL *mysql)
{
unsigned int iversion;
char *version;
MYSQL *my;
if (check_skip_ssl())
return SKIP;
my= mysql_init(NULL);
FAIL_IF(!my, "mysql_init() failed");
mysql_ssl_set(my,0, 0, "@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/ca-cert.pem", 0, 0);
FAIL_IF(!mysql_real_connect(my, hostname, ssluser, sslpw, schema,
port, socketname, 0), mysql_error(my));
diag("cipher: %s", mysql_get_ssl_cipher(my));
mariadb_get_infov(my, MARIADB_CONNECTION_SSL_VERSION_ID, &iversion);
diag("protocol: %d", iversion);
mariadb_get_infov(my, MARIADB_CONNECTION_SSL_VERSION, &version);
diag("protocol: %s", version);
mysql_close(my);
return OK;
}
struct my_tests_st my_tests[] = {
@@ -757,9 +817,11 @@ struct my_tests_st my_tests[] = {
{"test_ssl_cipher", test_ssl_cipher, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_multi_ssl_connections", test_multi_ssl_connections, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_conc_102", test_conc_102, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_ssl_version", test_ssl_version, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_ssl_threads", test_ssl_threads, TEST_CONNECTION_NEW, 0, NULL, NULL},
#ifndef HAVE_SCHANNEL
{"test_password_protected", test_password_protected, TEST_CONNECTION_NEW, 0, NULL, NULL},
#endif
{NULL, NULL, 0, 0, NULL, NULL}
};

View File

@@ -0,0 +1,67 @@
/*
*/
#include "my_test.h"
static int aurora1(MYSQL *mysql)
{
int rc;
my_bool read_only= 1;
char *primary, *replica;
MYSQL_RES *res;
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE t1 (a int, b varchar(20))");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1, 'foo'), (2, 'bar')");
check_mysql_rc(rc, mysql);
primary= mysql->host;
diag("primary: %s", primary);
mysql_options(mysql, MARIADB_OPT_CONNECTION_READ_ONLY, &read_only);
/* ensure, that this is a replica, so INSERT should fail */
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (3, 'error')");
if (rc)
diag("Expected error: %s", mysql_error(mysql));
rc= mysql_query(mysql, "SELECT a, b FROM t1");
check_mysql_rc(rc, mysql);
res= mysql_store_result(mysql);
diag("Num_rows: %d", mysql_num_rows(res));
mysql_free_result(res);
replica= mysql->host;
diag("replica: %s", replica);
diag("db: %s", mysql->db);
return OK;
}
struct my_tests_st my_tests[] = {
{"aurora1", aurora1, TEST_CONNECTION_NEW, 0, NULL, NULL},
{NULL, NULL, 0, 0, NULL, NULL}
};
int main(int argc, char **argv)
{
mysql_library_init(0,0,NULL);
if (argc > 1)
get_options(argc, argv);
get_envvars();
run_tests(my_tests);
mysql_server_end();
return(exit_status());
}

View File

@@ -789,7 +789,7 @@ win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, s
if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL)
{
tomode = cd->to.mode;
outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft);
outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, (int)*outbytesleft);
if (outsize == -1)
{
if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
@@ -816,7 +816,7 @@ win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, s
tomode = cd->to.mode;
wsize = MB_CHAR_MAX;
insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize);
insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, (int)*inbytesleft, wbuf, &wsize);
if (insize == -1)
{
if (cd->to.flags & FLAG_IGNORE)
@@ -867,7 +867,7 @@ win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, s
}
}
outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft);
outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, (int)*outbytesleft);
if (outsize == -1)
{
if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)

View File

@@ -57,7 +57,11 @@ IF(NOT WIX_DIR)
SET(WIX_DIR $ENV{WIX}/bin)
ENDIF()
SET(MSI_PACKAGE "mariadb-connector-c-${PRODUCT_VERSION}-${PLATFORM}.msi")
IF(NOT PACKAGE_STATUS_SUFFIX)
SET(MSI_PACKAGE "mariadb-connector-c-${PRODUCT_VERSION}-${PLATFORM}.msi")
ELSE()
SET(MSI_PACKAGE "mariadb-connector-c-${PRODUCT_VERSION}-${PACKAGE_STATUS_SUFFIX}-${PLATFORM}.msi")
ENDIF()
IF(WITH_SIGNCODE)
IF(EXISTS "/tools/sign.bat")