@@ -3587,6 +3587,7 @@ static void mysql_ssl_free(MYSQL *mysql) {
35873587 my_free (mysql->options .extension ->ssl_crlpath );
35883588 my_free (mysql->options .extension ->tls_ciphersuites );
35893589 my_free (mysql->options .extension ->load_data_dir );
3590+ my_free (mysql->options .extension ->tls_sni_servername );
35903591 for (unsigned int idx = 0 ; idx < MAX_AUTHENTICATION_FACTOR ; idx++) {
35913592 if (mysql->options .extension ->client_auth_info [idx].plugin_name ) {
35923593 my_free (mysql->options .extension ->client_auth_info [idx].plugin_name );
@@ -3613,6 +3614,7 @@ static void mysql_ssl_free(MYSQL *mysql) {
36133614 mysql->options .extension ->ssl_fips_mode = SSL_FIPS_MODE_OFF ;
36143615 mysql->options .extension ->tls_ciphersuites = nullptr ;
36153616 mysql->options .extension ->load_data_dir = nullptr ;
3617+ mysql->options .extension ->tls_sni_servername = nullptr ;
36163618 }
36173619 mysql->connector_fd = nullptr ;
36183620}
@@ -4649,27 +4651,39 @@ static int cli_establish_ssl(MYSQL *mysql) {
46494651 /* Connect to the server */
46504652 DBUG_PRINT (" info" , (" IO layer change in progress..." ));
46514653 MYSQL_TRACE (SSL_CONNECT , mysql, ());
4652- ssize_t ret = sslconnect (ssl_fd, net->vio ,
4653- timeout_to_seconds (mysql->options .connect_timeout ),
4654- ssl_session, &ssl_error, nullptr );
4654+ ssize_t ret = sslconnect (
4655+ ssl_fd, net->vio , timeout_to_seconds (mysql->options .connect_timeout ),
4656+ ssl_session, &ssl_error, nullptr ,
4657+ options->extension ? options->extension ->tls_sni_servername : nullptr );
46554658 if (ssl_session != nullptr ) SSL_SESSION_free (ssl_session);
4656- switch (ret) {
4657- case VIO_SOCKET_ERROR :
4658- char ssl_buf[512 ];
4659- char buf[1025 ];
4660- ERR_error_string_n (ssl_error, ssl_buf, 512 );
4661- ssl_buf[511 ] = 0 ;
4662- snprintf (buf, sizeof (buf) - 1 , " %s (errno %d)" , ssl_buf, errno);
4659+ if (ret) {
4660+ switch (ret) {
4661+ case VIO_SOCKET_READ_TIMEOUT :
4662+ set_mysql_error (mysql, CR_NET_READ_INTERRUPTED , unknown_sqlstate);
4663+ goto error;
4664+ case VIO_SOCKET_WRITE_TIMEOUT :
4665+ set_mysql_error (mysql, CR_NET_WRITE_INTERRUPTED , unknown_sqlstate);
4666+ goto error;
4667+ default :
4668+ break ;
4669+ /* continue for error handling */
4670+ }
4671+ char ssl_buf[512 ];
4672+ char buf[1025 ];
4673+ ERR_error_string_n (ssl_error, ssl_buf, 512 );
4674+ ssl_buf[511 ] = 0 ;
4675+ snprintf (buf, sizeof (buf) - 1 , " %s (errno %d)" , ssl_buf, errno);
4676+
4677+ if (ERR_GET_REASON (ssl_error) == SSL_R_TLSV1_UNRECOGNIZED_NAME ) {
4678+ set_mysql_extended_error (mysql, CR_TLS_SERVER_NOT_FOUND ,
4679+ unknown_sqlstate,
4680+ ER_CLIENT (CR_TLS_SERVER_NOT_FOUND ), buf);
4681+ } else {
46634682 set_mysql_extended_error (mysql, CR_SSL_CONNECTION_ERROR ,
46644683 unknown_sqlstate,
46654684 ER_CLIENT (CR_SSL_CONNECTION_ERROR ), buf);
4666- goto error;
4667- case VIO_SOCKET_READ_TIMEOUT :
4668- set_mysql_error (mysql, CR_NET_READ_INTERRUPTED , unknown_sqlstate);
4669- goto error;
4670- case VIO_SOCKET_WRITE_TIMEOUT :
4671- set_mysql_error (mysql, CR_NET_WRITE_INTERRUPTED , unknown_sqlstate);
4672- goto error;
4685+ }
4686+ goto error;
46734687 }
46744688 DBUG_PRINT (" info" , (" IO layer change done!" ));
46754689
@@ -4834,7 +4848,10 @@ static net_async_status cli_establish_ssl_nonblocking(MYSQL *mysql, int *res) {
48344848 MYSQL_TRACE (SSL_CONNECT , mysql, ());
48354849 if ((ret = sslconnect (ssl_fd, net->vio ,
48364850 timeout_to_seconds (mysql->options .connect_timeout ),
4837- ssl_session, &ssl_error, &ctx->ssl ))) {
4851+ ssl_session, &ssl_error, &ctx->ssl ,
4852+ options->extension
4853+ ? options->extension ->tls_sni_servername
4854+ : nullptr ))) {
48384855 if (ssl_session != nullptr ) SSL_SESSION_free (ssl_session);
48394856 switch (ret) {
48404857 case VIO_SOCKET_WANT_READ :
@@ -4859,8 +4876,17 @@ static net_async_status cli_establish_ssl_nonblocking(MYSQL *mysql, int *res) {
48594876 ERR_error_string_n (ssl_error, ssl_buf, 512 );
48604877 ssl_buf[511 ] = 0 ;
48614878 snprintf (buf, sizeof (buf) - 1 , " %s (errno %d)" , ssl_buf, errno);
4862- set_mysql_extended_error (mysql, CR_SSL_CONNECTION_ERROR , unknown_sqlstate,
4863- ER_CLIENT (CR_SSL_CONNECTION_ERROR ), buf);
4879+
4880+ if (ERR_GET_REASON (ssl_error) == SSL_R_TLSV1_UNRECOGNIZED_NAME ) {
4881+ set_mysql_extended_error (mysql, CR_TLS_SERVER_NOT_FOUND ,
4882+ unknown_sqlstate,
4883+ ER_CLIENT (CR_TLS_SERVER_NOT_FOUND ), buf);
4884+ } else {
4885+ set_mysql_extended_error (mysql, CR_SSL_CONNECTION_ERROR ,
4886+ unknown_sqlstate,
4887+ ER_CLIENT (CR_SSL_CONNECTION_ERROR ), buf);
4888+ }
4889+
48644890 goto error;
48654891 }
48664892 if (ssl_session != nullptr ) SSL_SESSION_free (ssl_session);
@@ -8942,6 +8968,10 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
89428968 EXTENSION_SET_STRING (&mysql->options , tls_ciphersuites,
89438969 static_cast <const char *>(arg));
89448970 break ;
8971+ case MYSQL_OPT_TLS_SNI_SERVERNAME :
8972+ EXTENSION_SET_STRING (&mysql->options , tls_sni_servername,
8973+ static_cast <const char *>(arg));
8974+ break ;
89458975 case MYSQL_OPT_SSL_CRL :
89468976 if (mysql->options .extension )
89478977 my_free (mysql->options .extension ->ssl_crl );
@@ -9231,6 +9261,7 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
92319261 MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER,
92329262 MYSQL_OPT_TLS_CIPHERSUITES, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
92339263 MYSQL_OPT_TLS_VERSION, MYSQL_SERVER_PUBLIC_KEY, MYSQL_OPT_SSL_FIPS_MODE
9264+ MYSQL_OPT_TLS_SNI_SERVERNAME
92349265
92359266 <none, error returned>
92369267 MYSQL_OPT_NAMED_PIPE, MYSQL_OPT_CONNECT_ATTR_RESET,
@@ -9364,6 +9395,12 @@ int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option,
93649395 mysql->options .extension ? mysql->options .extension ->tls_ciphersuites
93659396 : nullptr ;
93669397 break ;
9398+ case MYSQL_OPT_TLS_SNI_SERVERNAME :
9399+ *(static_cast <char **>(const_cast <void *>(arg))) =
9400+ mysql->options .extension
9401+ ? mysql->options .extension ->tls_sni_servername
9402+ : nullptr ;
9403+ break ;
93679404 case MYSQL_OPT_RETRY_COUNT :
93689405 *(const_cast <uint *>(static_cast <const uint *>(arg))) =
93699406 mysql->options .extension ? mysql->options .extension ->retry_count : 1 ;
0 commit comments