summaryrefslogtreecommitdiffhomepage
path: root/patches/unapplied/server/0708-Add-packet-limiter-config.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/unapplied/server/0708-Add-packet-limiter-config.patch')
-rw-r--r--patches/unapplied/server/0708-Add-packet-limiter-config.patch98
1 files changed, 98 insertions, 0 deletions
diff --git a/patches/unapplied/server/0708-Add-packet-limiter-config.patch b/patches/unapplied/server/0708-Add-packet-limiter-config.patch
new file mode 100644
index 0000000000..cc497d052a
--- /dev/null
+++ b/patches/unapplied/server/0708-Add-packet-limiter-config.patch
@@ -0,0 +1,98 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Fri, 30 Oct 2020 22:37:16 -0700
+Subject: [PATCH] Add packet limiter config
+
+Example config:
+packet-limiter:
+ kick-message: '&cSent too many packets'
+ limits:
+ all:
+ interval: 7.0
+ max-packet-rate: 500.0
+ ServerboundPlaceRecipePacket:
+ interval: 4.0
+ max-packet-rate: 5.0
+ action: DROP
+
+all section refers to all incoming packets, the action for all is
+hard coded to KICK.
+
+For specific limits, the section name is the class's name,
+and an action can be defined: DROP or KICK
+
+If interval or rate are less-than 0, the limit is ignored
+
+diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
+index b967c24e9ace2b6539e94bcc63b69e0c934a72be..ed27a0eb28b39f045064432107a86efc3b5927cd 100644
+--- a/src/main/java/net/minecraft/network/Connection.java
++++ b/src/main/java/net/minecraft/network/Connection.java
+@@ -156,6 +156,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
+ }
+ }
+ // Paper end - allow controlled flushing
++ // Paper start - packet limiter
++ protected final Object PACKET_LIMIT_LOCK = new Object();
++ protected final @Nullable io.papermc.paper.util.IntervalledCounter allPacketCounts = io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.allPackets.isEnabled() ? new io.papermc.paper.util.IntervalledCounter(
++ (long)(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.allPackets.interval() * 1.0e9)
++ ) : null;
++ protected final java.util.Map<Class<? extends net.minecraft.network.protocol.Packet<?>>, io.papermc.paper.util.IntervalledCounter> packetSpecificLimits = new java.util.HashMap<>();
++
++ private boolean stopReadingPackets;
++ private void killForPacketSpam() {
++ this.sendPacket(new ClientboundDisconnectPacket(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.kickMessage)), PacketSendListener.thenRun(() -> {
++ this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.kickMessage));
++ }));
++ this.setReadOnly();
++ this.stopReadingPackets = true;
++ }
++ // Paper end - packet limiter
+
+ public Connection(PacketFlow side) {
+ this.receiving = side;
+@@ -240,6 +256,45 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
+
+ protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet<?> packet) {
+ if (this.channel.isOpen()) {
++ // Paper start - packet limiter
++ if (this.stopReadingPackets) {
++ return;
++ }
++ if (this.allPacketCounts != null ||
++ io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.overrides.containsKey(packet.getClass())) {
++ long time = System.nanoTime();
++ synchronized (PACKET_LIMIT_LOCK) {
++ if (this.allPacketCounts != null) {
++ this.allPacketCounts.updateAndAdd(1, time);
++ if (this.allPacketCounts.getRate() >= io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.allPackets.maxPacketRate()) {
++ this.killForPacketSpam();
++ return;
++ }
++ }
++
++ for (Class<?> check = packet.getClass(); check != Object.class; check = check.getSuperclass()) {
++ io.papermc.paper.configuration.GlobalConfiguration.PacketLimiter.PacketLimit packetSpecificLimit =
++ io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.overrides.get(check);
++ if (packetSpecificLimit == null || !packetSpecificLimit.isEnabled()) {
++ continue;
++ }
++ io.papermc.paper.util.IntervalledCounter counter = this.packetSpecificLimits.computeIfAbsent((Class)check, (clazz) -> {
++ return new io.papermc.paper.util.IntervalledCounter((long)(packetSpecificLimit.interval() * 1.0e9));
++ });
++ counter.updateAndAdd(1, time);
++ if (counter.getRate() >= packetSpecificLimit.maxPacketRate()) {
++ switch (packetSpecificLimit.action()) {
++ case DROP:
++ return;
++ case KICK:
++ this.killForPacketSpam();
++ return;
++ }
++ }
++ }
++ }
++ }
++ // Paper end - packet limiter
+ try {
+ Connection.genericsFtw(packet, this.packetListener);
+ } catch (RunningOnDifferentThreadException cancelledpackethandleexception) {