Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable buffer pooling settings with a SSL configurable option #5316

Open
wants to merge 1 commit into
base: 4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/main/java/io/vertx/core/net/JdkSSLEngineOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,31 @@ public static synchronized boolean isAlpnAvailable() {
return jdkAlpnAvailable;
}

private boolean pooledHeapBuffers = false;

public JdkSSLEngineOptions() {
}

public JdkSSLEngineOptions(JsonObject json) {
super(json);
pooledHeapBuffers = json.getBoolean("pooledHeapBuffers", false);
}

public JdkSSLEngineOptions(JdkSSLEngineOptions that) {
super(that);
pooledHeapBuffers = that.pooledHeapBuffers;
}

/**
* Set whether to use pooled heap buffers. Default is {@code false}, but it is recommended to use pooled buffers
*/
public JdkSSLEngineOptions setPooledHeapBuffers(boolean pooledHeapBuffers) {
this.pooledHeapBuffers = pooledHeapBuffers;
return this;
}

public boolean isPooledHeapBuffers() {
return pooledHeapBuffers;
}

@Override
Expand All @@ -72,7 +88,9 @@ public JdkSSLEngineOptions setUseWorkerThread(boolean useWorkerThread) {
}

public JsonObject toJson() {
return new JsonObject();
JsonObject jsonObject = new JsonObject();
jsonObject.put("pooledHeapBuffers", pooledHeapBuffers);
return jsonObject;
}

@Override
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/io/vertx/core/net/impl/NetClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.buffer.impl.PartialPooledByteBufAllocator;
import io.vertx.core.impl.CloseFuture;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.impl.VertxInternal;
Expand All @@ -49,7 +48,6 @@
import java.net.ConnectException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;

/**
Expand Down Expand Up @@ -297,7 +295,8 @@ private void connectInternal2(ProxyOptions proxyOptions,
Objects.requireNonNull(connectHandler, "No null connectHandler accepted");
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoop);
bootstrap.option(ChannelOption.ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE);
bootstrap.option(ChannelOption.ALLOCATOR,
sslHelper.clientByteBufAllocator(sslChannelProvider.sslContextProvider()));

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

Expand Down
42 changes: 39 additions & 3 deletions src/main/java/io/vertx/core/net/impl/SSLHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@

package io.vertx.core.net.impl;

import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslProvider;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.VertxException;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.buffer.impl.PartialPooledByteBufAllocator;
import io.vertx.core.http.ClientAuth;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.net.ClientOptionsBase;
Expand Down Expand Up @@ -57,6 +60,27 @@ public class SSLHelper {
CLIENT_AUTH_MAPPING.put(ClientAuth.NONE, io.netty.handler.ssl.ClientAuth.NONE);
}

ByteBufAllocator clientByteBufAllocator(SslContextProvider ctxProvider) {
if (usesJDKSSLWithPooledHeapBuffers(ctxProvider)) {
return PooledByteBufAllocator.DEFAULT;
}
return PartialPooledByteBufAllocator.INSTANCE;
}

ByteBufAllocator serverByteBufAllocator(SslContextProvider ctxProvider) {
if (!ssl || usesJDKSSLWithPooledHeapBuffers(ctxProvider)) {
return PooledByteBufAllocator.DEFAULT;
}
return PartialPooledByteBufAllocator.INSTANCE;
}

private boolean usesJDKSSLWithPooledHeapBuffers(SslContextProvider ctxProvider) {
return ssl && sslEngineOptions instanceof JdkSSLEngineOptions &&
ctxProvider.sslProvider() == SslProvider.JDK &&
((JdkSSLEngineOptions) sslEngineOptions).isPooledHeapBuffers();
}


/**
* Resolve the ssl engine options to use for properly running the configured options.
*/
Expand Down Expand Up @@ -149,18 +173,22 @@ private static class CachedProvider {

private class EngineConfig {

private final SslProvider sslProvider;
private final SSLOptions sslOptions;
private final Supplier<SslContextFactory> supplier;
private final boolean useWorkerPool;

public EngineConfig(SSLOptions sslOptions, Supplier<SslContextFactory> supplier, boolean useWorkerPool) {
public EngineConfig(SslProvider sslProvider, SSLOptions sslOptions, Supplier<SslContextFactory> supplier,
boolean useWorkerPool) {
this.sslProvider = sslProvider;
this.sslOptions = sslOptions;
this.supplier = supplier;
this.useWorkerPool = useWorkerPool;
}

SslContextProvider sslContextProvider() {
return new SslContextProvider(
sslProvider,
clientAuth,
endpointIdentificationAlgorithm,
applicationProtocols,
Expand Down Expand Up @@ -291,18 +319,26 @@ private Future<EngineConfig> build(SSLOptions sslOptions, ContextInternal ctx) {
}).compose(v2 -> ctx.<EngineConfig>executeBlockingInternal(p -> {
Supplier<SslContextFactory> supplier;
boolean useWorkerPool;
SslProvider sslProvider;
try {
SSLEngineOptions resolvedEngineOptions = resolveEngineOptions(sslEngineOptions, useAlpn);
supplier = resolvedEngineOptions::sslContextFactory;
useWorkerPool = resolvedEngineOptions.getUseWorkerThread();
if (resolvedEngineOptions instanceof JdkSSLEngineOptions) {
sslProvider = SslProvider.JDK;
} else if (resolvedEngineOptions instanceof OpenSSLEngineOptions) {
sslProvider = SslProvider.OPENSSL;
} else {
sslProvider = SslProvider.JDK;
}
} catch (Exception e) {
p.fail(e);
return;
}
p.complete(new EngineConfig(sslOptions, supplier, useWorkerPool));
p.complete(new EngineConfig(sslProvider, sslOptions, supplier, useWorkerPool));
})).onComplete(promise);
} else {
sslContextFactorySupplier = Future.succeededFuture(new EngineConfig(sslOptions, () -> new DefaultSslContextFactory(SslProvider.JDK, false), SSLEngineOptions.DEFAULT_USE_WORKER_POOL));
sslContextFactorySupplier = Future.succeededFuture(new EngineConfig(SslProvider.JDK, sslOptions, () -> new DefaultSslContextFactory(SslProvider.JDK, false), SSLEngineOptions.DEFAULT_USE_WORKER_POOL));
}
return sslContextFactorySupplier;
}
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/io/vertx/core/net/impl/SslContextProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package io.vertx.core.net.impl;

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslProvider;
import io.vertx.core.VertxException;
import io.vertx.core.http.ClientAuth;
import io.vertx.core.spi.tls.SslContextFactory;
Expand All @@ -30,6 +31,7 @@
*/
public class SslContextProvider {

private final SslProvider providerType;
private final Supplier<SslContextFactory> provider;
private final Set<String> enabledProtocols;
private final List<CRL> crls;
Expand All @@ -42,7 +44,8 @@ public class SslContextProvider {
private final Function<String, KeyManagerFactory> keyManagerFactoryMapper;
private final Function<String, TrustManager[]> trustManagerMapper;

public SslContextProvider(ClientAuth clientAuth,
public SslContextProvider(SslProvider providerType,
ClientAuth clientAuth,
String endpointIdentificationAlgorithm,
List<String> applicationProtocols,
Set<String> enabledCipherSuites,
Expand All @@ -53,6 +56,7 @@ public SslContextProvider(ClientAuth clientAuth,
Function<String, TrustManager[]> trustManagerMapper,
List<CRL> crls,
Supplier<SslContextFactory> provider) {
this.providerType = providerType;
this.provider = provider;
this.clientAuth = clientAuth;
this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
Expand All @@ -66,6 +70,10 @@ public SslContextProvider(ClientAuth clientAuth,
this.crls = crls;
}

SslProvider sslProvider() {
return providerType;
}

public VertxSslContext createContext(boolean server,
KeyManagerFactory keyManagerFactory,
TrustManager[] trustManagers,
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/io/vertx/core/net/impl/TCPServerBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,12 @@ private synchronized Future<Channel> listen(SocketAddress localAddress, ContextI
// Initialize SSL before binding
sslChannelProvider = sslHelper.updateSslContext(options.getSslOptions(), true, listenContext).onComplete(ar -> {
if (ar.succeeded()) {

// Socket bind
channelBalancer.addWorker(eventLoop, worker);
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(vertx.getAcceptorEventLoopGroup(), channelBalancer.workers());
if (options.isSsl()) {
bootstrap.childOption(ChannelOption.ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE);
} else {
bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
}
bootstrap.childOption(ChannelOption.ALLOCATOR,
sslHelper.serverByteBufAllocator(ar.result().sslChannelProvider().sslContextProvider()));

bootstrap.childHandler(channelBalancer);
applyConnectionOptions(localAddress.isDomainSocket(), bootstrap);
Expand Down
6 changes: 5 additions & 1 deletion src/test/java/io/vertx/core/net/NetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,14 @@ public void testClientOptionsJson() {
int reconnectAttempts = TestUtils.randomPositiveInt();
long reconnectInterval = TestUtils.randomPositiveInt();
boolean useAlpn = TestUtils.randomBoolean();
boolean pooledHeapBuffers = rand.nextBoolean();
String hostnameVerificationAlgorithm = TestUtils.randomAlphaString(10);
String sslEngine;
JsonObject sslEngineOptions;
if (TestUtils.randomBoolean()) {
sslEngine = "jdkSslEngineOptions";
sslEngineOptions = new JsonObject();
sslEngineOptions = new JsonObject()
.put("pooledHeapBuffers", pooledHeapBuffers);
} else {
sslEngine = "openSslEngineOptions";
boolean sessionCacheEnabled = rand.nextBoolean();
Expand Down Expand Up @@ -577,6 +579,8 @@ public void testClientOptionsJson() {
switch (sslEngine) {
case "jdkSslEngineOptions":
assertTrue(options.getSslEngineOptions() instanceof JdkSSLEngineOptions);
JdkSSLEngineOptions jdkSSLEngineOptions = (JdkSSLEngineOptions) options.getSslEngineOptions();
assertEquals(pooledHeapBuffers, jdkSSLEngineOptions.isPooledHeapBuffers());
break;
case "openSslEngineOptions":
assertTrue(options.getSslEngineOptions() instanceof OpenSSLEngineOptions);
Expand Down
Loading
Loading