ocirocir
ocirocir

Reputation: 4058

Mariadb C API client returns "Connection timeout" / "Connection reset by peer" if CA SSL is provided

I'm writing a C++ client application connecting to a MariaDB server with a MariaDB C connector. This code works:

this->mysql = mysql_init(0);

int timeout_sec = 10;
int ret = mysql_options(this->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout_sec);
assert(ret == 0);

auto ret_mysql = mysql_real_connect(this->mysql,
                   this->host.c_str(),
                   this->username.c_str(),
                   this->password.c_str(),
                   this->db_name.c_str(),
                   this->port,
                   nullptr,
                   0);

if (ret_mysql == nullptr) {
    // An error occurred.
    throw MyException("Database",mysql_error(this->mysql));
}

However, I would like to enable SSL and, because I'm using a server with a self-signed certificate, I need to add the CA file, therefore I added (before the connect):

int ret;
ret = mysql_options(this->pimpl->mysql, MYSQL_OPT_SSL_CA, ca_file.c_str());
assert(ret == 0);

However, if I add these lines, the mysql_real_connect then fails with a "Connection timeout".

Extra notes:

Any idea what can be the problem? Perhaps, there is some other function to call before the connect?

--EDIT--

Apparently the problem was a SSL error due to a certificate common name mismatch. I fixed the issue and now it works. However, why if there is a problem with SSL it generates a timeout/connection reset by peer rather than returning an error as expected?

Upvotes: 0

Views: 163

Answers (1)

Diego Ferruchelli
Diego Ferruchelli

Reputation: 874

I'll try an answer to the updated question, guessing some details that aren't in your post.

The list of "Errors" documented for mysql_real_connect() doesn't include one for "TLS/SSL error: Validation of SSL server certificate failed". I guess you're getting a CR_SERVER_LOST ("If connect_timeout > 0 and it took longer than connect_timeout seconds to connect to the server or if the server died while executing the init-command.") This error is directly related to the MYSQL_OPT_CONNECT_TIMEOUT you're actually using. I think the server is just ignoring your call when the certificate is invalid, and that results in a timeout at the client (ie. the client aborts after waiting too much for a response).

I can't explain why you get a "Connection reset by peer" when you increase the timeout, but this error is signaled/detected by the client network layer after the server explicitly closes the communication channel (before the client times out).

The command-line 'mysql' client may be using an explicit call to MYSQL_OPT_SSL_MODE option with a value of SSL_MODE_VERIFY_CA. You could do the same using mysql_options(). Please check https://dev.mysql.com/doc/refman/8.0/en/connection-options.html#option_general_ssl-mode.

Upvotes: 0

Related Questions