mirror of
https://github.com/PaperMC/Paper
synced 2026-08-20 18:26:12 -04:00
Fix login compression setup ordering/race condition (#13929)
This commit is contained in:
parent
ae22db2692
commit
2951b50613
4 changed files with 60 additions and 20 deletions
|
|
@ -28,7 +28,7 @@ and then catch exceptions and close if they fire.
|
|||
Part of this commit was authored by: Spottedleaf, sandtechnology
|
||||
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a14a25a59a 100644
|
||||
index cc91fceced12698146766a6b09a8dce8f573f39e..3f10ea62d2ef70e7e4f01c83942cd9051249954c 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -65,7 +65,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
|
@ -102,7 +102,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
}
|
||||
}
|
||||
|
||||
@@ -420,21 +451,42 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -444,21 +475,42 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
private void doSendPacket(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
|
||||
|
|
@ -125,7 +125,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
} else {
|
||||
- this.channel.write(packet, this.channel.voidPromise());
|
||||
+ future = this.channel.write(packet, this.channel.voidPromise()); // Paper - Optimize network
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ // Paper start - Optimize network
|
||||
+ if (packet.hasFinishListener()) {
|
||||
|
|
@ -136,7 +136,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
+ Component reason = Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage());
|
||||
+ this.send(new ClientboundDisconnectPacket(reason), PacketSendListener.thenRun(() -> this.disconnect(reason)));
|
||||
+ packet.onPacketDispatchFinish(player, null);
|
||||
}
|
||||
+ }
|
||||
+ // Paper end - Optimize network
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
}
|
||||
}
|
||||
|
||||
@@ -446,16 +498,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -470,16 +522,57 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
|
||||
private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
|
||||
private static int joinAttemptsThisTick; // Paper - Buffer joins to world
|
||||
@@ -525,6 +618,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -549,6 +642,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
public void disconnect(final DisconnectionDetails details) {
|
||||
this.preparing = false; // Spigot
|
||||
|
|
@ -220,7 +220,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
if (this.channel == null) {
|
||||
this.delayedDisconnect = details;
|
||||
}
|
||||
@@ -714,7 +808,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -738,7 +832,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public void handleDisconnection() {
|
||||
if (this.channel != null && !this.channel.isOpen()) {
|
||||
if (this.disconnectionHandled) {
|
||||
|
|
@ -229,7 +229,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
} else {
|
||||
this.disconnectionHandled = true;
|
||||
PacketListener packetListener = this.getPacketListener();
|
||||
@@ -725,7 +819,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -749,7 +843,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
);
|
||||
disconnectListener.onDisconnect(details);
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ index 6e7331dc7bc5f7e69f21eec0b42141dde36a6c08..fceaac42791034a047d2af4acfd160a1
|
|||
// Paper start - Add PlayerConnectionCloseEvent
|
||||
if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
|
||||
/* Player was logged in, either game listener or configuration listener */
|
||||
@@ -768,4 +862,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -792,4 +886,96 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
public @Nullable UUID getIntendedProfileId() {
|
||||
return this.intendedProfileId;
|
||||
}
|
||||
|
|
@ -372,7 +372,7 @@ index 1480d0db90f5797e3dee19503e52d1e783493ac3..bd76e55ea56dd7c1e232806d1d13a747
|
|||
+ // Paper end
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index ffa34134e3b4b6fdeafc0922e4eb49be12c6fbb7..c5e029444adb05c129d51b51f63fcf63a8c70ce8 100644
|
||||
index b7476ff3f5570b92e9e4ca8fc756f3a8098b1385..1a60071f32a0c92c69f60c75035e5324aa144fb4 100644
|
||||
--- a/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -55,11 +55,13 @@ public class ServerConnectionListener {
|
||||
|
|
|
|||
|
|
@ -267,10 +267,10 @@ index 595db570b0ade9cad7de77d2ab7b10d9e68699df..ac095f59d9f17d8239d6493d1c1e3942
|
|||
+ // Paper end - Use Velocity cipher
|
||||
}
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index fceaac42791034a047d2af4acfd160a14a25a59a..01e5ff70c70dd7fab089d8965bd1c237fa239f45 100644
|
||||
index 3f10ea62d2ef70e7e4f01c83942cd9051249954c..9a04309584a5b9b55d0d383619113835190ad8f9 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -744,10 +744,24 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -768,10 +768,24 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +298,7 @@ index fceaac42791034a047d2af4acfd160a14a25a59a..01e5ff70c70dd7fab089d8965bd1c237
|
|||
|
||||
public boolean isConnected() {
|
||||
return this.channel != null && this.channel.isOpen();
|
||||
@@ -781,16 +795,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -805,16 +819,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
|
||||
public void setupCompression(final int threshold, final boolean validateDecompressed) {
|
||||
if (threshold >= 0) {
|
||||
|
|
@ -320,7 +320,7 @@ index fceaac42791034a047d2af4acfd160a14a25a59a..01e5ff70c70dd7fab089d8965bd1c237
|
|||
this.channel.pipeline().fireUserEventTriggered(io.papermc.paper.network.ConnectionEvent.COMPRESSION_THRESHOLD_SET); // Paper - Add Channel initialization listeners
|
||||
} else {
|
||||
diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index c5e029444adb05c129d51b51f63fcf63a8c70ce8..4552ebad6154c0178f928a4e9a5fe061f6fbde52 100644
|
||||
index 1a60071f32a0c92c69f60c75035e5324aa144fb4..e84e243f35b09691d03e9a9cf3de0c093b1d5cfb 100644
|
||||
--- a/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -80,6 +80,10 @@ public class ServerConnectionListener {
|
||||
|
|
@ -335,10 +335,10 @@ index c5e029444adb05c129d51b51f63fcf63a8c70ce8..4552ebad6154c0178f928a4e9a5fe061
|
|||
.add(
|
||||
new ServerBootstrap()
|
||||
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 98f8d7001ba7af6373bea630c376af3c02cafac4..fb5a84d2a00528d5c8f549f238abb6aa20d1ccad 100644
|
||||
index d6b6c6e7dce618c3f4aecc0969b7423771eab3ba..b94e01aa54b932b29370d1742b00ed73254fe4dc 100644
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -255,9 +255,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
@@ -257,9 +257,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
SecretKey secretKey = packet.getSecretKey(serverPrivateKey);
|
||||
digest = new BigInteger(Crypt.digestData("", this.server.getKeyPair().getPublic(), secretKey)).toString(16);
|
||||
this.state = ServerLoginPacketListenerImpl.State.AUTHENTICATING;
|
||||
|
|
|
|||
|
|
@ -182,6 +182,37 @@
|
|||
} catch (RejectedExecutionException ignored) {
|
||||
this.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown"));
|
||||
} catch (ClassCastException exception) {
|
||||
@@ -297,6 +_,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Add netty task scheduling helper
|
||||
+ /**
|
||||
+ * Schedules a task on the channel's event loop after all currently queued packets have been submitted for writing.
|
||||
+ * This allows the compression packet to be written and compression to be enabled in the same event-loop task.
|
||||
+ * Vanilla enables compression from a write-future listener, which may run after another packet has already been
|
||||
+ * queued without compression.
|
||||
+ *
|
||||
+ * @see <a href="https://mojira.dev/MC-308621">MC-308621</a>
|
||||
+ */
|
||||
+ public void scheduleNettyTask(final Runnable task) {
|
||||
+ final boolean connected = this.isConnected();
|
||||
+ if (!connected && !this.preparing) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (connected && this.pendingActions.isEmpty()) {
|
||||
+ this.channel.eventLoop().execute(task);
|
||||
+ } else {
|
||||
+ this.pendingActions.add(new WrappedConsumer(connection -> connection.channel.eventLoop().execute(task)));
|
||||
+ this.flushQueue();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add netty task scheduling helper
|
||||
+
|
||||
private void sendPacket(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
|
||||
this.sentPackets++;
|
||||
if (this.channel.eventLoop().inEventLoop()) {
|
||||
@@ -344,10 +_,30 @@
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -139,11 +_,11 @@
|
||||
@@ -139,21 +_,23 @@
|
||||
|
||||
private void verifyLoginAndFinishConnectionSetup(final GameProfile profile) {
|
||||
PlayerList playerList = this.server.getPlayerList();
|
||||
|
|
@ -157,9 +157,18 @@
|
|||
+ this.disconnectAsync(CommonComponents.CONNECT_FAILED); // Paper
|
||||
} else {
|
||||
if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) {
|
||||
this.connection
|
||||
@@ -153,7 +_,7 @@
|
||||
);
|
||||
- this.connection
|
||||
- .send(
|
||||
- new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()),
|
||||
- PacketSendListener.thenRun(() -> this.connection.setupCompression(this.server.getCompressionThreshold(), true))
|
||||
- );
|
||||
+ // Paper start - Keep compression packet write and setup in the same Netty task
|
||||
+ final int compressionThreshold = this.server.getCompressionThreshold();
|
||||
+ this.connection.scheduleNettyTask(() -> {
|
||||
+ this.connection.send(new ClientboundLoginCompressionPacket(compressionThreshold));
|
||||
+ this.connection.setupCompression(compressionThreshold, true);
|
||||
+ });
|
||||
+ // Paper end - Keep compression packet write and setup in the same Netty task
|
||||
}
|
||||
|
||||
- boolean waitForDisconnection = playerList.disconnectAllPlayersWithProfile(profile.id());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue