Skip to content

Commit 1f21a48

Browse files
authored
Merge pull request #14 from SpigotMC/master
[pull] master from SpigotMC:master
2 parents e4bdfa1 + 556a15a commit 1f21a48

File tree

5 files changed

+94
-13
lines changed

5 files changed

+94
-13
lines changed

proxy/src/main/java/net/md_5/bungee/conf/Configuration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public class Configuration implements ProxyConfig
6969
private boolean preventProxyConnections;
7070
private boolean forgeSupport;
7171
private boolean rejectTransfers;
72+
private int maxPacketsPerSecond = 1 << 12;
73+
private int maxPacketDataPerSecond = 1 << 25;
7274

7375
public void load()
7476
{
@@ -105,6 +107,8 @@ public void load()
105107
preventProxyConnections = adapter.getBoolean( "prevent_proxy_connections", preventProxyConnections );
106108
forgeSupport = adapter.getBoolean( "forge_support", forgeSupport );
107109
rejectTransfers = adapter.getBoolean( "reject_transfers", rejectTransfers );
110+
maxPacketsPerSecond = adapter.getInt( "max_packets_per_second", maxPacketsPerSecond );
111+
maxPacketDataPerSecond = adapter.getInt( "max_packets_data_per_second", maxPacketDataPerSecond );
108112

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

proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,19 @@
1010
import java.io.IOException;
1111
import java.net.InetSocketAddress;
1212
import java.util.logging.Level;
13+
import lombok.Setter;
1314
import net.md_5.bungee.api.ProxyServer;
15+
import net.md_5.bungee.api.chat.TextComponent;
1416
import net.md_5.bungee.connection.CancelSendSignal;
1517
import net.md_5.bungee.connection.InitialHandler;
1618
import net.md_5.bungee.connection.PingHandler;
19+
import net.md_5.bungee.connection.UpstreamBridge;
1720
import net.md_5.bungee.protocol.BadPacketException;
1821
import net.md_5.bungee.protocol.OverflowPacketException;
1922
import net.md_5.bungee.protocol.PacketWrapper;
2023
import net.md_5.bungee.protocol.Protocol;
24+
import net.md_5.bungee.protocol.packet.Kick;
25+
import net.md_5.bungee.util.PacketLimiter;
2126
import net.md_5.bungee.util.QuietException;
2227

2328
/**
@@ -28,6 +33,8 @@
2833
public class HandlerBoss extends ChannelInboundHandlerAdapter
2934
{
3035

36+
@Setter
37+
private PacketLimiter limiter;
3138
private ChannelWrapper channel;
3239
private PacketHandler handler;
3340
private boolean healthCheck;
@@ -107,20 +114,35 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
107114
}
108115

109116
PacketWrapper packet = (PacketWrapper) msg;
110-
if ( packet.packet != null )
117+
118+
try
111119
{
112-
Protocol nextProtocol = packet.packet.nextProtocol();
113-
if ( nextProtocol != null )
120+
// check if the player exceeds packet limits, put inside try final, so we always release.
121+
if ( limiter != null && !limiter.incrementAndCheck( packet.buf.readableBytes() ) )
114122
{
115-
channel.setDecodeProtocol( nextProtocol );
123+
// we shouldn't tell the player what limits he exceeds by default
124+
// but if someone applies custom message we should allow them to display counter and bytes
125+
channel.close( handler instanceof UpstreamBridge ? new Kick( TextComponent.fromLegacy( ProxyServer.getInstance().getTranslation( "packet_limit_kick", limiter.getCounter(), limiter.getDataCounter() ) ) ) : null );
126+
// but the server admin should know
127+
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} exceeded packet limit ({1} packets and {2} bytes per second)", new Object[]
128+
{
129+
handler, limiter.getCounter(), limiter.getDataCounter()
130+
} );
131+
return;
116132
}
117-
}
118133

119-
if ( handler != null )
120-
{
121-
boolean sendPacket = handler.shouldHandle( packet );
122-
try
134+
if ( packet.packet != null )
123135
{
136+
Protocol nextProtocol = packet.packet.nextProtocol();
137+
if ( nextProtocol != null )
138+
{
139+
channel.setDecodeProtocol( nextProtocol );
140+
}
141+
}
142+
143+
if ( handler != null )
144+
{
145+
boolean sendPacket = handler.shouldHandle( packet );
124146
if ( sendPacket && packet.packet != null )
125147
{
126148
try
@@ -135,10 +157,10 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
135157
{
136158
handler.handle( packet );
137159
}
138-
} finally
139-
{
140-
packet.trySingleRelease();
141160
}
161+
} finally
162+
{
163+
packet.trySingleRelease();
142164
}
143165
}
144166

proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import net.md_5.bungee.protocol.Varint21FrameDecoder;
5151
import net.md_5.bungee.protocol.channel.BungeeChannelInitializer;
5252
import net.md_5.bungee.protocol.channel.ChannelAcceptor;
53+
import net.md_5.bungee.util.PacketLimiter;
5354

5455
public class PipelineUtils
5556
{
@@ -79,8 +80,16 @@ private static void setChannelInitializerHolders()
7980
ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
8081
ch.pipeline().addAfter( FRAME_PREPENDER_AND_COMPRESS, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
8182
ch.pipeline().addBefore( FRAME_PREPENDER_AND_COMPRESS, LEGACY_KICKER, legacyKicker );
82-
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), listener ) );
8383

84+
HandlerBoss handlerBoss = ch.pipeline().get( HandlerBoss.class );
85+
handlerBoss.setHandler( new InitialHandler( BungeeCord.getInstance(), listener ) );
86+
87+
int packetLimit = BungeeCord.getInstance().getConfig().getMaxPacketsPerSecond();
88+
int packetDataLimit = BungeeCord.getInstance().getConfig().getMaxPacketDataPerSecond();
89+
if ( packetLimit > 0 || packetDataLimit > 0 )
90+
{
91+
handlerBoss.setLimiter( new PacketLimiter( packetLimit, packetDataLimit ) );
92+
}
8493
if ( listener.isProxyProtocol() )
8594
{
8695
ch.pipeline().addFirst( new HAProxyMessageDecoder() );
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package net.md_5.bungee.util;
2+
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
6+
@RequiredArgsConstructor
7+
public class PacketLimiter
8+
{
9+
10+
// max amount of packets allowed per second
11+
private final int limit;
12+
// max amount of data allowed per second
13+
private final int dataLimit;
14+
15+
@Getter
16+
private int counter;
17+
@Getter
18+
private int dataCounter;
19+
private long nextSecond;
20+
21+
/**
22+
* Counts the received packet amount and size.
23+
*
24+
* @param size size of the packet
25+
* @return return false if the player should be kicked
26+
*/
27+
public boolean incrementAndCheck(int size)
28+
{
29+
counter++;
30+
dataCounter += size;
31+
32+
if ( ( limit > 0 && counter > limit ) || ( dataLimit > 0 && dataCounter > dataLimit ) )
33+
{
34+
long now = System.currentTimeMillis();
35+
if ( nextSecond > now )
36+
{
37+
return false;
38+
}
39+
nextSecond = now + 1000;
40+
counter = 0;
41+
dataCounter = 0;
42+
}
43+
return true;
44+
}
45+
}

proxy/src/main/resources/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ command_ip=\u00a79IP of {0} is {1}
4141
illegal_chat_characters=\u00a7cIllegal characters in chat ({0})
4242
kick_message=\u00a7cYou have been kicked off the proxy.
4343
reject_transfer=\u00a7cYour transfer was rejected.
44+
packet_limit_kick=\u00a7cYou have sent too many packets

0 commit comments

Comments
 (0)