Fix ipv6 loopback addresses being able to get connection throttled (#12155)

This commit is contained in:
Warrior 2025-04-30 17:50:18 +02:00 committed by GitHub
parent a74400d92c
commit 1e930763d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -9,10 +9,10 @@
+ static final java.util.regex.Pattern HOST_PATTERN = java.util.regex.Pattern.compile("[0-9a-f\\.:]{0,45}"); + static final java.util.regex.Pattern HOST_PATTERN = java.util.regex.Pattern.compile("[0-9a-f\\.:]{0,45}");
+ static final java.util.regex.Pattern PROP_PATTERN = java.util.regex.Pattern.compile("\\w{0,16}"); + static final java.util.regex.Pattern PROP_PATTERN = java.util.regex.Pattern.compile("\\w{0,16}");
+ // Spigot end + // Spigot end
+ // CraftBukkit start - add fields + // Paper start - Connection throttle
+ private static final java.util.HashMap<java.net.InetAddress, Long> throttleTracker = new java.util.HashMap<>(); + private static final java.util.Map<java.net.InetAddress, Long> throttleTracker = new java.util.HashMap<>();
+ private static int throttleCounter = 0; + private static int throttleCounter = 0;
+ // CraftBukkit end + // Paper end - Connection throttle
+ private static final boolean BYPASS_HOSTCHECK = Boolean.getBoolean("Paper.bypassHostCheck"); // Paper + private static final boolean BYPASS_HOSTCHECK = Boolean.getBoolean("Paper.bypassHostCheck"); // Paper
private final MinecraftServer server; private final MinecraftServer server;
private final Connection connection; private final Connection connection;
@ -29,7 +29,7 @@
switch (packet.intention()) { switch (packet.intention()) {
case LOGIN: case LOGIN:
this.beginLogin(packet, false); this.beginLogin(packet, false);
@@ -50,22 +_,117 @@ @@ -50,22 +_,118 @@
default: default:
throw new UnsupportedOperationException("Invalid intention " + packet.intention()); throw new UnsupportedOperationException("Invalid intention " + packet.intention());
} }
@ -42,17 +42,18 @@
private void beginLogin(ClientIntentionPacket packet, boolean transferred) { private void beginLogin(ClientIntentionPacket packet, boolean transferred) {
this.connection.setupOutboundProtocol(LoginProtocols.CLIENTBOUND); this.connection.setupOutboundProtocol(LoginProtocols.CLIENTBOUND);
+ // CraftBukkit start - Connection throttle + // Paper start - Connection throttle
+ try { + try {
+ if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket + final long connectionThrottle = this.server.server.getConnectionThrottle();
+ final boolean isUnixDomainSocket = this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress; // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket
+ if (connectionThrottle > 0 && !isUnixDomainSocket && this.connection.getRemoteAddress() instanceof java.net.InetSocketAddress socketAddress && !socketAddress.isUnresolved() && !socketAddress.getAddress().isLoopbackAddress()) {
+ long currentTime = System.currentTimeMillis(); + long currentTime = System.currentTimeMillis();
+ long connectionThrottle = this.server.server.getConnectionThrottle(); + java.net.InetAddress address = socketAddress.getAddress();
+ java.net.InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
+ +
+ synchronized (ServerHandshakePacketListenerImpl.throttleTracker) { + synchronized (ServerHandshakePacketListenerImpl.throttleTracker) {
+ if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) { + if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) {
+ ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime); + ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime);
+ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message + Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle);
+ this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); + this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage));
+ this.connection.disconnect(chatmessage); + this.connection.disconnect(chatmessage);
+ return; + return;
@ -67,11 +68,11 @@
+ ServerHandshakePacketListenerImpl.throttleTracker.values().removeIf(time -> time > connectionThrottle); + ServerHandshakePacketListenerImpl.throttleTracker.values().removeIf(time -> time > connectionThrottle);
+ } + }
+ } + }
+ } // Paper - Unix domain socket support + }
+ } catch (Throwable t) { + } catch (Throwable t) {
+ org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
+ } + }
+ // CraftBukkit end + // Paper end - Connection throttle
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) { if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) {
- Component component; - Component component;
- if (packet.protocolVersion() < 754) { - if (packet.protocolVersion() < 754) {