diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java index 334a8eab..5518bf26 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java @@ -14,6 +14,13 @@ public class LegacyDecoder extends ByteToMessageDecoder @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + // See check in Varint21FrameDecoder for more details + if ( !ctx.channel().isActive() ) + { + in.skipBytes( in.readableBytes() ); + return; + } + if ( !in.isReadable() ) { return; diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java index ea44573d..d36b7f3c 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java @@ -20,6 +20,13 @@ public class MinecraftDecoder extends MessageToMessageDecoder @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + // See Varint21FrameDecoder for the general reasoning. We add this here as ByteToMessageDecoder#handlerRemoved() + // will fire any cumulated data through the pipeline, so we want to try and stop it here. + if ( !ctx.channel().isActive() ) + { + return; + } + Protocol.DirectionData prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT; ByteBuf slice = in.copy(); // Can't slice this one due to EntityMap :( diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java index e903fd09..647394ba 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java @@ -15,6 +15,16 @@ public class Varint21FrameDecoder extends ByteToMessageDecoder @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + // If we decode an invalid packet and an exception is thrown (thus triggering a close of the connection), + // the Netty ByteToMessageDecoder will continue to frame more packets and potentially call fireChannelRead() + // on them, likely with more invalid packets. Therefore, check if the connection is no longer active and if so + // sliently discard the packet. + if ( !ctx.channel().isActive() ) + { + in.skipBytes( in.readableBytes() ); + return; + } + in.markReaderIndex(); final byte[] buf = new byte[ 3 ];