Skip to content

feat: harden login plugin-message and keep-alive handling#689

Merged
robinbraemer merged 1 commit into
masterfrom
feat/sync-velocity-pr11
May 27, 2026
Merged

feat: harden login plugin-message and keep-alive handling#689
robinbraemer merged 1 commit into
masterfrom
feat/sync-velocity-pr11

Conversation

@robinbraemer
Copy link
Copy Markdown
Member

@robinbraemer robinbraemer commented May 26, 2026

Hardening fixes for the login / plugin-message / keep-alive / compression paths. Each behavioral change ships with a focused unit test; the full repo test suite is green.

Changes

Area Change Test
Plugin message Reject serverbound plugin-message payloads larger than the vanilla 32767-byte limit (clientbound unchanged) message_test.go
Compression Cap a serverbound packet's claimed decompressed size at 2 MiB (clientbound keeps the 8 MiB vanilla cap) decoder_decompress_test.go
Client play (DoS) Bound the pre-join loginPluginMessages queue by count (1024) and total bytes (4 MiB); disconnect on overflow session_client_play_queue_test.go
Keep-alive Forward a keep-alive to the backend only when it is open and in the same protocol state as the client (CONFIG/PLAY); always consume the pending ping session_client_play_keepalive_test.go
Versions The Minecraft_26_1 entry lists all protocol-775 release names (26.1, 26.1.1, 26.1.2)

Why these matter

  • Serverbound payload, decompression, and pre-join queue caps — serverbound data comes from the untrusted client; these three bounds together limit how much memory a client can force the proxy to allocate (a client that never finishes its login/FML handshake previously had an unbounded queue; decompression was capped at 8 MiB regardless of direction).
  • Keep-alive state guard — during a server switch the backend may be in CONFIG while the client is still in PLAY; forwarding a PLAY-encoded keep-alive into a CONFIG-state backend would mis-encode the packet. The fix also stops a consumed ping from being re-dispatched to another connection.

The serverbound bounds and keep-alive guard follow the approach Velocity uses for the same paths.

Related upstream changes intentionally out of scope

  • Packet rate-limiter subsystem (per-connection bytes/packets-per-second) — large new feature with no direct analog in Gate's netmc layer; Gate already has connection/login quotas (config.quota). Belongs in its own PR.
  • Backend disconnected() result change — Gate's result(nil, err) already yields a graceful, recovery-eligible disconnect via handleConnectionErr; the upstream change addresses a Java CompletableFuture detail with no Go equivalent.
  • Netty-specific changes (ByteBuf refcount handling, frame-decoder index handling, backend large-packet flush batching, status player-sample bound, MiniMessage/HTTP-client cleanups) — N/A: Gate's Go codec/forwarding model has no analogous code.

Verification

  • go build ./... — clean
  • go vet ./pkg/edition/java/... — clean
  • go test ./... — all packages pass (0 failures)
  • gofmt — clean

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 26, 2026

Deploying gate-minekube with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0caba07
Status: ✅  Deploy successful!
Preview URL: https://17db2bcd.gate-minekube.pages.dev
Branch Preview URL: https://feat-sync-velocity-pr11.gate-minekube.pages.dev

View logs

@robinbraemer robinbraemer force-pushed the feat/sync-velocity-pr11 branch from 3213573 to 97b9307 Compare May 27, 2026 06:36
@robinbraemer robinbraemer force-pushed the feat/sync-velocity-pr11 branch from 97b9307 to f1bda66 Compare May 27, 2026 11:21
@robinbraemer robinbraemer changed the title feat: sync hardening fixes from Velocity dev/3.0.0 (PR #11) feat: harden login plugin-message and keep-alive handling May 27, 2026
- version: the Minecraft 26.1 entry now lists every protocol-775 release
  name (26.1, 26.1.1, 26.1.2).
- plugin message: reject serverbound payloads larger than the vanilla
  32767-byte limit (clientbound unchanged) to prevent client abuse.
- compression: cap a serverbound packet's claimed decompressed size at
  2 MiB (clientbound keeps the 8 MiB vanilla cap). Serverbound data is
  untrusted, so this limits how much memory a client can force the proxy
  to allocate.
- client play: bound the pre-join loginPluginMessages queue by message
  count (1024) and total bytes (4 MiB), disconnecting on overflow. A
  client that never completes its login/FML phase could otherwise grow
  the queue without limit.
- keep-alive: only forward a keep-alive to the backend when it is open
  and in the same protocol state as the client (CONFIG/PLAY), and always
  consume the pending ping. Prevents mis-encoding a PLAY keep-alive to a
  backend still in CONFIG during a server switch.

The serverbound bounds and keep-alive state guard adopt the approach
Velocity uses for the same paths. Each behavioral change has a focused
unit test.
@robinbraemer robinbraemer force-pushed the feat/sync-velocity-pr11 branch from f1bda66 to 0caba07 Compare May 27, 2026 11:29
@robinbraemer robinbraemer merged commit f818164 into master May 27, 2026
7 checks passed
@robinbraemer robinbraemer deleted the feat/sync-velocity-pr11 branch May 27, 2026 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant