Repository: cassandra Updated Branches: refs/heads/cassandra-3.0 ac6ca9c50 -> 1681c18c2
Respond with ProtocolError to v1/v2 message header Patch by Tyler Hobbs; reviewed by Sandeep Tamhankar for CASSANDRA-11464 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/1681c18c Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/1681c18c Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/1681c18c Branch: refs/heads/cassandra-3.0 Commit: 1681c18c2f2c1be8d4c1b68c787097e8a1a23fa1 Parents: ac6ca9c Author: Tyler Hobbs <[email protected]> Authored: Tue Apr 5 14:02:18 2016 -0500 Committer: Tyler Hobbs <[email protected]> Committed: Tue Apr 5 14:02:18 2016 -0500 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ .../org/apache/cassandra/transport/Frame.java | 11 +++++++--- .../cassandra/transport/ProtocolErrorTest.java | 23 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/1681c18c/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 4baaa30..8f4329a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,6 @@ 3.0.6 + * Properly respond with ProtocolError when a v1/v2 native protocol + header is received (CASSANDRA-11464) * Validate that num_tokens and initial_token are consistent with one another (CASSANDRA-10120) Merged from 2.2: * IncomingStreamingConnection version check message wrong (CASSANDRA-11462) http://git-wip-us.apache.org/repos/asf/cassandra/blob/1681c18c/src/java/org/apache/cassandra/transport/Frame.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/transport/Frame.java b/src/java/org/apache/cassandra/transport/Frame.java index 04cc95e..363ff76 100644 --- a/src/java/org/apache/cassandra/transport/Frame.java +++ b/src/java/org/apache/cassandra/transport/Frame.java @@ -162,20 +162,25 @@ public class Frame return; } - // Wait until we have the complete header - if (buffer.readableBytes() < Header.LENGTH) + int readableBytes = buffer.readableBytes(); + if (readableBytes == 0) return; int idx = buffer.readerIndex(); + // Check the first byte for the protocol version before we wait for a complete header. Protocol versions + // 1 and 2 use a shorter header, so we may never have a complete header's worth of bytes. int firstByte = buffer.getByte(idx++); Message.Direction direction = Message.Direction.extractFromVersion(firstByte); int version = firstByte & PROTOCOL_VERSION_MASK; - if (version < Server.MIN_SUPPORTED_VERSION || version > Server.CURRENT_VERSION) throw new ProtocolException(String.format("Invalid or unsupported protocol version (%d); the lowest supported version is %d and the greatest is %d", version, Server.MIN_SUPPORTED_VERSION, Server.CURRENT_VERSION)); + // Wait until we have the complete header + if (readableBytes < Header.LENGTH) + return; + int flags = buffer.getByte(idx++); int streamId = buffer.getShort(idx); http://git-wip-us.apache.org/repos/asf/cassandra/blob/1681c18c/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java b/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java index de21bb1..599087c 100644 --- a/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java +++ b/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java @@ -68,6 +68,29 @@ public class ProtocolErrorTest { } @Test + public void testInvalidProtocolVersionShortFrame() throws Exception + { + // test for CASSANDRA-11464 + Frame.Decoder dec = new Frame.Decoder(null); + + List<Object> results = new ArrayList<>(); + byte[] frame = new byte[] { + (byte) REQUEST.addToVersion(1), // direction & version + 0x00, // flags + 0x01, // stream ID + 0x09, // opcode + 0x00, 0x00, 0x00, 0x21, // body length + }; + ByteBuf buf = Unpooled.wrappedBuffer(frame); + try { + dec.decode(null, buf, results); + Assert.fail("Expected protocol error"); + } catch (ProtocolException e) { + Assert.assertTrue(e.getMessage().contains("Invalid or unsupported protocol version")); + } + } + + @Test public void testInvalidDirection() throws Exception { Frame.Decoder dec = new Frame.Decoder(null);
