Skip to content

Commit 3923e18

Browse files
Copilotakrherz
authored andcommitted
Address Netty 4.2 migration guide items: TLS endpoint validation and NioEventLoopGroup deprecation
Co-authored-by: akrherz <210858+akrherz@users.noreply.github.com>
1 parent 0c670aa commit 3923e18

File tree

3 files changed

+14
-7
lines changed

3 files changed

+14
-7
lines changed

xmppserver/src/main/java/org/jivesoftware/openfire/nio/NettySessionInitializer.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
import io.netty.bootstrap.Bootstrap;
2020
import io.netty.channel.*;
21-
import io.netty.channel.nio.NioEventLoopGroup;
21+
import io.netty.channel.MultiThreadIoEventLoopGroup;
22+
import io.netty.channel.nio.NioIoHandler;
2223
import io.netty.channel.socket.SocketChannel;
2324
import io.netty.channel.socket.nio.NioSocketChannel;
2425
import io.netty.handler.codec.string.StringEncoder;
@@ -132,7 +133,7 @@ public static void initializeSharedResources()
132133
}
133134
Log.debug("Initialising shared Netty resources for outbound S2S.");
134135
final ThreadFactory ioFactory = new NamedThreadFactory("socket_s2s_outbound-worker-", null, false, Thread.NORM_PRIORITY);
135-
ioWorkerGroup = new NioEventLoopGroup(ioFactory);
136+
ioWorkerGroup = new MultiThreadIoEventLoopGroup(ioFactory, NioIoHandler.newFactory());
136137

137138
final int handlerThreads = Math.max(1, Runtime.getRuntime().availableProcessors()) * 2;
138139
final ThreadFactory handlerFactory = new NamedThreadFactory("socket_s2s_outbound-handler-", null, false, Thread.NORM_PRIORITY);
@@ -310,7 +311,7 @@ public boolean exceptionOccurredForDirectTLS(Throwable cause) {
310311

311312
this.channel = b.connect(socketAddress).sync().channel();
312313

313-
// Make sure we free up resources (worker group NioEventLoopGroup) when the channel is closed
314+
// Make sure we free up resources (worker group MultiThreadIoEventLoopGroup) when the channel is closed
314315
this.channel.closeFuture().addListener(future -> stop());
315316

316317
// When using directTLS a Netty SSLHandler is added to the pipeline from instantiation. This initiates the TLS handshake, and as such we do not need to send an opening stream element.

xmppserver/src/main/java/org/jivesoftware/openfire/spi/EncryptionArtifactFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,13 +417,18 @@ public SslContext createClientModeSslContext() throws SSLException, Unrecoverabl
417417
// createClientModeSslContext is only used when the Openfire server is acting as a client when
418418
// making outbound S2S connections so the first stanza we send should be encrypted hence startTls(false)
419419

420+
// Netty 4.2 changed the default for endpointIdentificationAlgorithm from null (disabled) to "HTTPS".
421+
// XMPP S2S certificate validation is handled by Openfire's own trust manager (getTrustManagers()), which
422+
// applies XMPP-specific rules (RFC 6120). Enabling Netty's HTTPS hostname verification on top would be
423+
// redundant and could reject valid XMPP servers whose certificates do not conform to HTTPS naming conventions.
420424
return SslContextBuilder
421425
.forClient()
422426
.protocols(protocols)
423427
.ciphers(configuration.getEncryptionCipherSuites())
424428
.keyManager(getKeyManagerFactory())
425429
.trustManager(getTrustManagers()[0]) // The existing implementation never returns more than one trust manager.
426430
.startTls(false) // Acting as client making outbound S2S connection so encrypt next stanza
431+
.endpointIdentificationAlgorithm(null) // Disable Netty's built-in hostname verification; Openfire's trust manager handles XMPP certificate validation.
427432
.build();
428433
}
429434

xmppserver/src/main/java/org/jivesoftware/openfire/spi/NettyConnectionAcceptor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
import io.netty.channel.ChannelHandler;
2222
import io.netty.channel.ChannelOption;
2323
import io.netty.channel.EventLoopGroup;
24+
import io.netty.channel.MultiThreadIoEventLoopGroup;
2425
import io.netty.channel.group.ChannelGroup;
2526
import io.netty.channel.group.DefaultChannelGroup;
26-
import io.netty.channel.nio.NioEventLoopGroup;
27+
import io.netty.channel.nio.NioIoHandler;
2728
import io.netty.channel.socket.nio.NioServerSocketChannel;
2829
import io.netty.util.concurrent.DefaultEventExecutorGroup;
2930
import io.netty.util.concurrent.EventExecutorGroup;
@@ -133,7 +134,7 @@ public class NettyConnectionAcceptor extends ConnectionAcceptor {
133134
.setMaxValue(Duration.ofSeconds(Integer.MAX_VALUE))
134135
.build();
135136

136-
// NioEventLoopGroup is a multithreaded event loop that handles I/O operation.
137+
// MultiThreadIoEventLoopGroup is a multithreaded event loop that handles I/O operation.
137138
// The first one, often called 'boss', accepts an incoming connection.
138139
// The second one, often called 'worker', handles the traffic of the accepted connection once the boss
139140
// accepts the connection and registers the accepted connection to the worker. How many Threads are
@@ -194,10 +195,10 @@ public NettyConnectionAcceptor(ConnectionConfiguration configuration) {
194195

195196
// The configuration of threads is based on defaults used by io.netty.util.concurrent.DefaultThreadFactory (OF-3028)
196197
final ThreadFactory acceptorGroupThreadFactory = new NamedThreadFactory(name + "-acceptor-", null, false, Thread.NORM_PRIORITY);
197-
acceptorGroup = new NioEventLoopGroup(acceptorGroupThreadFactory);
198+
acceptorGroup = new MultiThreadIoEventLoopGroup(acceptorGroupThreadFactory, NioIoHandler.newFactory());
198199

199200
final ThreadFactory ioWorkerGroupThreadFactory = new NamedThreadFactory(name + "-worker-", null, false, Thread.NORM_PRIORITY);
200-
ioWorkerGroup = new NioEventLoopGroup(ioWorkerGroupThreadFactory);
201+
ioWorkerGroup = new MultiThreadIoEventLoopGroup(ioWorkerGroupThreadFactory, NioIoHandler.newFactory());
201202

202203
final ThreadFactory blockingHandlerGroupThreadFactory = new NamedThreadFactory(name + "-handler-", null, false, Thread.NORM_PRIORITY);
203204
blockingHandlerExecutor = new DefaultEventExecutorGroup(configuration.getMaxThreadPoolSize(), blockingHandlerGroupThreadFactory);

0 commit comments

Comments
 (0)