diff --git a/include/errmsg.h b/include/errmsg.h index 21b199fe..3e91b6bb 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -105,7 +105,12 @@ extern const char *mariadb_client_errors[]; /* Error messages */ #define CR_PLUGIN_NOT_ALLOWED 5010 #define CR_CONNSTR_PARSE_ERROR 5011 #define CR_ERR_LOAD_PLUGIN 5012 +#define CR_ERR_NET_READ 5013 +#define CR_ERR_NET_WRITE 5014 +#define CR_ERR_NET_UNCOMPRESS 5015 + /* Always last, if you add new error codes please update the value for CR_MARIADB_LAST_ERROR */ -#define CR_MARIADB_LAST_ERROR CR_ERR_LOAD_PLUGIN +#define CR_MARIADB_LAST_ERROR CR_ERR_NET_UNCOMPRESS + #endif diff --git a/include/ma_global.h b/include/ma_global.h index d3f4a714..ff1fb009 100644 --- a/include/ma_global.h +++ b/include/ma_global.h @@ -33,6 +33,7 @@ #if _MSC_VER < 1900 #define snprintf _snprintf #endif +#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) #endif #define STDCALL __stdcall #endif diff --git a/libmariadb/ma_errmsg.c b/libmariadb/ma_errmsg.c index 9ddc49bc..3d2f725a 100644 --- a/libmariadb/ma_errmsg.c +++ b/libmariadb/ma_errmsg.c @@ -107,6 +107,9 @@ const char *mariadb_client_errors[] = /* 5010 */ "Authentication plugin '%s' couldn't be found in restricted_auth plugin list.", /* 5011 */ "Parse error in connection string (offset %d)", /* 5012 */ "Error while loading plugin '%s'", + /* 5013 */ "Read error: %s (%d)", + /* 5014 */ "Write error: %s (%d)", + /* 5015 */ "Error while uncompressing packet", "" }; diff --git a/libmariadb/ma_net.c b/libmariadb/ma_net.c index 185bffe4..35301090 100644 --- a/libmariadb/ma_net.c +++ b/libmariadb/ma_net.c @@ -29,7 +29,7 @@ #include #include #include "mysql.h" -#include "ma_server_error.h" +#include "errmsg.h" #include #include #include @@ -125,7 +125,7 @@ static my_bool net_realloc(NET *net, size_t length) if (length >= net->max_packet_size) { net->error=1; - net->last_errno=ER_NET_PACKET_TOO_LARGE; + net->pvio->set_error(net->pvio->mysql, CR_NET_PACKET_TOO_LARGE, SQLSTATE_UNKNOWN, 0); return(1); } pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); @@ -313,7 +313,7 @@ int ma_net_real_write(NET *net, const char *packet, size_t len) uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; if (!(b=(uchar*) malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1))) { - net->last_errno=ER_OUT_OF_RESOURCES; + net->pvio->set_error(net->pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); net->error=2; net->reading_or_writing=0; return(1); @@ -337,8 +337,13 @@ int ma_net_real_write(NET *net, const char *packet, size_t len) { if ((length=ma_pvio_write(net->pvio,(uchar *)pos,(size_t) (end-pos))) <= 0) { + int save_errno= errno; + char errmsg[100]; + net->error=2; /* Close socket */ - net->last_errno= ER_NET_ERROR_ON_WRITE; + strerror_r(save_errno, errmsg, 100); + net->pvio->set_error(net->pvio->mysql, CR_ERR_NET_WRITE, SQLSTATE_UNKNOWN, 0, + errmsg, save_errno); net->reading_or_writing=0; #ifdef HAVE_COMPRESS if (net->compress) @@ -557,8 +562,7 @@ ulong ma_net_read(NET *net) if (_mariadb_uncompress(net, (unsigned char*) net->buff + net->where_b, &packet_length, &complen)) { net->error=2; /* caller will close socket */ - net->last_errno=ER_NET_UNCOMPRESS_ERROR; - break; + net->pvio->set_error(net->pvio->mysql, CR_ERR_NET_UNCOMPRESS, SQLSTATE_UNKNOWN, 0); return packet_error; } buffer_length+= complen; diff --git a/libmariadb/ma_tls.c b/libmariadb/ma_tls.c index a5401f95..3f48ad8b 100644 --- a/libmariadb/ma_tls.c +++ b/libmariadb/ma_tls.c @@ -232,6 +232,6 @@ end: void ma_pvio_tls_set_connection(MYSQL *mysql) { - return ma_tls_set_connection(mysql); + ma_tls_set_connection(mysql); } #endif /* HAVE_TLS */ diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index f5a47999..882d8d58 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -1767,7 +1767,8 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned lon goto fail; if (!is_multi && mysql->net.extension->multi_status == COM_MULTI_ENABLED) - ma_multi_command(mysql, COM_MULTI_END); + if (ma_multi_command(mysql, COM_MULTI_END)) + goto fail; if (mysql->net.extension->multi_status > COM_MULTI_OFF || mysql->options.extension->skip_read_response) diff --git a/libmariadb/secure/gnutls.c b/libmariadb/secure/gnutls.c index 8218b78f..805ea4f7 100644 --- a/libmariadb/secure/gnutls.c +++ b/libmariadb/secure/gnutls.c @@ -878,12 +878,7 @@ static void ma_tls_set_error(MYSQL *mysql, void *ssl, int ssl_errno) char ssl_error[MAX_SSL_ERR_LEN]; const char *ssl_error_reason; MARIADB_PVIO *pvio= mysql->net.pvio; - - if (!ssl_errno) - { - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown SSL error"); - return; - } + int save_errno= errno; /* give a more descriptive error message for alerts */ if (ssl_errno == GNUTLS_E_FATAL_ALERT_RECEIVED) @@ -898,15 +893,16 @@ static void ma_tls_set_error(MYSQL *mysql, void *ssl, int ssl_errno) return; } - if ((ssl_error_reason= gnutls_strerror(ssl_errno))) + if (ssl_errno && (ssl_error_reason= gnutls_strerror(ssl_errno))) { - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, + pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, ssl_error_reason); return; } - snprintf(ssl_error, MAX_SSL_ERR_LEN, "SSL errno=%d", ssl_errno); - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, - ssl_error); + + strerror_r(save_errno, ssl_error, MAX_SSL_ERR_LEN); + pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "TLS/SSL error: %s (%d)", + ssl_error, save_errno); } diff --git a/libmariadb/secure/openssl.c b/libmariadb/secure/openssl.c index b7e2e79b..7ab94954 100644 --- a/libmariadb/secure/openssl.c +++ b/libmariadb/secure/openssl.c @@ -125,20 +125,18 @@ static void ma_tls_set_error(MYSQL *mysql) char ssl_error[MAX_SSL_ERR_LEN]; const char *ssl_error_reason; MARIADB_PVIO *pvio= mysql->net.pvio; + int save_errno= errno; - if (!ssl_errno) - { - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown SSL error"); - return; - } - if ((ssl_error_reason= ERR_reason_error_string(ssl_errno))) + if (ssl_errno && (ssl_error_reason= ERR_reason_error_string(ssl_errno))) { pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, ssl_error_reason); return; } - snprintf(ssl_error, MAX_SSL_ERR_LEN, "SSL errno=%lu", ssl_errno); - pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, ssl_error); + + strerror_r(save_errno, ssl_error, MAX_SSL_ERR_LEN); + pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "TLS/SSL error: %s (%d)", + ssl_error, save_errno); return; } diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index 227daf0f..39f7907a 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -682,7 +682,7 @@ int test_connection_timeout2(MYSQL *unused __attribute__((unused))) SKIP_SKYSQL; SKIP_MAXSCALE; -// SKIP_TLS; + SKIP_TLS; mysql= mysql_init(NULL); mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (unsigned int *)&timeout);