-
-
Notifications
You must be signed in to change notification settings - Fork 307
Use Velocity VarIntFrameDecoder #783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
5b3ddf0
Use Velocity VarIntFrameDecoder
xism4 b9b8309
Replace GPL license with same as 0056 patch.
xism4 6f7929a
Remove unused objects due trace-less catch
xism4 532158a
Re-implement TOO_BIG result
xism4 2fbb6b4
Merge branch 'PaperMC:master' into master
xism4 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
188 changes: 188 additions & 0 deletions
188
BungeeCord-Patches/0066-Use-Velocity-VarintFrameDecoder.patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,188 @@ | ||
| From dcbe861c2c63b09edc88ca7f3e42d9f9687f63af Mon Sep 17 00:00:00 2001 | ||
| From: xIsm4 <minelatinsoporte@gmail.com> | ||
| Date: Thu, 17 Nov 2022 10:52:42 +0100 | ||
| Subject: [PATCH] Use Velocity VarintFrameDecoder | ||
|
|
||
|
|
||
| diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java | ||
| index c0d37142..bdeab0dc 100644 | ||
| --- a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java | ||
| +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java | ||
| @@ -1,65 +1,78 @@ | ||
| +/* | ||
| + * Courtesy of Velocity | ||
| + * See https://github.com/VelocityPowered/Velocity/commit/5ceac16a821ea35572ff11412ace8929fd06e278 | ||
| + */ | ||
| + | ||
| package net.md_5.bungee.protocol; | ||
|
|
||
| +import net.md_5.bungee.protocol.VarintByteDecoder.DecodeResult; | ||
| import io.netty.buffer.ByteBuf; | ||
| -import io.netty.buffer.Unpooled; | ||
| import io.netty.channel.ChannelHandlerContext; | ||
| import io.netty.handler.codec.ByteToMessageDecoder; | ||
| -import io.netty.handler.codec.CorruptedFrameException; | ||
| + | ||
| import java.util.List; | ||
|
|
||
| -public class Varint21FrameDecoder extends ByteToMessageDecoder | ||
| -{ | ||
| +public class Varint21FrameDecoder extends ByteToMessageDecoder { | ||
|
|
||
| - private static boolean DIRECT_WARNING; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The patch 0044-Don-t-use-a-bytebuf-for-packet-decoding.patch should be edited if you want to remove this line.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it |
||
| + private static final FastDecoderException BAD_LENGTH_CACHED = | ||
| + new FastDecoderException("Bad packet length"); | ||
| + private static final FastDecoderException VARINT_BIG_CACHED = | ||
| + new FastDecoderException("VarInt too big"); | ||
|
|
||
| @Override | ||
| - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception | ||
| - { | ||
| - // If we decode an invalid packet and an exception is thrown (thus triggering a close of the connection), | ||
| - // the Netty ByteToMessageDecoder will continue to frame more packets and potentially call fireChannelRead() | ||
| - // on them, likely with more invalid packets. Therefore, check if the connection is no longer active and if so | ||
| - // sliently discard the packet. | ||
| - if ( !ctx.channel().isActive() ) | ||
| - { | ||
| - in.skipBytes( in.readableBytes() ); | ||
| + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { | ||
| + if (!ctx.channel().isActive()) { | ||
| + in.clear(); | ||
| return; | ||
| } | ||
|
|
||
| - in.markReaderIndex(); | ||
| + final VarintByteDecoder reader = new VarintByteDecoder(); | ||
|
xism4 marked this conversation as resolved.
xism4 marked this conversation as resolved.
|
||
|
|
||
| - for ( int i = 0; i < 3; i++ ) // Waterfall | ||
| - { | ||
| - if ( !in.isReadable() ) | ||
| - { | ||
| - in.resetReaderIndex(); | ||
| - return; | ||
| + int varintEnd = in.forEachByte(reader); | ||
| + if (varintEnd == -1) { | ||
| + // We tried to go beyond the end of the buffer. This is probably a good sign that the | ||
| + // buffer was too short to hold a proper varint. | ||
| + if (reader.getResult() == DecodeResult.RUN_OF_ZEROES) { | ||
| + // Special case where the entire packet is just a run of zeroes. We ignore them all. | ||
| + in.clear(); | ||
| } | ||
| + return; | ||
| + } | ||
|
|
||
| - // Waterfall start | ||
| - byte read = in.readByte(); | ||
| - if ( read >= 0 ) | ||
| - { | ||
| - in.resetReaderIndex(); | ||
| - int length = DefinedPacket.readVarInt( in ); | ||
| - // Waterfall end | ||
| - if ( false && length == 0) // Waterfall - ignore | ||
| - { | ||
| - throw new CorruptedFrameException( "Empty Packet!" ); | ||
| - } | ||
| - | ||
| - if ( in.readableBytes() < length ) | ||
| - { | ||
| - in.resetReaderIndex(); | ||
| - return; | ||
| - // Waterfall start | ||
| - } else { | ||
| - out.add(in.readRetainedSlice(length)); | ||
| - return; | ||
| - // Waterfall end | ||
| + if (reader.getResult() == DecodeResult.RUN_OF_ZEROES) { | ||
| + // this will return to the point where the next varint starts | ||
| + in.readerIndex(varintEnd); | ||
| + } else if (reader.getResult() == DecodeResult.SUCCESS) { | ||
| + int readVarint = reader.getReadVarint(); | ||
| + int bytesRead = reader.getBytesRead(); | ||
| + if (readVarint < 0) { | ||
| + in.clear(); | ||
| + throw BAD_LENGTH_CACHED; | ||
| + } else if (readVarint == 0) { | ||
| + // skip over the empty packet(s) and ignore it | ||
| + in.readerIndex(varintEnd + 1); | ||
| + } else { | ||
| + int minimumRead = bytesRead + readVarint; | ||
| + if (in.isReadable(minimumRead)) { | ||
| + out.add(in.retainedSlice(varintEnd + 1, readVarint)); | ||
| + in.skipBytes(minimumRead); | ||
| } | ||
| } | ||
| + } else if (reader.getResult() == DecodeResult.TOO_BIG) { | ||
| + in.clear(); | ||
| + throw VARINT_BIG_CACHED; | ||
| } | ||
| - | ||
| - throw new CorruptedFrameException( "length wider than 21-bit" ); | ||
| } | ||
| -} | ||
| +} | ||
| \ No newline at end of file | ||
| diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/VarintByteDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/VarintByteDecoder.java | ||
| new file mode 100644 | ||
| index 00000000..2e4ccf05 | ||
| --- /dev/null | ||
| +++ b/protocol/src/main/java/net/md_5/bungee/protocol/VarintByteDecoder.java | ||
| @@ -0,0 +1,68 @@ | ||
| +/* | ||
| + * Courtesy of Velocity | ||
| + * See https://github.com/VelocityPowered/Velocity/commit/5ceac16a821ea35572ff11412ace8929fd06e278 | ||
| + */ | ||
|
xism4 marked this conversation as resolved.
|
||
| + | ||
| +package net.md_5.bungee.protocol; | ||
| + | ||
| +import io.netty.util.ByteProcessor; | ||
| + | ||
| +class VarintByteDecoder implements ByteProcessor { | ||
| + | ||
| + private int readVarint; | ||
| + private int bytesRead; | ||
| + private DecodeResult result = DecodeResult.TOO_SHORT; | ||
| + | ||
| + @Override | ||
| + public boolean process(byte k) { | ||
| + if (k == 0 && bytesRead == 0) { | ||
| + // tentatively say it's invalid, but there's a possibility of redemption | ||
| + result = DecodeResult.RUN_OF_ZEROES; | ||
| + return true; | ||
| + } | ||
| + if (result == DecodeResult.RUN_OF_ZEROES) { | ||
| + return false; | ||
| + } | ||
| + readVarint |= (k & 0x7F) << bytesRead++ * 7; | ||
| + if (bytesRead > 3) { | ||
| + result = DecodeResult.TOO_BIG; | ||
| + return false; | ||
| + } | ||
| + if ((k & 0x80) != 128) { | ||
| + result = DecodeResult.SUCCESS; | ||
| + return false; | ||
| + } | ||
| + return true; | ||
| + } | ||
| + | ||
| + public int getReadVarint() { | ||
| + return readVarint; | ||
| + } | ||
| + | ||
| + public int getBytesRead() { | ||
| + return bytesRead; | ||
| + } | ||
| + | ||
| + public DecodeResult getResult() { | ||
| + return result; | ||
| + } | ||
| + | ||
| + public enum DecodeResult { | ||
| + SUCCESS, | ||
| + TOO_BIG, | ||
| + RUN_OF_ZEROES, | ||
| + } | ||
| +} | ||
| \ No newline at end of file | ||
| -- | ||
| 2.38.1.windows.1 | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.