diff --git a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java index 6967d4fcd2..b26669bec6 100644 --- a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java @@ -69,6 +69,7 @@ public class Configuration implements ProxyConfig private boolean preventProxyConnections; private boolean forgeSupport; private boolean rejectTransfers; + private int maxPacketsPerSecond = 2000; public void load() { @@ -105,6 +106,7 @@ public void load() preventProxyConnections = adapter.getBoolean( "prevent_proxy_connections", preventProxyConnections ); forgeSupport = adapter.getBoolean( "forge_support", forgeSupport ); rejectTransfers = adapter.getBoolean( "reject_transfers", rejectTransfers ); + maxPacketsPerSecond = adapter.getInt( "max_packets_per_second", maxPacketsPerSecond ); disabledCommands = new CaseInsensitiveSet( (Collection) adapter.getList( "disabled_commands", Arrays.asList( "disabledcommandhere" ) ) ); diff --git a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java index d82173b1ea..30b157d5c8 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.util.logging.Level; +import lombok.Setter; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.connection.CancelSendSignal; import net.md_5.bungee.connection.InitialHandler; @@ -18,6 +19,7 @@ import net.md_5.bungee.protocol.OverflowPacketException; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.util.PacketLimiter; import net.md_5.bungee.util.QuietException; /** @@ -28,6 +30,8 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter { + @Setter + private PacketLimiter limiter; private ChannelWrapper channel; private PacketHandler handler; private boolean healthCheck; @@ -80,6 +84,11 @@ public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exceptio @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if ( limiter != null ) + { + limiter.received(); + } + if ( msg instanceof HAProxyMessage ) { HAProxyMessage proxy = (HAProxyMessage) msg; diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java index 25f045bebe..af79c50028 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java @@ -51,6 +51,7 @@ import net.md_5.bungee.protocol.Varint21FrameDecoder; import net.md_5.bungee.protocol.Varint21LengthFieldExtraBufPrepender; import net.md_5.bungee.protocol.Varint21LengthFieldPrepender; +import net.md_5.bungee.util.PacketLimiter; public class PipelineUtils { @@ -82,7 +83,14 @@ protected void initChannel(Channel ch) throws Exception ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) ); ch.pipeline().addAfter( FRAME_PREPENDER, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) ); ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, legacyKicker ); - ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), listener ) ); + + HandlerBoss handlerBoss = ch.pipeline().get( HandlerBoss.class ); + handlerBoss.setHandler( new InitialHandler( BungeeCord.getInstance(), listener ) ); + int packetLimit = BungeeCord.getInstance().getConfig().getMaxPacketsPerSecond(); + if ( packetLimit > 0 ) + { + handlerBoss.setLimiter( new PacketLimiter( packetLimit ) ); + } if ( listener.isProxyProtocol() ) { diff --git a/proxy/src/main/java/net/md_5/bungee/util/PacketLimiter.java b/proxy/src/main/java/net/md_5/bungee/util/PacketLimiter.java new file mode 100644 index 0000000000..7440a2b508 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/util/PacketLimiter.java @@ -0,0 +1,26 @@ +package net.md_5.bungee.util; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class PacketLimiter +{ + // max amount of packets allowed per second + private final int limit; + private int counter; + private long nextSecond; + + public void received() + { + if ( ++counter == limit ) + { + long now = System.currentTimeMillis(); + if ( nextSecond > now ) + { + throw new QuietException( "exceeded packet limit" ); + } + nextSecond = now + 1000; + counter = 0; + } + } +}