Skip to content

Commit 45983da

Browse files
authored
mysql client should retry to establish an unsecured connection when failing to complete the SSL handshake in PREFERRED SSL mode (#1229)
Signed-off-by: Billy Yuan <billy112487983@gmail.com> Signed-off-by: Billy Yuan <billy112487983@gmail.com>
1 parent 4928497 commit 45983da

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ protected void configureNetClientOptions(NetClientOptions netClientOptions) {
114114

115115
@Override
116116
protected Future<Connection> doConnectInternal(SocketAddress server, String username, String password, String database, EventLoopContext context) {
117+
if (sslMode == SslMode.PREFERRED) {
118+
return doConnect(server, username, password, database, sslMode, context).recover(err -> doConnect(server, username, password, database, SslMode.DISABLED, context));
119+
} else {
120+
return doConnect(server, username, password, database, sslMode, context);
121+
}
122+
}
123+
124+
private Future<Connection> doConnect(SocketAddress server, String username, String password, String database, SslMode sslMode, EventLoopContext context) {
117125
Future<NetSocket> fut = netClient.connect(server);
118126
return fut.flatMap(so -> {
119127
MySQLSocketConnection conn = new MySQLSocketConnection((NetSocketInternal) so, cachePreparedStatements, preparedStatementCacheSize, preparedStatementCacheSqlFilter, pipeliningLimit, context);

vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLTLSTest.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
package io.vertx.mysqlclient;
1313

1414
import io.vertx.core.Vertx;
15+
import io.vertx.core.buffer.Buffer;
1516
import io.vertx.core.net.PemKeyCertOptions;
1617
import io.vertx.core.net.PemTrustOptions;
1718
import io.vertx.ext.unit.TestContext;
@@ -31,14 +32,18 @@ public class MySQLTLSTest {
3132
@ClassRule
3233
public static MySQLRule rule = MySQLRule.SHARED_TLS_INSTANCE;
3334

35+
@ClassRule
36+
public static MySQLRule nonTlsRule = MySQLRule.SHARED_INSTANCE;
37+
3438
Vertx vertx;
3539
MySQLConnectOptions options;
40+
MySQLConnectOptions nonTlsOptions;
3641

3742
@Before
3843
public void setup() {
3944
vertx = Vertx.vertx();
4045
options = new MySQLConnectOptions(rule.options());
41-
46+
nonTlsOptions = new MySQLConnectOptions(nonTlsRule.options());
4247
/*
4348
* For testing we have to drop using the TLSv1.2.
4449
*
@@ -79,7 +84,7 @@ public void testSuccessWithDisabledSslMode(TestContext ctx) {
7984
}
8085

8186
@Test
82-
public void testSuccessWithPreferredSslMode(TestContext ctx) {
87+
public void testTlsSuccessWithPreferredSslMode(TestContext ctx) {
8388
options.setSslMode(SslMode.PREFERRED);
8489
options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem"));
8590
options.setPemKeyCertOptions(new PemKeyCertOptions()
@@ -95,6 +100,40 @@ public void testSuccessWithPreferredSslMode(TestContext ctx) {
95100
}));
96101
}
97102

103+
@Test
104+
public void testTlsHandshakeFailWithPreferredSslMode(TestContext ctx) {
105+
options.setSslMode(SslMode.PREFERRED);
106+
options.setPemTrustOptions(new PemTrustOptions().addCertValue(Buffer.buffer("INVALID CERT")));
107+
options.setPemKeyCertOptions(new PemKeyCertOptions()
108+
.setCertPath("tls/files/client-cert.pem")
109+
.setKeyPath("tls/files/client-key.pem"));
110+
111+
MySQLConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
112+
ctx.assertFalse(conn.isSSL());
113+
conn.query("SELECT 1").execute(ctx.asyncAssertSuccess(res -> {
114+
ctx.assertEquals(1, res.size());
115+
conn.close();
116+
}));
117+
}));
118+
}
119+
120+
@Test
121+
public void testNonTlsConnWithPreferredSslMode(TestContext ctx) {
122+
nonTlsOptions.setSslMode(SslMode.PREFERRED);
123+
nonTlsOptions.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem"));
124+
nonTlsOptions.setPemKeyCertOptions(new PemKeyCertOptions()
125+
.setCertPath("tls/files/client-cert.pem")
126+
.setKeyPath("tls/files/client-key.pem"));
127+
128+
MySQLConnection.connect(vertx, nonTlsOptions, ctx.asyncAssertSuccess(conn -> {
129+
ctx.assertFalse(conn.isSSL());
130+
conn.query("SELECT 1").execute(ctx.asyncAssertSuccess(res -> {
131+
ctx.assertEquals(1, res.size());
132+
conn.close();
133+
}));
134+
}));
135+
}
136+
98137
@Test
99138
public void testSuccessWithRequiredSslMode(TestContext ctx) {
100139
options.setSslMode(SslMode.REQUIRED);

vertx-mysql-client/src/test/java/io/vertx/mysqlclient/junit/MySQLRule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private void initServer() throws IOException {
8888
server.withClasspathResourceMapping("tls/files", "/etc/mysql/tls", BindMode.READ_ONLY);
8989
} else {
9090
server.withClasspathResourceMapping("tls/files", "/etc/mysql/tls", BindMode.READ_ONLY);
91-
String cmd = "--max_allowed_packet=33554432 --max_prepared_stmt_count=1024 --local_infile=true --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci";
91+
String cmd = "--disable-ssl --max_allowed_packet=33554432 --max_prepared_stmt_count=1024 --local_infile=true --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci";
9292
if (isUsingMySQL8()) {
9393
// introduced in MySQL 8.0.3
9494
cmd += " --caching-sha2-password-public-key-path=/etc/mysql/tls/public_key.pem --caching-sha2-password-private-key-path=/etc/mysql/tls/private_key.pem";

0 commit comments

Comments
 (0)