diff options
author | Michael Widenius <monty@askmonty.org> | 2012-08-14 17:23:34 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-08-14 17:23:34 +0300 |
commit | 60589aeee03949033c66da5c1eae70d4342179fc (patch) | |
tree | 1cd399dbed17c5c7b4ed16eb7b872dc979af1c93 /sql-common | |
parent | b39e6e3d093b45f792959ef06fea1c175263ae1a (diff) | |
download | mariadb-git-60589aeee03949033c66da5c1eae70d4342179fc.tar.gz |
Next part of merge. See TODO for details
Diffstat (limited to 'sql-common')
-rw-r--r-- | sql-common/client.c | 168 |
1 files changed, 122 insertions, 46 deletions
diff --git a/sql-common/client.c b/sql-common/client.c index 337e5b7458c..05688a33730 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -143,6 +143,37 @@ CHARSET_INFO *default_client_charset_info = &my_charset_latin1; unsigned int mysql_server_last_errno; char mysql_server_last_error[MYSQL_ERRMSG_SIZE]; +/** + Convert the connect timeout option to a timeout value for VIO + functions (vio_socket_connect() and vio_io_wait()). + + @param mysql Connection handle (client side). + + @return The timeout value in milliseconds, or -1 if no timeout. +*/ + +static int get_vio_connect_timeout(MYSQL *mysql) +{ + int timeout_ms; + uint timeout_sec; + + /* + A timeout of 0 means no timeout. Also, the connect_timeout + option value is in seconds, while VIO timeouts are measured + in milliseconds. Hence, check for a possible overflow. In + case of overflow, set to no timeout. + */ + timeout_sec= mysql->options.connect_timeout; + + if (!timeout_sec || (timeout_sec > INT_MAX/1000)) + timeout_ms= -1; + else + timeout_ms= (int) (timeout_sec * 1000); + + return timeout_ms; +} + + /**************************************************************************** A modified version of connect(). my_connect() allows you to specify a timeout value, in seconds, that we should wait until we @@ -1139,6 +1170,7 @@ static const char *default_options[]= "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name", "multi-results", "multi-statements", "multi-queries", "secure-auth", "report-data-truncation", "plugin-dir", "default-auth", + "bind-address", "ssl-crl", "ssl-crlpath", NullS }; enum option_id { @@ -1150,6 +1182,7 @@ enum option_id { OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name, OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth, OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth, + OPT_bind_address, OPT_ssl_crl, OPT_ssl_crlpath, OPT_keep_this_one_last }; @@ -1187,12 +1220,28 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd) (OPTS)->extension= (struct st_mysql_options_extention *) \ my_malloc(sizeof(struct st_mysql_options_extention), \ MYF(MY_WME | MY_ZEROFILL)); \ - (OPTS)->extension->X= VAL; + (OPTS)->extension->X= (VAL); + +#define EXTENSION_SET_STRING_MAYBE_NULL(OPTS, X, STR) \ + if ((OPTS)->extension) \ + my_free((OPTS)->extension->X); \ + EXTENSION_SET(OPTS, X, (STR) ? my_strdup((STR), MYF(MY_WME)) : NullS); #define EXTENSION_SET_STRING(OPTS, X, STR) \ if ((OPTS)->extension) \ my_free((OPTS)->extension->X); \ - EXTENSION_SET(OPTS, X, my_strdup((STR), MYF(MY_WME))); + EXTENSION_SET(OPTS, X, my_strdup((STR), MYF(MY_WME))) + +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) +#define SET_SSL_OPTION(OPTS, opt_var, arg) \ + my_free((OPTS)->opt_var); \ + (OPTS)->opt_var= arg ? my_strdup(arg, MYF(MY_WME)) : NULL; +#define EXTENSION_SET_SSL_STRING(OPTS, X, STR) \ + EXTENSION_SET_STRING_MAYBE_NULL((OPTS), X, (STR)); +#else +#define SET_SSL_OPTION(OPTS, opt_var,arg) do { } while(0) +#define EXTENSION_SET_SSL_STRING(OPTS, X, STR) do { } while(0) +#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */ void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group) @@ -1296,35 +1345,27 @@ void mysql_read_default_options(struct st_mysql_options *options, case OPT_return_found_rows: options->client_flag|=CLIENT_FOUND_ROWS; break; -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) case OPT_ssl_key: - my_free(options->ssl_key); - options->ssl_key = my_strdup(opt_arg, MYF(MY_WME)); + SET_SSL_OPTION(options, ssl_key, opt_arg); break; case OPT_ssl_cert: - my_free(options->ssl_cert); - options->ssl_cert = my_strdup(opt_arg, MYF(MY_WME)); + SET_SSL_OPTION(options, ssl_cert, opt_arg); break; case OPT_ssl_ca: - my_free(options->ssl_ca); - options->ssl_ca = my_strdup(opt_arg, MYF(MY_WME)); + SET_SSL_OPTION(options, ssl_ca, opt_arg); break; case OPT_ssl_capath: - my_free(options->ssl_capath); - options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME)); + SET_SSL_OPTION(options, ssl_capath, opt_arg); break; case OPT_ssl_cipher: - my_free(options->ssl_cipher); - options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME)); + SET_SSL_OPTION(options, ssl_cipher, opt_arg); + break; + case OPT_ssl_crl: + EXTENSION_SET_SSL_STRING(options, ssl_crl, opt_arg); + break; + case OPT_ssl_crlpath: + EXTENSION_SET_SSL_STRING(options, ssl_crlpath, opt_arg); break; -#else - case OPT_ssl_key: - case OPT_ssl_cert: - case OPT_ssl_ca: - case OPT_ssl_capath: - case OPT_ssl_cipher: - break; -#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ case OPT_character_sets_dir: my_free(options->charset_dir); options->charset_dir = my_strdup(opt_arg, MYF(MY_WME)); @@ -1761,12 +1802,11 @@ mysql_init(MYSQL *mysql) /* - Fill in SSL part of MYSQL structure and set 'use_ssl' flag. + Fill in SSL part of MYSQL structure. NB! Errors are not reported until you do mysql_real_connect. + use_ssl is set in send_client_reply_packet if any ssl option is set. */ -#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME)) - my_bool STDCALL mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , const char *key __attribute__((unused)), @@ -1775,20 +1815,17 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , const char *capath __attribute__((unused)), const char *cipher __attribute__((unused))) { + my_bool result= 0; DBUG_ENTER("mysql_ssl_set"); #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - my_free(mysql->options.ssl_key); - my_free(mysql->options.ssl_cert); - my_free(mysql->options.ssl_ca); - my_free(mysql->options.ssl_capath); - my_free(mysql->options.ssl_cipher); - mysql->options.ssl_key= strdup_if_not_null(key); - mysql->options.ssl_cert= strdup_if_not_null(cert); - mysql->options.ssl_ca= strdup_if_not_null(ca); - mysql->options.ssl_capath= strdup_if_not_null(capath); - mysql->options.ssl_cipher= strdup_if_not_null(cipher); + result= (mysql_options(mysql, MYSQL_OPT_SSL_KEY, key) | + mysql_options(mysql, MYSQL_OPT_SSL_CERT, cert) | + mysql_options(mysql, MYSQL_OPT_SSL_CA, ca) | + mysql_options(mysql, MYSQL_OPT_SSL_CAPATH, capath) | + mysql_options(mysql, MYSQL_OPT_SSL_CIPHER, cipher) ? + 1 : 0); #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ - DBUG_RETURN(0); + DBUG_RETURN(result); } @@ -1810,6 +1847,11 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) my_free(mysql->options.ssl_ca); my_free(mysql->options.ssl_capath); my_free(mysql->options.ssl_cipher); + if (mysql->options.extension) + { + my_free(mysql->options.extension->ssl_crl); + my_free(mysql->options.extension->ssl_crlpath); + } if (ssl_fd) SSL_CTX_free(ssl_fd->ssl_context); my_free(mysql->connector_fd); @@ -1818,6 +1860,11 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) mysql->options.ssl_ca = 0; mysql->options.ssl_capath = 0; mysql->options.ssl_cipher= 0; + if (mysql->options.extension) + { + mysql->options.extension->ssl_crl = 0; + mysql->options.extension->ssl_crlpath = 0; + } mysql->options.use_ssl = FALSE; mysql->connector_fd = 0; DBUG_VOID_RETURN; @@ -2461,7 +2508,10 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) if (mysql->options.ssl_key || mysql->options.ssl_cert || mysql->options.ssl_ca || mysql->options.ssl_capath || - mysql->options.ssl_cipher) + mysql->options.ssl_cipher || + (mysql->options.extension && + (mysql->options.extension->ssl_crl || + mysql->options.extension->ssl_crlpath))) mysql->options.use_ssl= 1; if (mysql->options.use_ssl) mysql->client_flag|= CLIENT_SSL; @@ -2522,7 +2572,11 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, options->ssl_ca, options->ssl_capath, options->ssl_cipher, - &ssl_init_error))) + &ssl_init_error, + options->extension ? + options->extension->ssl_crl : NULL, + options->extension ? + options->extension->ssl_crlpath : NULL))) { set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, ER(CR_SSL_CONNECTION_ERROR), sslGetErrString(ssl_init_error)); @@ -2726,21 +2780,21 @@ void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info) switch (vio->type) { case VIO_TYPE_TCPIP: info->protocol= MYSQL_VIO_TCP; - info->socket= vio->sd; + info->socket= vio_fd(vio); return; case VIO_TYPE_SOCKET: info->protocol= MYSQL_VIO_SOCKET; - info->socket= vio->sd; + info->socket= vio_fd(vio); return; case VIO_TYPE_SSL: { struct sockaddr addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - if (getsockname(vio->sd, &addr, &addrlen)) + if (getsockname(vio_fd(vio), &addr, &addrlen)) return; info->protocol= addr.sa_family == AF_UNIX ? MYSQL_VIO_SOCKET : MYSQL_VIO_TCP; - info->socket= vio->sd; + info->socket= vio_fd(vio); return; } #ifdef _WIN32 @@ -3304,7 +3358,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* Get version info */ mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */ if (mysql->options.connect_timeout && - vio_poll_read(net->vio, mysql->options.connect_timeout)) + (vio_io_wait(net->vio, VIO_IO_EVENT_READ, + get_vio_connect_timeout(mysql)) < 1)) { set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate, ER(CR_SERVER_LOST_EXTENDED), @@ -3920,7 +3975,6 @@ mysql_send_query(MYSQL* mysql, const char* query, ulong length) DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1)); } - int STDCALL mysql_real_query(MYSQL *mysql, const char *query, ulong length) { @@ -4171,6 +4225,7 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.methods_to_use= option; break; case MYSQL_SET_CLIENT_IP: + my_free(mysql->options.client_ip); mysql->options.client_ip= my_strdup(arg, MYF(MY_WME)); break; case MYSQL_SECURE_AUTH: @@ -4189,10 +4244,10 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT; break; case MYSQL_PLUGIN_DIR: - EXTENSION_SET_STRING(&mysql->options, plugin_dir, arg); + EXTENSION_SET_STRING_MAYBE_NULL(&mysql->options, plugin_dir, arg); break; case MYSQL_DEFAULT_AUTH: - EXTENSION_SET_STRING(&mysql->options, default_auth, arg); + EXTENSION_SET_STRING_MAYBE_NULL(&mysql->options, default_auth, arg); break; case MYSQL_PROGRESS_CALLBACK: if (!mysql->options.extension) @@ -4236,6 +4291,27 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) if (mysql->net.vio) mysql->net.vio->async_context= ctxt; break; + case MYSQL_OPT_SSL_KEY: + SET_SSL_OPTION(&mysql->options,ssl_key, arg); + break; + case MYSQL_OPT_SSL_CERT: + SET_SSL_OPTION(&mysql->options, ssl_cert, arg); + break; + case MYSQL_OPT_SSL_CA: + SET_SSL_OPTION(&mysql->options,ssl_ca, arg); + break; + case MYSQL_OPT_SSL_CAPATH: + SET_SSL_OPTION(&mysql->options,ssl_capath, arg); + break; + case MYSQL_OPT_SSL_CIPHER: + SET_SSL_OPTION(&mysql->options,ssl_cipher, arg); + break; + case MYSQL_OPT_SSL_CRL: + EXTENSION_SET_SSL_STRING(&mysql->options, ssl_crl, arg); + break; + case MYSQL_OPT_SSL_CRLPATH: + EXTENSION_SET_SSL_STRING(&mysql->options, ssl_crlpath, arg); + break; default: DBUG_RETURN(1); } @@ -4450,6 +4526,6 @@ my_socket STDCALL mysql_get_socket(const MYSQL *mysql) { if (mysql->net.vio) - return mysql->net.vio->sd; + return vio_fd(mysql->net.vio); return INVALID_SOCKET; } |