13
0
geforkt von Mirrors/Velocity

Simplify and harden Netty handlers

Dieser Commit ist enthalten in:
Andrew Steinborn 2019-11-05 20:07:36 -05:00
Ursprung 09d33de03e
Commit 8c98f5a4a6
4 geänderte Dateien mit 24 neuen und 23 gelöschten Zeilen

Datei anzeigen

@ -5,10 +5,10 @@ import com.velocitypowered.natives.encryption.VelocityCipher;
import com.velocitypowered.natives.util.MoreByteBufUtils; import com.velocitypowered.natives.util.MoreByteBufUtils;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List; import java.util.List;
public class MinecraftCipherDecoder extends ByteToMessageDecoder { public class MinecraftCipherDecoder extends MessageToMessageDecoder<ByteBuf> {
private final VelocityCipher cipher; private final VelocityCipher cipher;
@ -30,7 +30,7 @@ public class MinecraftCipherDecoder extends ByteToMessageDecoder {
} }
@Override @Override
protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
cipher.dispose(); cipher.dispose();
} }
} }

Datei anzeigen

@ -13,7 +13,8 @@ import java.util.List;
public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> { public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> {
private static final int MAXIMUM_UNCOMPRESSED_SIZE = 2 * 1024 * 1024; // 2MiB private static final int SOFT_MAXIMUM_UNCOMPRESSED_SIZE = 2 * 1024 * 1024; // 2MiB
private static final int HARD_MAXIMUM_UNCOMPRESSED_SIZE = 16 * 1024 * 1024; // 16MiB
private final int threshold; private final int threshold;
private final VelocityCompressor compressor; private final VelocityCompressor compressor;
@ -25,21 +26,23 @@ public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
int expectedSize = ProtocolUtils.readVarInt(in); int claimedUncompressedSize = ProtocolUtils.readVarInt(in);
if (expectedSize == 0) { if (claimedUncompressedSize == 0) {
// Strip the now-useless uncompressed size, this message is already uncompressed. // Strip the now-useless uncompressed size, this message is already uncompressed.
out.add(in.retainedSlice()); out.add(in.retainedSlice());
in.skipBytes(in.readableBytes()); in.skipBytes(in.readableBytes());
return; return;
} }
checkFrame(expectedSize >= threshold, "Uncompressed size %s is less than threshold %s", checkFrame(claimedUncompressedSize >= threshold, "Uncompressed size %s is less than"
expectedSize, threshold); + " threshold %s", claimedUncompressedSize, threshold);
int initialCapacity = Math.min(expectedSize, MAXIMUM_UNCOMPRESSED_SIZE); int allowedMax = Math.min(claimedUncompressedSize, HARD_MAXIMUM_UNCOMPRESSED_SIZE);
int initialCapacity = Math.min(claimedUncompressedSize, SOFT_MAXIMUM_UNCOMPRESSED_SIZE);
ByteBuf compatibleIn = ensureCompatible(ctx.alloc(), compressor, in); ByteBuf compatibleIn = ensureCompatible(ctx.alloc(), compressor, in);
ByteBuf uncompressed = preferredBuffer(ctx.alloc(), compressor, initialCapacity); ByteBuf uncompressed = preferredBuffer(ctx.alloc(), compressor, initialCapacity);
try { try {
compressor.inflate(compatibleIn, uncompressed, expectedSize); compressor.inflate(compatibleIn, uncompressed, allowedMax);
out.add(uncompressed); out.add(uncompressed);
} catch (Exception e) { } catch (Exception e) {
uncompressed.release(); uncompressed.release();

Datei anzeigen

@ -47,20 +47,21 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
packet.decode(msg, direction, registry.version); packet.decode(msg, direction, registry.version);
} catch (Exception e) { } catch (Exception e) {
throw new CorruptedFrameException( throw new CorruptedFrameException(
"Error decoding " + packet.getClass() + " Direction " + direction "Error decoding " + packet.getClass() + " " + getExtraConnectionDetail(packetId), e);
+ " Protocol " + registry.version + " State " + state + " ID " + Integer
.toHexString(packetId), e);
} }
if (msg.isReadable()) { if (msg.isReadable()) {
throw new CorruptedFrameException( throw new CorruptedFrameException("Did not read full packet for " + packet.getClass() + " "
"Did not read full packet for " + packet.getClass() + " Direction " + direction + getExtraConnectionDetail(packetId));
+ " Protocol " + registry.version + " State " + state + " ID " + Integer
.toHexString(packetId));
} }
out.add(packet); out.add(packet);
} }
} }
private String getExtraConnectionDetail(int packetId) {
return "Direction " + direction + " Protocol " + registry.version + " State " + state
+ " ID " + Integer.toHexString(packetId);
}
public void setProtocolVersion(ProtocolVersion protocolVersion) { public void setProtocolVersion(ProtocolVersion protocolVersion) {
this.registry = direction.getProtocolRegistry(state, protocolVersion); this.registry = direction.getProtocolRegistry(state, protocolVersion);
} }

Datei anzeigen

@ -27,16 +27,13 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
// Make sure reader index of length buffer is returned to the beginning // Make sure reader index of length buffer is returned to the beginning
in.readerIndex(origReaderIndex); in.readerIndex(origReaderIndex);
int packetLength = ProtocolUtils.readVarInt(in); int packetLength = ProtocolUtils.readVarInt(in);
if (packetLength == 0) {
return;
}
if (in.readableBytes() < packetLength) { if (in.readableBytes() >= packetLength) {
out.add(in.readRetainedSlice(packetLength));
} else {
in.readerIndex(origReaderIndex); in.readerIndex(origReaderIndex);
return;
} }
out.add(in.readRetainedSlice(packetLength));
return; return;
} }
} }