diff --git a/transport-raknet/src/main/java/org/cloudburstmc/netty/handler/codec/raknet/server/RakServerOfflineHandler.java b/transport-raknet/src/main/java/org/cloudburstmc/netty/handler/codec/raknet/server/RakServerOfflineHandler.java index 76b653a0..c4d1db3b 100644 --- a/transport-raknet/src/main/java/org/cloudburstmc/netty/handler/codec/raknet/server/RakServerOfflineHandler.java +++ b/transport-raknet/src/main/java/org/cloudburstmc/netty/handler/codec/raknet/server/RakServerOfflineHandler.java @@ -34,14 +34,17 @@ import org.cloudburstmc.netty.util.RakUtils; import java.net.Inet6Address; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import static org.cloudburstmc.netty.channel.raknet.RakConstants.*; public class RakServerOfflineHandler extends AdvancedChannelInboundHandler { public static final String NAME = "rak-offline-handler"; + private static final int MAX_PACKETS_PER_SECOND = 10; private static final InternalLogger log = InternalLoggerFactory.getInstance(RakServerOfflineHandler.class); @@ -51,6 +54,11 @@ public class RakServerOfflineHandler extends AdvancedChannelInboundHandler ReferenceCountUtil.release(value)) .build(); + private final ExpiringMap packetsCounter = ExpiringMap.builder() + .expiration(1, TimeUnit.SECONDS) + .expirationPolicy(ExpirationPolicy.CREATED) + .build(); + @Override protected boolean acceptInboundMessage(ChannelHandlerContext ctx, Object msg) throws Exception { if (!super.acceptInboundMessage(ctx, msg)) { @@ -91,6 +99,12 @@ protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) th ByteBuf magicBuf = ctx.channel().config().getOption(RakChannelOption.RAK_UNCONNECTED_MAGIC); long guid = ctx.channel().config().getOption(RakChannelOption.RAK_GUID); + AtomicInteger counter = this.packetsCounter.computeIfAbsent(packet.sender().getAddress(), s -> new AtomicInteger()); + if (counter.incrementAndGet() > MAX_PACKETS_PER_SECOND) { + log.warn("[{}] Sent too many packets per second", packet.sender()); + return; + } + switch (packetId) { case ID_UNCONNECTED_PING: this.onUnconnectedPing(ctx, packet, magicBuf, guid);