You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
OpenSSL timeout fix:
Since timeout was already set via setsockopt, we call wait_io_or_timeout() with a very small timeout (5ms) to get a more precise errno, which is used by OpenSSL's error function.
This commit is contained in:
@@ -567,11 +567,13 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
{
|
{
|
||||||
switch((SSL_get_error(ssl, rc))) {
|
switch((SSL_get_error(ssl, rc))) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, mysql->options.connect_timeout) < 1)
|
/* use low timeout, see ma_tls_read */
|
||||||
|
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, 5) < 1)
|
||||||
try_connect= 0;
|
try_connect= 0;
|
||||||
break;
|
break;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, mysql->options.connect_timeout) < 1)
|
/* use low timeout, see ma_tls_read */
|
||||||
|
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, 5) < 1)
|
||||||
try_connect= 0;
|
try_connect= 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -655,7 +657,10 @@ ssize_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
|
|||||||
int error= SSL_get_error((SSL *)ctls->ssl, rc);
|
int error= SSL_get_error((SSL *)ctls->ssl, rc);
|
||||||
if (error != SSL_ERROR_WANT_READ)
|
if (error != SSL_ERROR_WANT_READ)
|
||||||
break;
|
break;
|
||||||
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, pvio->mysql->options.read_timeout) < 1)
|
/* To get a more precise error message than "resource temporary
|
||||||
|
unavailable" (=errno 11) after read timeout occured, we check
|
||||||
|
the socket status using a very small timeout (=5 ms) */
|
||||||
|
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, 5) < 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
@@ -676,7 +681,8 @@ ssize_t ma_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
|
|||||||
int error= SSL_get_error((SSL *)ctls->ssl, rc);
|
int error= SSL_get_error((SSL *)ctls->ssl, rc);
|
||||||
if (error != SSL_ERROR_WANT_WRITE)
|
if (error != SSL_ERROR_WANT_WRITE)
|
||||||
break;
|
break;
|
||||||
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, pvio->mysql->options.write_timeout) < 1)
|
/* use low timeout, see ma_tls_read */
|
||||||
|
if (pvio->methods->wait_io_or_timeout(pvio, TRUE, 5) < 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
|
@@ -2374,7 +2374,41 @@ static int test_parsec(MYSQL *my)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test for PR250 */
|
||||||
|
int test_tls_timeout(MYSQL *unused __attribute__((unused)))
|
||||||
|
{
|
||||||
|
unsigned int connect_timeout= 5;
|
||||||
|
unsigned int read_write_timeout= 10;
|
||||||
|
int rc;
|
||||||
|
time_t start, elapsed;
|
||||||
|
|
||||||
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
|
mysql_ssl_set(mysql, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (unsigned int *)&connect_timeout);
|
||||||
|
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (unsigned int *)&read_write_timeout);
|
||||||
|
mysql_options(mysql, MYSQL_OPT_WRITE_TIMEOUT, (unsigned int *)&read_write_timeout);
|
||||||
|
if (!my_test_connect(mysql, hostname, username, password, schema, port, socketname, CLIENT_REMEMBER_OPTIONS, 1))
|
||||||
|
{
|
||||||
|
mysql_close(mysql);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
start= time(NULL);
|
||||||
|
rc= mysql_query(mysql, "SET @a:=SLEEP(12)");
|
||||||
|
elapsed= time(NULL) - start;
|
||||||
|
diag("elapsed: %lu", (unsigned long)elapsed);
|
||||||
|
FAIL_IF((unsigned int)elapsed > read_write_timeout + 1, "timeout ignored");
|
||||||
|
|
||||||
|
FAIL_IF(!rc, "expected timeout error");
|
||||||
|
diag("Error: %s", mysql_error(mysql));
|
||||||
|
|
||||||
|
mysql_close(mysql);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
|
{"test_tls_timeout", test_tls_timeout, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_parsec", test_parsec, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_parsec", test_parsec, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc505", test_conc505, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_conc505", test_conc505, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_conc632", test_conc632, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_conc632", test_conc632, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
@@ -2423,6 +2457,7 @@ struct my_tests_st my_tests[] = {
|
|||||||
{"test_connection_timeout", test_connection_timeout, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_connection_timeout", test_connection_timeout, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_connection_timeout2", test_connection_timeout2, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_connection_timeout2", test_connection_timeout2, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_connection_timeout3", test_connection_timeout3, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_connection_timeout3", test_connection_timeout3, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
|
{"test_tls_timeout", test_tls_timeout, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{NULL, NULL, 0, 0, NULL, NULL}
|
{NULL, NULL, 0, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user