Skip to content

Commit

Permalink
Merge pull request #14 from SpigotMC/master
Browse files Browse the repository at this point in the history
[pull] master from SpigotMC:master
  • Loading branch information
pull[bot] authored Feb 15, 2025
2 parents e4bdfa1 + 556a15a commit 1f21a48
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 13 deletions.
4 changes: 4 additions & 0 deletions proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public class Configuration implements ProxyConfig
private boolean preventProxyConnections;
private boolean forgeSupport;
private boolean rejectTransfers;
private int maxPacketsPerSecond = 1 << 12;
private int maxPacketDataPerSecond = 1 << 25;

public void load()
{
Expand Down Expand Up @@ -105,6 +107,8 @@ 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 );
maxPacketDataPerSecond = adapter.getInt( "max_packets_data_per_second", maxPacketDataPerSecond );

disabledCommands = new CaseInsensitiveSet( (Collection<String>) adapter.getList( "disabled_commands", Arrays.asList( "disabledcommandhere" ) ) );

Expand Down
46 changes: 34 additions & 12 deletions proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@
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.api.chat.TextComponent;
import net.md_5.bungee.connection.CancelSendSignal;
import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.connection.PingHandler;
import net.md_5.bungee.connection.UpstreamBridge;
import net.md_5.bungee.protocol.BadPacketException;
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.protocol.packet.Kick;
import net.md_5.bungee.util.PacketLimiter;
import net.md_5.bungee.util.QuietException;

/**
Expand All @@ -28,6 +33,8 @@
public class HandlerBoss extends ChannelInboundHandlerAdapter
{

@Setter
private PacketLimiter limiter;
private ChannelWrapper channel;
private PacketHandler handler;
private boolean healthCheck;
Expand Down Expand Up @@ -107,20 +114,35 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
}

PacketWrapper packet = (PacketWrapper) msg;
if ( packet.packet != null )

try
{
Protocol nextProtocol = packet.packet.nextProtocol();
if ( nextProtocol != null )
// check if the player exceeds packet limits, put inside try final, so we always release.
if ( limiter != null && !limiter.incrementAndCheck( packet.buf.readableBytes() ) )
{
channel.setDecodeProtocol( nextProtocol );
// we shouldn't tell the player what limits he exceeds by default
// but if someone applies custom message we should allow them to display counter and bytes
channel.close( handler instanceof UpstreamBridge ? new Kick( TextComponent.fromLegacy( ProxyServer.getInstance().getTranslation( "packet_limit_kick", limiter.getCounter(), limiter.getDataCounter() ) ) ) : null );
// but the server admin should know
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} exceeded packet limit ({1} packets and {2} bytes per second)", new Object[]
{
handler, limiter.getCounter(), limiter.getDataCounter()
} );
return;
}
}

if ( handler != null )
{
boolean sendPacket = handler.shouldHandle( packet );
try
if ( packet.packet != null )
{
Protocol nextProtocol = packet.packet.nextProtocol();
if ( nextProtocol != null )
{
channel.setDecodeProtocol( nextProtocol );
}
}

if ( handler != null )
{
boolean sendPacket = handler.shouldHandle( packet );
if ( sendPacket && packet.packet != null )
{
try
Expand All @@ -135,10 +157,10 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
{
handler.handle( packet );
}
} finally
{
packet.trySingleRelease();
}
} finally
{
packet.trySingleRelease();
}
}

Expand Down
11 changes: 10 additions & 1 deletion proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import net.md_5.bungee.protocol.Varint21FrameDecoder;
import net.md_5.bungee.protocol.channel.BungeeChannelInitializer;
import net.md_5.bungee.protocol.channel.ChannelAcceptor;
import net.md_5.bungee.util.PacketLimiter;

public class PipelineUtils
{
Expand Down Expand Up @@ -79,8 +80,16 @@ private static void setChannelInitializerHolders()
ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
ch.pipeline().addAfter( FRAME_PREPENDER_AND_COMPRESS, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
ch.pipeline().addBefore( FRAME_PREPENDER_AND_COMPRESS, 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();
int packetDataLimit = BungeeCord.getInstance().getConfig().getMaxPacketDataPerSecond();
if ( packetLimit > 0 || packetDataLimit > 0 )
{
handlerBoss.setLimiter( new PacketLimiter( packetLimit, packetDataLimit ) );
}
if ( listener.isProxyProtocol() )
{
ch.pipeline().addFirst( new HAProxyMessageDecoder() );
Expand Down
45 changes: 45 additions & 0 deletions proxy/src/main/java/net/md_5/bungee/util/PacketLimiter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.md_5.bungee.util;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class PacketLimiter
{

// max amount of packets allowed per second
private final int limit;
// max amount of data allowed per second
private final int dataLimit;

@Getter
private int counter;
@Getter
private int dataCounter;
private long nextSecond;

/**
* Counts the received packet amount and size.
*
* @param size size of the packet
* @return return false if the player should be kicked
*/
public boolean incrementAndCheck(int size)
{
counter++;
dataCounter += size;

if ( ( limit > 0 && counter > limit ) || ( dataLimit > 0 && dataCounter > dataLimit ) )
{
long now = System.currentTimeMillis();
if ( nextSecond > now )
{
return false;
}
nextSecond = now + 1000;
counter = 0;
dataCounter = 0;
}
return true;
}
}
1 change: 1 addition & 0 deletions proxy/src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ command_ip=\u00a79IP of {0} is {1}
illegal_chat_characters=\u00a7cIllegal characters in chat ({0})
kick_message=\u00a7cYou have been kicked off the proxy.
reject_transfer=\u00a7cYour transfer was rejected.
packet_limit_kick=\u00a7cYou have sent too many packets

0 comments on commit 1f21a48

Please sign in to comment.