geforkt von Mirrors/Velocity
Simplify and harden Netty handlers
Dieser Commit ist enthalten in:
Ursprung
09d33de03e
Commit
8c98f5a4a6
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren