diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index 2e9616e187..f1fd5d0505 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -210,14 +210,10 @@ public class SslHandler extends ByteToMessageDecoder { } @Override - int getPacketBufferSize(SslHandler handler) { - return ((ReferenceCountedOpenSslEngine) handler.engine).maxEncryptedPacketLength0(); - } - - @Override - int calculateWrapBufferCapacity(SslHandler handler, int pendingBytes, int numComponents) { - return ((ReferenceCountedOpenSslEngine) handler.engine).calculateMaxLengthForWrap(pendingBytes, - numComponents); + ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator, + int pendingBytes, int numComponents) { + return allocator.directBuffer(((ReferenceCountedOpenSslEngine) handler.engine) + .calculateMaxLengthForWrap(pendingBytes, numComponents)); } @Override @@ -259,8 +255,10 @@ public class SslHandler extends ByteToMessageDecoder { } @Override - int calculateWrapBufferCapacity(SslHandler handler, int pendingBytes, int numComponents) { - return ((ConscryptAlpnSslEngine) handler.engine).calculateOutNetBufSize(pendingBytes, numComponents); + ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator, + int pendingBytes, int numComponents) { + return allocator.directBuffer( + ((ConscryptAlpnSslEngine) handler.engine).calculateOutNetBufSize(pendingBytes, numComponents)); } @Override @@ -302,8 +300,15 @@ public class SslHandler extends ByteToMessageDecoder { } @Override - int calculateWrapBufferCapacity(SslHandler handler, int pendingBytes, int numComponents) { - return handler.engine.getSession().getPacketBufferSize(); + ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator, + int pendingBytes, int numComponents) { + // As for the JDK SSLEngine we always need to allocate buffers of the size required by the SSLEngine + // (normally ~16KB). This is required even if the amount of data to encrypt is very small. Use heap + // buffers to reduce the native memory usage. + // + // Beside this the JDK SSLEngine also (as of today) will do an extra heap to direct buffer copy + // if a direct buffer is used as its internals operate on byte[]. + return allocator.heapBuffer(handler.engine.getSession().getPacketBufferSize()); } @Override @@ -327,23 +332,21 @@ public class SslHandler extends ByteToMessageDecoder { this.cumulator = cumulator; } - int getPacketBufferSize(SslHandler handler) { - return handler.engine.getSession().getPacketBufferSize(); - } - abstract SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int readerIndex, int len, ByteBuf out) throws SSLException; - abstract int calculateWrapBufferCapacity(SslHandler handler, int pendingBytes, int numComponents); - abstract int calculatePendingData(SslHandler handler, int guess); abstract boolean jdkCompatibilityMode(SSLEngine engine); + abstract ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator, + int pendingBytes, int numComponents); + // BEGIN Platform-dependent flags /** - * {@code true} if and only if {@link SSLEngine} expects a direct buffer. + * {@code true} if and only if {@link SSLEngine} expects a direct buffer and so if a heap buffer + * is given will make an extra memory copy. */ final boolean wantsDirectBuffer; @@ -2103,7 +2106,7 @@ public class SslHandler extends ByteToMessageDecoder { * the specified amount of pending bytes. */ private ByteBuf allocateOutNetBuf(ChannelHandlerContext ctx, int pendingBytes, int numComponents) { - return allocate(ctx, engineType.calculateWrapBufferCapacity(this, pendingBytes, numComponents)); + return engineType.allocateWrapBuffer(this, ctx.alloc(), pendingBytes, numComponents); } /**