mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-07 19:30:34 +01:00
Implement a "proper" connection throttle for netty.
Proper meaning a simple portover from CraftBukkit's implementation. The last implementation had a few issues: - For each server ping, the connection was getting throttled. - ConcurrentHashMap is heavy (More of an opinion but don't judge) From the last implementation, the connection throttle entry (your IP) wasn't getting removed from the list after a server ping, which is supposed to happen according to the original implementation.
This commit is contained in:
parent
b158bb3960
commit
296620b306
@ -152,7 +152,7 @@ index 9f8afe3..b1d3a17 100644
|
|||||||
};
|
};
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
diff --git a/src/main/java/net/minecraft/server/PendingConnection.java b/src/main/java/net/minecraft/server/PendingConnection.java
|
diff --git a/src/main/java/net/minecraft/server/PendingConnection.java b/src/main/java/net/minecraft/server/PendingConnection.java
|
||||||
index eb474f5..fcfc3d2 100644
|
index eb474f5..bbf1abd 100644
|
||||||
--- a/src/main/java/net/minecraft/server/PendingConnection.java
|
--- a/src/main/java/net/minecraft/server/PendingConnection.java
|
||||||
+++ b/src/main/java/net/minecraft/server/PendingConnection.java
|
+++ b/src/main/java/net/minecraft/server/PendingConnection.java
|
||||||
@@ -17,7 +17,7 @@ public class PendingConnection extends Connection {
|
@@ -17,7 +17,7 @@ public class PendingConnection extends Connection {
|
||||||
@ -190,6 +190,80 @@ index eb474f5..fcfc3d2 100644
|
|||||||
// CraftBukkit start - Fix decompile issues, don't create a list from an array
|
// CraftBukkit start - Fix decompile issues, don't create a list from an array
|
||||||
Object[] list = new Object[] { 1, 60, this.server.getVersion(), pingEvent.getMotd(), playerlist.getPlayerCount(), pingEvent.getMaxPlayers() };
|
Object[] list = new Object[] { 1, 60, this.server.getVersion(), pingEvent.getMotd(), playerlist.getPlayerCount(), pingEvent.getMaxPlayers() };
|
||||||
|
|
||||||
|
@@ -173,8 +178,8 @@ public class PendingConnection extends Connection {
|
||||||
|
|
||||||
|
this.networkManager.queue(new Packet255KickDisconnect(s));
|
||||||
|
this.networkManager.d();
|
||||||
|
- if (inetaddress != null && this.server.ae() instanceof DedicatedServerConnection) {
|
||||||
|
- ((DedicatedServerConnection) this.server.ae()).a(inetaddress);
|
||||||
|
+ if (inetaddress != null) { // Spigot - removed DedicatedServerConnection instance check
|
||||||
|
+ this.server.ae().a(inetaddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.b = true;
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..0113ed3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/minecraft/server/ServerConnection.java
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+package net.minecraft.server;
|
||||||
|
+
|
||||||
|
+import java.net.InetAddress;
|
||||||
|
+import java.util.ArrayList;
|
||||||
|
+import java.util.Collections;
|
||||||
|
+import java.util.List;
|
||||||
|
+
|
||||||
|
+public abstract class ServerConnection {
|
||||||
|
+
|
||||||
|
+ private final MinecraftServer b;
|
||||||
|
+ private final List c = Collections.synchronizedList(new ArrayList());
|
||||||
|
+ public volatile boolean a = false;
|
||||||
|
+
|
||||||
|
+ public ServerConnection(MinecraftServer minecraftserver) {
|
||||||
|
+ this.b = minecraftserver;
|
||||||
|
+ this.a = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void a(PlayerConnection playerconnection) {
|
||||||
|
+ this.c.add(playerconnection);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public abstract void a(InetAddress address); // Spigot - make a(InetAddress) a abstract void
|
||||||
|
+
|
||||||
|
+ public void a() {
|
||||||
|
+ this.a = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void b() {
|
||||||
|
+ for (int i = 0; i < this.c.size(); ++i) {
|
||||||
|
+ PlayerConnection playerconnection = (PlayerConnection) this.c.get(i);
|
||||||
|
+
|
||||||
|
+ try {
|
||||||
|
+ playerconnection.d();
|
||||||
|
+ } catch (Exception exception) {
|
||||||
|
+ if (playerconnection.networkManager instanceof MemoryNetworkManager) {
|
||||||
|
+ CrashReport crashreport = CrashReport.a((Throwable) exception, "Ticking memory connection");
|
||||||
|
+
|
||||||
|
+ throw new ReportedException(crashreport);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this.b.getLogger().warning("Failed to handle packet for " + playerconnection.player.getLocalizedName() + "/" + playerconnection.player.p() + ": " + exception, (Throwable) exception);
|
||||||
|
+ playerconnection.disconnect("Internal server error");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (playerconnection.disconnected) {
|
||||||
|
+ this.c.remove(i--);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ playerconnection.networkManager.a();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public MinecraftServer d() {
|
||||||
|
+ return this.b;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
diff --git a/src/main/java/net/minecraft/server/ThreadCommandReader.java b/src/main/java/net/minecraft/server/ThreadCommandReader.java
|
diff --git a/src/main/java/net/minecraft/server/ThreadCommandReader.java b/src/main/java/net/minecraft/server/ThreadCommandReader.java
|
||||||
index 489e184..9533b6f 100644
|
index 489e184..9533b6f 100644
|
||||||
--- a/src/main/java/net/minecraft/server/ThreadCommandReader.java
|
--- a/src/main/java/net/minecraft/server/ThreadCommandReader.java
|
||||||
@ -302,10 +376,10 @@ index 0000000..2dbbf6c
|
|||||||
+}
|
+}
|
||||||
diff --git a/src/main/java/org/spigotmc/netty/NettyNetworkManager.java b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java
|
diff --git a/src/main/java/org/spigotmc/netty/NettyNetworkManager.java b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..94d126d
|
index 0000000..85a6c05
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java
|
+++ b/src/main/java/org/spigotmc/netty/NettyNetworkManager.java
|
||||||
@@ -0,0 +1,247 @@
|
@@ -0,0 +1,271 @@
|
||||||
+package org.spigotmc.netty;
|
+package org.spigotmc.netty;
|
||||||
+
|
+
|
||||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
@ -313,10 +387,13 @@ index 0000000..94d126d
|
|||||||
+import io.netty.channel.ChannelHandlerContext;
|
+import io.netty.channel.ChannelHandlerContext;
|
||||||
+import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
+import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
||||||
+import io.netty.channel.socket.SocketChannel;
|
+import io.netty.channel.socket.SocketChannel;
|
||||||
|
+import java.net.InetAddress;
|
||||||
|
+import java.net.InetSocketAddress;
|
||||||
+import java.net.Socket;
|
+import java.net.Socket;
|
||||||
+import java.net.SocketAddress;
|
+import java.net.SocketAddress;
|
||||||
+import java.security.PrivateKey;
|
+import java.security.PrivateKey;
|
||||||
+import java.util.AbstractList;
|
+import java.util.AbstractList;
|
||||||
|
+import java.util.HashMap;
|
||||||
+import java.util.List;
|
+import java.util.List;
|
||||||
+import java.util.Queue;
|
+import java.util.Queue;
|
||||||
+import java.util.concurrent.ConcurrentLinkedQueue;
|
+import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
@ -370,12 +447,33 @@ index 0000000..94d126d
|
|||||||
+ private Object[] dcArgs;
|
+ private Object[] dcArgs;
|
||||||
+ private Socket socketAdaptor;
|
+ private Socket socketAdaptor;
|
||||||
+ private long writtenBytes;
|
+ private long writtenBytes;
|
||||||
|
+ private long connectionThrottle;
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||||
+ // Channel and address groundwork first
|
+ // Channel and address groundwork first
|
||||||
+ channel = ctx.channel();
|
+ channel = ctx.channel();
|
||||||
+ address = channel.remoteAddress();
|
+ address = channel.remoteAddress();
|
||||||
|
+ // Connection throttler (ported from CraftBukkit)
|
||||||
|
+ long currentTime = System.currentTimeMillis();
|
||||||
|
+ InetAddress iaddress = ((InetSocketAddress) channel.remoteAddress()).getAddress();
|
||||||
|
+
|
||||||
|
+ if (server == null || server.server == null) {
|
||||||
|
+ channel.close();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ connectionThrottle = server.server.getConnectionThrottle();
|
||||||
|
+
|
||||||
|
+ synchronized (serverConnection.throttledConnections) {
|
||||||
|
+ if (serverConnection.throttledConnections.containsKey(iaddress) && !"127.0.0.1".equals(iaddress.getHostAddress()) && currentTime - (serverConnection.throttledConnections.get(iaddress)).longValue() < connectionThrottle) {
|
||||||
|
+ serverConnection.throttledConnections.put(iaddress, Long.valueOf(currentTime));
|
||||||
|
+ channel.close();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ serverConnection.throttledConnections.put(iaddress, Long.valueOf(currentTime));
|
||||||
|
+ }
|
||||||
+ // Then the socket adaptor
|
+ // Then the socket adaptor
|
||||||
+ socketAdaptor = NettySocketAdaptor.adapt((SocketChannel) channel);
|
+ socketAdaptor = NettySocketAdaptor.adapt((SocketChannel) channel);
|
||||||
+ // Followed by their first handler
|
+ // Followed by their first handler
|
||||||
@ -555,10 +653,10 @@ index 0000000..94d126d
|
|||||||
+}
|
+}
|
||||||
diff --git a/src/main/java/org/spigotmc/netty/NettyServerConnection.java b/src/main/java/org/spigotmc/netty/NettyServerConnection.java
|
diff --git a/src/main/java/org/spigotmc/netty/NettyServerConnection.java b/src/main/java/org/spigotmc/netty/NettyServerConnection.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..790f325
|
index 0000000..7809aa9
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/src/main/java/org/spigotmc/netty/NettyServerConnection.java
|
+++ b/src/main/java/org/spigotmc/netty/NettyServerConnection.java
|
||||||
@@ -0,0 +1,110 @@
|
@@ -0,0 +1,126 @@
|
||||||
+package org.spigotmc.netty;
|
+package org.spigotmc.netty;
|
||||||
+
|
+
|
||||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
@ -576,6 +674,7 @@ index 0000000..790f325
|
|||||||
+import java.security.Key;
|
+import java.security.Key;
|
||||||
+import java.util.ArrayList;
|
+import java.util.ArrayList;
|
||||||
+import java.util.Collections;
|
+import java.util.Collections;
|
||||||
|
+import java.util.HashMap;
|
||||||
+import java.util.List;
|
+import java.util.List;
|
||||||
+import java.util.logging.Level;
|
+import java.util.logging.Level;
|
||||||
+import javax.crypto.Cipher;
|
+import javax.crypto.Cipher;
|
||||||
@ -594,6 +693,7 @@ index 0000000..790f325
|
|||||||
+public class NettyServerConnection extends ServerConnection {
|
+public class NettyServerConnection extends ServerConnection {
|
||||||
+
|
+
|
||||||
+ private final ChannelFuture socket;
|
+ private final ChannelFuture socket;
|
||||||
|
+ final HashMap<InetAddress, Long> throttledConnections = new HashMap<InetAddress, Long>();
|
||||||
+ final List<PendingConnection> pendingConnections = Collections.synchronizedList(new ArrayList<PendingConnection>());
|
+ final List<PendingConnection> pendingConnections = Collections.synchronizedList(new ArrayList<PendingConnection>());
|
||||||
+
|
+
|
||||||
+ public NettyServerConnection(MinecraftServer ms, InetAddress host, int port) {
|
+ public NettyServerConnection(MinecraftServer ms, InetAddress host, int port) {
|
||||||
@ -643,6 +743,20 @@ index 0000000..790f325
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ /**
|
+ /**
|
||||||
|
+ * Remove the user from connection throttle. This should fix the server ping bugs.
|
||||||
|
+ *
|
||||||
|
+ * @param address the address to remove
|
||||||
|
+ */
|
||||||
|
+ @Override
|
||||||
|
+ public void a(InetAddress address) {
|
||||||
|
+ if (address != null) {
|
||||||
|
+ synchronized (throttledConnections) {
|
||||||
|
+ throttledConnections.remove(address);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
+ * Shutdown. This method is called when the server is shutting down and the
|
+ * Shutdown. This method is called when the server is shutting down and the
|
||||||
+ * server socket and all clients should be terminated with no further
|
+ * server socket and all clients should be terminated with no further
|
||||||
+ * action.
|
+ * action.
|
||||||
|
Loading…
Reference in New Issue
Block a user