Repository: cassandra Updated Branches: refs/heads/cassandra-2.2 30be921d4 -> 05253cc28
Fix error response to unsupported protocol version Patch by Tyler Hobbs; reviewed by Stefania Alborghetti for CASSANDRA-9451 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/b3177f15 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/b3177f15 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/b3177f15 Branch: refs/heads/cassandra-2.2 Commit: b3177f15aed1d60ec3cc6166133102f86a795844 Parents: be3e389 Author: Tyler Hobbs <[email protected]> Authored: Thu Jun 4 10:16:19 2015 -0500 Committer: Tyler Hobbs <[email protected]> Committed: Thu Jun 4 10:16:19 2015 -0500 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ .../org/apache/cassandra/transport/Frame.java | 4 ++- .../transport/messages/ErrorMessage.java | 13 +++++++-- .../cassandra/transport/ProtocolErrorTest.java | 30 ++++++++++++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/b3177f15/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index f5f9862..eea1640 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,6 @@ 2.1.6 + * Use ProtocolError code instead of ServerError code for native protocol + error responses to unsupported protocol versions (CASSANDRA-9451) * Default commitlog_sync_batch_window_in_ms changed to 2ms (CASSANDRA-9504) * Fix empty partition assertion in unsorted sstable writing tools (CASSANDRA-9071) * Ensure truncate without snapshot cannot produce corrupt responses (CASSANDRA-9388) http://git-wip-us.apache.org/repos/asf/cassandra/blob/b3177f15/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 2868ed4..f5c3834 100644 --- a/src/java/org/apache/cassandra/transport/Frame.java +++ b/src/java/org/apache/cassandra/transport/Frame.java @@ -34,6 +34,8 @@ import org.apache.cassandra.transport.messages.ErrorMessage; public class Frame { + public static final byte PROTOCOL_VERSION_MASK = 0x7f; + public final Header header; public final ByteBuf body; @@ -178,7 +180,7 @@ public class Frame int firstByte = buffer.getByte(idx++); Message.Direction direction = Message.Direction.extractFromVersion(firstByte); - int version = firstByte & 0x7F; + int version = firstByte & PROTOCOL_VERSION_MASK; if (version > Server.CURRENT_VERSION) throw new ProtocolException("Invalid or unsupported protocol version: " + version); http://git-wip-us.apache.org/repos/asf/cassandra/blob/b3177f15/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java b/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java index a049a57..01c0e2e 100644 --- a/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java +++ b/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java @@ -224,10 +224,17 @@ public class ErrorMessage extends Message.Response if (e instanceof CodecException) { Throwable cause = e.getCause(); - if (cause != null && cause instanceof WrappedException) + if (cause != null) { - streamId = ((WrappedException)cause).streamId; - e = cause.getCause(); + if (cause instanceof WrappedException) + { + streamId = ((WrappedException) cause).streamId; + e = cause.getCause(); + } + else if (cause instanceof TransportException) + { + e = cause; + } } } else if (e instanceof WrappedException) http://git-wip-us.apache.org/repos/asf/cassandra/blob/b3177f15/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 91f7355..9910167 100644 --- a/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java +++ b/test/unit/org/apache/cassandra/transport/ProtocolErrorTest.java @@ -29,6 +29,33 @@ import java.util.List; public class ProtocolErrorTest { @Test + public void testInvalidProtocolVersion() throws Exception + { + Frame.Decoder dec = new Frame.Decoder(null); + + List<Object> results = new ArrayList<>(); + // should generate a protocol exception for using a protocol version higher than the current version + byte[] frame = new byte[] { + (byte) ((Server.CURRENT_VERSION + 1) & Frame.PROTOCOL_VERSION_MASK), // direction & version + 0x00, // flags + 0x01, // stream ID + 0x09, // opcode + 0x00, 0x00, 0x00, 0x21, // body length + 0x00, 0x00, 0x00, 0x1b, 0x00, 0x1b, 0x53, 0x45, + 0x4c, 0x45, 0x43, 0x54, 0x20, 0x2a, 0x20, 0x46, + 0x52, 0x4f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x3b + }; + ByteBuf buf = Unpooled.wrappedBuffer(frame); + try { + dec.decode(null, buf, results); + Assert.fail("Expected protocol error"); + } catch (ProtocolException e) { + } + } + + @Test public void testInvalidDirection() throws Exception { Frame.Decoder dec = new Frame.Decoder(null); @@ -51,6 +78,7 @@ public class ProtocolErrorTest { ByteBuf buf = Unpooled.wrappedBuffer(frame); try { dec.decode(null, buf, results); + Assert.fail("Expected protocol error"); } catch (ErrorMessage.WrappedException e) { // make sure the exception has the correct stream ID Assert.assertEquals(1, e.getStreamId()); @@ -73,6 +101,7 @@ public class ProtocolErrorTest { ByteBuf buf = Unpooled.wrappedBuffer(frame); try { dec.decode(null, buf, results); + Assert.fail("Expected protocol error"); } catch (ErrorMessage.WrappedException e) { // make sure the exception has the correct stream ID Assert.assertEquals(1, e.getStreamId()); @@ -95,6 +124,7 @@ public class ProtocolErrorTest { ByteBuf buf = Unpooled.wrappedBuffer(frame); try { dec.decode(null, buf, results); + Assert.fail("Expected protocol error"); } catch (ErrorMessage.WrappedException e) { // make sure the exception has the correct stream ID Assert.assertEquals(1, e.getStreamId());
