From 674e1079dde7ce4a1aaaf5707aad54fa285efc6d Mon Sep 17 00:00:00 2001 From: themode Date: Fri, 13 Nov 2020 01:34:25 +0100 Subject: [PATCH] Added max packet size condition --- .../net/minestom/server/MinecraftServer.java | 27 +++++++++++--- .../server/network/netty/NettyServer.java | 5 +-- .../network/netty/codec/PacketFramer.java | 35 +++++++++++++++++-- .../network/netty/packet/InboundPacket.java | 3 +- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index e83cc9559..22b3ebd28 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -107,15 +107,14 @@ public final class MinecraftServer { @Setter private static boolean hardcoreLook = false; - //Extras + // Extras @Getter @Setter private static boolean fixLighting = true; - //Rate Limiting + // Rate Limiting private static int rateLimit = 0; - // TODO - public static final int MAX_PACKET_SIZE = 300_000; + private static int maxPacketSize = 30_000; private static PacketListenerManager packetListenerManager; private static NettyServer nettyServer; @@ -250,7 +249,7 @@ public final class MinecraftServer { /** * Gets the max number of packets a client can send over 1 second. * - * @return the packet count limit over 1 second + * @return the packet count limit over 1 second, 0 if not enabled */ public static int getRateLimit() { return rateLimit; @@ -265,6 +264,24 @@ public final class MinecraftServer { MinecraftServer.rateLimit = rateLimit; } + /** + * Gets the maximum packet size (in bytes) that a client can send without getting disconnected. + * + * @return the maximum packet size + */ + public static int getMaxPacketSize() { + return maxPacketSize; + } + + /** + * Changes the maximum packet size (in bytes) that a client can send without getting disconnected. + * + * @param maxPacketSize the new max packet size + */ + public static void setMaxPacketSize(int maxPacketSize) { + MinecraftServer.maxPacketSize = maxPacketSize; + } + /** * Gets the server difficulty showed in game option. * diff --git a/src/main/java/net/minestom/server/network/netty/NettyServer.java b/src/main/java/net/minestom/server/network/netty/NettyServer.java index c6654195b..5bd2fbfbf 100644 --- a/src/main/java/net/minestom/server/network/netty/NettyServer.java +++ b/src/main/java/net/minestom/server/network/netty/NettyServer.java @@ -29,7 +29,7 @@ public class NettyServer { private String address; private int port; - public NettyServer(PacketProcessor packetProcessor) { + public NettyServer(@NotNull PacketProcessor packetProcessor) { Class channel; if (Epoll.isAvailable()) { @@ -55,10 +55,11 @@ public class NettyServer { ChannelPipeline pipeline = ch.pipeline(); + // First check should verify if the packet is a legacy ping (from 1.6 version and earlier) pipeline.addLast("legacy-ping", new LegacyPingHandler()); // Adds packetLength at start | Reads framed bytebuf - pipeline.addLast("framer", new PacketFramer()); + pipeline.addLast("framer", new PacketFramer(packetProcessor)); // Reads bytebuf and creating inbound packet pipeline.addLast("decoder", new PacketDecoder()); diff --git a/src/main/java/net/minestom/server/network/netty/codec/PacketFramer.java b/src/main/java/net/minestom/server/network/netty/codec/PacketFramer.java index 8da30a9dc..f78c65942 100644 --- a/src/main/java/net/minestom/server/network/netty/codec/PacketFramer.java +++ b/src/main/java/net/minestom/server/network/netty/codec/PacketFramer.java @@ -4,12 +4,26 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageCodec; import io.netty.handler.codec.CorruptedFrameException; +import net.minestom.server.MinecraftServer; +import net.minestom.server.entity.Player; +import net.minestom.server.network.PacketProcessor; +import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; public class PacketFramer extends ByteToMessageCodec { + public final static Logger LOGGER = LoggerFactory.getLogger(PacketFramer.class); + + private final PacketProcessor packetProcessor; + + public PacketFramer(PacketProcessor packetProcessor) { + this.packetProcessor = packetProcessor; + } + @Override protected void encode(ChannelHandlerContext ctx, ByteBuf from, ByteBuf to) { final int packetSize = from.readableBytes(); @@ -40,14 +54,29 @@ public class PacketFramer extends ByteToMessageCodec { if (b >= 0) { buf.resetReaderIndex(); - final int j = Utils.readVarInt(buf); + final int packetSize = Utils.readVarInt(buf); - if (buf.readableBytes() < j) { + // Max packet size check + if (packetSize >= MinecraftServer.getMaxPacketSize()) { + final PlayerConnection playerConnection = packetProcessor.getPlayerConnection(ctx); + if (playerConnection != null) { + final Player player = playerConnection.getPlayer(); + final String identifier = player != null ? + player.getUsername() : + playerConnection.getRemoteAddress().toString(); + LOGGER.warn("An user (" + identifier + ") sent a packet over the maximum size (" + packetSize + ")"); + } else { + LOGGER.warn("An unregistered user sent a packet over the maximum size (" + packetSize + ")"); + } + ctx.close(); + } + + if (buf.readableBytes() < packetSize) { buf.resetReaderIndex(); return; } - out.add(buf.readRetainedSlice(j)); + out.add(buf.readRetainedSlice(packetSize)); return; } } diff --git a/src/main/java/net/minestom/server/network/netty/packet/InboundPacket.java b/src/main/java/net/minestom/server/network/netty/packet/InboundPacket.java index e42cc07c2..a8d184396 100644 --- a/src/main/java/net/minestom/server/network/netty/packet/InboundPacket.java +++ b/src/main/java/net/minestom/server/network/netty/packet/InboundPacket.java @@ -1,13 +1,14 @@ package net.minestom.server.network.netty.packet; import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; public class InboundPacket { public final int packetId; public final ByteBuf body; - public InboundPacket(int id, ByteBuf body) { + public InboundPacket(int id, @NotNull ByteBuf body) { this.packetId = id; this.body = body; }