Skip to content

Commit ccca2b8

Browse files
authored
Merge pull request #5316 from franz1981/4.x_unified_allocator_fix_ssl
Enable buffer pooling settings with a SSL configurable option
2 parents a7c2ba5 + a3393ac commit ccca2b8

File tree

8 files changed

+554
-15
lines changed

8 files changed

+554
-15
lines changed

src/main/java/io/vertx/core/net/JdkSSLEngineOptions.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,31 @@ public static synchronized boolean isAlpnAvailable() {
5555
return jdkAlpnAvailable;
5656
}
5757

58+
private boolean pooledHeapBuffers = false;
59+
5860
public JdkSSLEngineOptions() {
5961
}
6062

6163
public JdkSSLEngineOptions(JsonObject json) {
6264
super(json);
65+
pooledHeapBuffers = json.getBoolean("pooledHeapBuffers", false);
6366
}
6467

6568
public JdkSSLEngineOptions(JdkSSLEngineOptions that) {
6669
super(that);
70+
pooledHeapBuffers = that.pooledHeapBuffers;
71+
}
72+
73+
/**
74+
* Set whether to use pooled heap buffers. Default is {@code false}, but it is recommended to use pooled buffers
75+
*/
76+
public JdkSSLEngineOptions setPooledHeapBuffers(boolean pooledHeapBuffers) {
77+
this.pooledHeapBuffers = pooledHeapBuffers;
78+
return this;
79+
}
80+
81+
public boolean isPooledHeapBuffers() {
82+
return pooledHeapBuffers;
6783
}
6884

6985
@Override
@@ -72,7 +88,9 @@ public JdkSSLEngineOptions setUseWorkerThread(boolean useWorkerThread) {
7288
}
7389

7490
public JsonObject toJson() {
75-
return new JsonObject();
91+
JsonObject jsonObject = new JsonObject();
92+
jsonObject.put("pooledHeapBuffers", pooledHeapBuffers);
93+
return jsonObject;
7694
}
7795

7896
@Override

src/main/java/io/vertx/core/net/impl/NetClientImpl.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import io.vertx.core.Future;
2929
import io.vertx.core.Handler;
3030
import io.vertx.core.Promise;
31-
import io.vertx.core.buffer.impl.PartialPooledByteBufAllocator;
3231
import io.vertx.core.impl.CloseFuture;
3332
import io.vertx.core.impl.ContextInternal;
3433
import io.vertx.core.impl.VertxInternal;
@@ -49,7 +48,6 @@
4948
import java.net.ConnectException;
5049
import java.util.Objects;
5150
import java.util.concurrent.TimeUnit;
52-
import java.util.concurrent.atomic.AtomicReference;
5351
import java.util.function.Predicate;
5452

5553
/**
@@ -297,7 +295,8 @@ private void connectInternal2(ProxyOptions proxyOptions,
297295
Objects.requireNonNull(connectHandler, "No null connectHandler accepted");
298296
Bootstrap bootstrap = new Bootstrap();
299297
bootstrap.group(eventLoop);
300-
bootstrap.option(ChannelOption.ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE);
298+
bootstrap.option(ChannelOption.ALLOCATOR,
299+
sslHelper.clientByteBufAllocator(sslChannelProvider.sslContextProvider()));
301300

302301
vertx.transport().configure(options, remoteAddress.isDomainSocket(), bootstrap);
303302

src/main/java/io/vertx/core/net/impl/SSLHelper.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111

1212
package io.vertx.core.net.impl;
1313

14+
import io.netty.buffer.ByteBufAllocator;
15+
import io.netty.buffer.PooledByteBufAllocator;
1416
import io.netty.handler.ssl.OpenSsl;
1517
import io.netty.handler.ssl.SslProvider;
1618
import io.vertx.core.Future;
1719
import io.vertx.core.Promise;
1820
import io.vertx.core.VertxException;
1921
import io.vertx.core.buffer.Buffer;
22+
import io.vertx.core.buffer.impl.PartialPooledByteBufAllocator;
2023
import io.vertx.core.http.ClientAuth;
2124
import io.vertx.core.impl.ContextInternal;
2225
import io.vertx.core.net.ClientOptionsBase;
@@ -57,6 +60,27 @@ public class SSLHelper {
5760
CLIENT_AUTH_MAPPING.put(ClientAuth.NONE, io.netty.handler.ssl.ClientAuth.NONE);
5861
}
5962

63+
ByteBufAllocator clientByteBufAllocator(SslContextProvider ctxProvider) {
64+
if (usesJDKSSLWithPooledHeapBuffers(ctxProvider)) {
65+
return PooledByteBufAllocator.DEFAULT;
66+
}
67+
return PartialPooledByteBufAllocator.INSTANCE;
68+
}
69+
70+
ByteBufAllocator serverByteBufAllocator(SslContextProvider ctxProvider) {
71+
if (!ssl || usesJDKSSLWithPooledHeapBuffers(ctxProvider)) {
72+
return PooledByteBufAllocator.DEFAULT;
73+
}
74+
return PartialPooledByteBufAllocator.INSTANCE;
75+
}
76+
77+
private boolean usesJDKSSLWithPooledHeapBuffers(SslContextProvider ctxProvider) {
78+
return ssl && sslEngineOptions instanceof JdkSSLEngineOptions &&
79+
ctxProvider.jdkSSLProvider() &&
80+
((JdkSSLEngineOptions) sslEngineOptions).isPooledHeapBuffers();
81+
}
82+
83+
6084
/**
6185
* Resolve the ssl engine options to use for properly running the configured options.
6286
*/
@@ -149,18 +173,22 @@ private static class CachedProvider {
149173

150174
private class EngineConfig {
151175

176+
private final boolean jdkSSLProvider;
152177
private final SSLOptions sslOptions;
153178
private final Supplier<SslContextFactory> supplier;
154179
private final boolean useWorkerPool;
155180

156-
public EngineConfig(SSLOptions sslOptions, Supplier<SslContextFactory> supplier, boolean useWorkerPool) {
181+
public EngineConfig(boolean jdkSSLProvider, SSLOptions sslOptions, Supplier<SslContextFactory> supplier,
182+
boolean useWorkerPool) {
183+
this.jdkSSLProvider = jdkSSLProvider;
157184
this.sslOptions = sslOptions;
158185
this.supplier = supplier;
159186
this.useWorkerPool = useWorkerPool;
160187
}
161188

162189
SslContextProvider sslContextProvider() {
163190
return new SslContextProvider(
191+
jdkSSLProvider,
164192
clientAuth,
165193
endpointIdentificationAlgorithm,
166194
applicationProtocols,
@@ -291,18 +319,20 @@ private Future<EngineConfig> build(SSLOptions sslOptions, ContextInternal ctx) {
291319
}).compose(v2 -> ctx.<EngineConfig>executeBlockingInternal(p -> {
292320
Supplier<SslContextFactory> supplier;
293321
boolean useWorkerPool;
322+
final boolean jdkSSLProvider;
294323
try {
295324
SSLEngineOptions resolvedEngineOptions = resolveEngineOptions(sslEngineOptions, useAlpn);
296325
supplier = resolvedEngineOptions::sslContextFactory;
297326
useWorkerPool = resolvedEngineOptions.getUseWorkerThread();
327+
jdkSSLProvider = resolvedEngineOptions instanceof JdkSSLEngineOptions;
298328
} catch (Exception e) {
299329
p.fail(e);
300330
return;
301331
}
302-
p.complete(new EngineConfig(sslOptions, supplier, useWorkerPool));
332+
p.complete(new EngineConfig(jdkSSLProvider, sslOptions, supplier, useWorkerPool));
303333
})).onComplete(promise);
304334
} else {
305-
sslContextFactorySupplier = Future.succeededFuture(new EngineConfig(sslOptions, () -> new DefaultSslContextFactory(SslProvider.JDK, false), SSLEngineOptions.DEFAULT_USE_WORKER_POOL));
335+
sslContextFactorySupplier = Future.succeededFuture(new EngineConfig(true, sslOptions, () -> new DefaultSslContextFactory(SslProvider.JDK, false), SSLEngineOptions.DEFAULT_USE_WORKER_POOL));
306336
}
307337
return sslContextFactorySupplier;
308338
}

src/main/java/io/vertx/core/net/impl/SslContextProvider.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
*/
3131
public class SslContextProvider {
3232

33+
private final boolean jdkSSLProvider;
3334
private final Supplier<SslContextFactory> provider;
3435
private final Set<String> enabledProtocols;
3536
private final List<CRL> crls;
@@ -42,7 +43,8 @@ public class SslContextProvider {
4243
private final Function<String, KeyManagerFactory> keyManagerFactoryMapper;
4344
private final Function<String, TrustManager[]> trustManagerMapper;
4445

45-
public SslContextProvider(ClientAuth clientAuth,
46+
public SslContextProvider(boolean jdkSSLProvider,
47+
ClientAuth clientAuth,
4648
String endpointIdentificationAlgorithm,
4749
List<String> applicationProtocols,
4850
Set<String> enabledCipherSuites,
@@ -53,6 +55,7 @@ public SslContextProvider(ClientAuth clientAuth,
5355
Function<String, TrustManager[]> trustManagerMapper,
5456
List<CRL> crls,
5557
Supplier<SslContextFactory> provider) {
58+
this.jdkSSLProvider = jdkSSLProvider;
5659
this.provider = provider;
5760
this.clientAuth = clientAuth;
5861
this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
@@ -66,6 +69,10 @@ public SslContextProvider(ClientAuth clientAuth,
6669
this.crls = crls;
6770
}
6871

72+
boolean jdkSSLProvider() {
73+
return jdkSSLProvider;
74+
}
75+
6976
public VertxSslContext createContext(boolean server,
7077
KeyManagerFactory keyManagerFactory,
7178
TrustManager[] trustManagers,

src/main/java/io/vertx/core/net/impl/TCPServerBase.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,16 +237,12 @@ private synchronized Future<Channel> listen(SocketAddress localAddress, ContextI
237237
// Initialize SSL before binding
238238
sslChannelProvider = sslHelper.updateSslContext(options.getSslOptions(), true, listenContext).onComplete(ar -> {
239239
if (ar.succeeded()) {
240-
241240
// Socket bind
242241
channelBalancer.addWorker(eventLoop, worker);
243242
ServerBootstrap bootstrap = new ServerBootstrap();
244243
bootstrap.group(vertx.getAcceptorEventLoopGroup(), channelBalancer.workers());
245-
if (options.isSsl()) {
246-
bootstrap.childOption(ChannelOption.ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE);
247-
} else {
248-
bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
249-
}
244+
bootstrap.childOption(ChannelOption.ALLOCATOR,
245+
sslHelper.serverByteBufAllocator(ar.result().sslChannelProvider().sslContextProvider()));
250246

251247
bootstrap.childHandler(channelBalancer);
252248
applyConnectionOptions(localAddress.isDomainSocket(), bootstrap);

src/test/java/io/vertx/core/net/NetTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,12 +526,14 @@ public void testClientOptionsJson() {
526526
int reconnectAttempts = TestUtils.randomPositiveInt();
527527
long reconnectInterval = TestUtils.randomPositiveInt();
528528
boolean useAlpn = TestUtils.randomBoolean();
529+
boolean pooledHeapBuffers = rand.nextBoolean();
529530
String hostnameVerificationAlgorithm = TestUtils.randomAlphaString(10);
530531
String sslEngine;
531532
JsonObject sslEngineOptions;
532533
if (TestUtils.randomBoolean()) {
533534
sslEngine = "jdkSslEngineOptions";
534-
sslEngineOptions = new JsonObject();
535+
sslEngineOptions = new JsonObject()
536+
.put("pooledHeapBuffers", pooledHeapBuffers);
535537
} else {
536538
sslEngine = "openSslEngineOptions";
537539
boolean sessionCacheEnabled = rand.nextBoolean();
@@ -599,6 +601,8 @@ public void testClientOptionsJson() {
599601
switch (sslEngine) {
600602
case "jdkSslEngineOptions":
601603
assertTrue(options.getSslEngineOptions() instanceof JdkSSLEngineOptions);
604+
JdkSSLEngineOptions jdkSSLEngineOptions = (JdkSSLEngineOptions) options.getSslEngineOptions();
605+
assertEquals(pooledHeapBuffers, jdkSSLEngineOptions.isPooledHeapBuffers());
602606
break;
603607
case "openSslEngineOptions":
604608
assertTrue(options.getSslEngineOptions() instanceof OpenSSLEngineOptions);

0 commit comments

Comments
 (0)