From 7a0282cb4646bdfe942f3e89f4a2903a750f4e4a Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Mon, 2 Nov 2015 18:42:36 +0900 Subject: [PATCH] Reject the first SETTINGS ack on HTTP/2 Preface Motivation: Http2ConnectionHandler verifies if the first frame after the preface is a SETTINGS frame. However, it does not reject the SETTING ack frame which is not expected actually. Modifications: Reject a SETTINGS-ack frame as well Result: When the first frame is a SETTINGS-ack frame, connection does not proceed to further frame handling. (simplicity) --- .../codec/http2/Http2ConnectionHandler.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java index 9ffc48ed5b..6ce20ba42f 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java @@ -462,23 +462,24 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http } /** - * Peeks at that the next frame in the buffer and verifies that it is a {@code SETTINGS} frame. + * Peeks at that the next frame in the buffer and verifies that it is a non-ack {@code SETTINGS} frame. * * @param in the inbound buffer. - * @return {@code} true if the next frame is a {@code SETTINGS} frame, {@code false} if more + * @return {@code} true if the next frame is a non-ack {@code SETTINGS} frame, {@code false} if more * data is required before we can determine the next frame type. - * @throws Http2Exception thrown if the next frame is NOT a {@code SETTINGS} frame. + * @throws Http2Exception thrown if the next frame is NOT a non-ack {@code SETTINGS} frame. */ private boolean verifyFirstFrameIsSettings(ByteBuf in) throws Http2Exception { - if (in.readableBytes() < 4) { + if (in.readableBytes() < 5) { // Need more data before we can see the frame type for the first frame. return false; } - byte frameType = in.getByte(in.readerIndex() + 3); - if (frameType != SETTINGS) { + short frameType = in.getUnsignedByte(in.readerIndex() + 3); + short flags = in.getUnsignedByte(in.readerIndex() + 4); + if (frameType != SETTINGS || (flags & Http2Flags.ACK) != 0) { throw connectionError(PROTOCOL_ERROR, "First received frame was not SETTINGS. " + - "Hex dump for first 4 bytes: %s", hexDump(in, in.readerIndex(), 4)); + "Hex dump for first 5 bytes: %s", hexDump(in, in.readerIndex(), 5)); } return true; }