From 7f416a06c4cb0a5f7ba055da55bc0d9e7fd75193 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 15 Mar 2017 11:11:38 +0700 Subject: [PATCH] send a HeadersStreamDataDecompressFailure error when H2 frame parsing fails fixes #479 --- h2quic/client.go | 2 +- h2quic/client_test.go | 2 +- h2quic/server.go | 4 ++-- h2quic/server_test.go | 2 +- qerr/error_codes.go | 3 +++ qerr/errorcode_string.go | 6 +++++- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/h2quic/client.go b/h2quic/client.go index c712915a..2fb698cf 100644 --- a/h2quic/client.go +++ b/h2quic/client.go @@ -110,7 +110,7 @@ func (c *Client) handleHeaderStream() { for { frame, err := h2framer.ReadFrame() if err != nil { - c.headerErr = qerr.Error(qerr.InvalidStreamData, "cannot read frame") + c.headerErr = qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame") break } lastStream = protocol.StreamID(frame.Header().StreamID) diff --git a/h2quic/client_test.go b/h2quic/client_test.go index c2eeaae0..3c2c00ed 100644 --- a/h2quic/client_test.go +++ b/h2quic/client_test.go @@ -175,7 +175,7 @@ var _ = Describe("Client", func() { client.handleHeaderStream() Eventually(func() bool { return doReturned }).Should(BeTrue()) - Expect(client.headerErr).To(HaveOccurred()) + Expect(client.headerErr).To(MatchError(qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame"))) Expect(doErr).To(MatchError(client.headerErr)) Expect(doRsp).To(BeNil()) Expect(client.session.(*mockSession).closedWithError).To(MatchError(client.headerErr)) diff --git a/h2quic/server.go b/h2quic/server.go index 09f4dacd..1da8c3a0 100644 --- a/h2quic/server.go +++ b/h2quic/server.go @@ -128,7 +128,7 @@ func (s *Server) handleHeaderStream(session streamCreator) { if _, ok := err.(*qerr.QuicError); !ok { utils.Errorf("error handling h2 request: %s", err.Error()) } - session.Close(qerr.Error(qerr.InvalidHeadersStreamData, err.Error())) + session.Close(err) return } } @@ -138,7 +138,7 @@ func (s *Server) handleHeaderStream(session streamCreator) { func (s *Server) handleRequest(session streamCreator, headerStream quic.Stream, headerStreamMutex *sync.Mutex, hpackDecoder *hpack.Decoder, h2framer *http2.Framer) error { h2frame, err := h2framer.ReadFrame() if err != nil { - return err + return qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame") } h2headersFrame, ok := h2frame.(*http2.HeadersFrame) if !ok { diff --git a/h2quic/server_test.go b/h2quic/server_test.go index e2c99a8f..209b2e89 100644 --- a/h2quic/server_test.go +++ b/h2quic/server_test.go @@ -266,7 +266,7 @@ var _ = Describe("H2 server", func() { go s.handleHeaderStream(session) Consistently(func() bool { return handlerCalled }).Should(BeFalse()) Eventually(func() bool { return session.closed }).Should(BeTrue()) - Expect(session.closedWithError).To(MatchError(qerr.Error(qerr.InvalidHeadersStreamData, "connection error: PROTOCOL_ERROR"))) + Expect(session.closedWithError).To(MatchError(qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame"))) }) It("errors if the accepted header stream has the wrong stream ID", func() { diff --git a/qerr/error_codes.go b/qerr/error_codes.go index 4797530b..f3e6dd9c 100644 --- a/qerr/error_codes.go +++ b/qerr/error_codes.go @@ -89,6 +89,9 @@ const ( EmptyStreamFrameNoFin ErrorCode = 50 // We received invalid data on the headers stream. InvalidHeadersStreamData ErrorCode = 56 + // Invalid data on the headers stream received because of decompression + // failure. + HeadersStreamDataDecompressFailure ErrorCode = 97 // The peer received too much data, violating flow control. FlowControlReceivedTooMuchData ErrorCode = 59 // The peer sent too much data, violating flow control. diff --git a/qerr/errorcode_string.go b/qerr/errorcode_string.go index aadd6576..5a8e0240 100644 --- a/qerr/errorcode_string.go +++ b/qerr/errorcode_string.go @@ -10,6 +10,7 @@ const ( _ErrorCode_name_2 = "InvalidHeaderIDInvalidNegotiatedValueDecompressionFailureNetworkIdleTimeoutErrorMigratingAddressPacketWriteErrorHandshakeFailedCryptoTagsOutOfOrderCryptoTooManyEntriesCryptoInvalidValueLengthCryptoMessageAfterHandshakeCompleteInvalidCryptoMessageTypeInvalidCryptoMessageParameterCryptoMessageParameterNotFoundCryptoMessageParameterNoOverlapCryptoMessageIndexNotFoundCryptoInternalErrorCryptoVersionNotSupportedCryptoNoSupportCryptoTooManyRejectsProofInvalidCryptoDuplicateTagCryptoEncryptionLevelIncorrectCryptoServerConfigExpiredInvalidStreamData" _ErrorCode_name_3 = "MissingPayloadInvalidPriorityEmptyStreamFrameNoFinPacketReadErrorInvalidChannelIDSignatureCryptoSymmetricKeySetupFailedCryptoMessageWhileValidatingClientHelloVersionNegotiationMismatchInvalidHeadersStreamDataInvalidWindowUpdateDataInvalidBlockedDataFlowControlReceivedTooMuchDataInvalidStopWaitingDataUnencryptedStreamDataConnectionIPPooledFlowControlSentTooMuchDataFlowControlInvalidWindowCryptoUpdateBeforeHandshakeComplete" _ErrorCode_name_4 = "HandshakeTimeoutTooManyOutstandingSentPacketsTooManyOutstandingReceivedPacketsConnectionCancelledBadPacketLossRateCryptoHandshakeStatelessRejectPublicResetsPostHandshakeTimeoutsWithOpenStreamsFailedToSerializePacketTooManyAvailableStreamsUnencryptedFecDataInvalidPathCloseDataBadMultipathFlagIPAddressChangedConnectionMigrationNoMigratableStreamsConnectionMigrationTooManyChangesConnectionMigrationNoNewNetworkConnectionMigrationNonMigratableStreamTooManyRtosErrorMigratingPortOverlappingStreamDataAttemptToSendUnencryptedStreamData" + _ErrorCode_name_5 = "HeadersStreamDataDecompressFailure" ) var ( @@ -18,12 +19,13 @@ var ( _ErrorCode_index_2 = [...]uint16{0, 15, 37, 57, 75, 96, 112, 127, 147, 167, 191, 226, 250, 279, 309, 340, 366, 385, 410, 425, 445, 457, 475, 505, 530, 547} _ErrorCode_index_3 = [...]uint16{0, 14, 29, 50, 65, 90, 119, 158, 184, 208, 231, 249, 279, 301, 322, 340, 366, 390, 425} _ErrorCode_index_4 = [...]uint16{0, 16, 45, 78, 97, 114, 144, 169, 192, 215, 238, 256, 276, 292, 308, 346, 379, 410, 448, 459, 477, 498, 532} + _ErrorCode_index_5 = [...]uint8{0, 34} ) func (i ErrorCode) String() string { switch { case 1 <= i && i <= 14: - i-- + i -= 1 return _ErrorCode_name_0[_ErrorCode_index_0[i]:_ErrorCode_index_0[i+1]] case 16 <= i && i <= 20: i -= 16 @@ -37,6 +39,8 @@ func (i ErrorCode) String() string { case 67 <= i && i <= 88: i -= 67 return _ErrorCode_name_4[_ErrorCode_index_4[i]:_ErrorCode_index_4[i+1]] + case i == 97: + return _ErrorCode_name_5 default: return fmt.Sprintf("ErrorCode(%d)", i) }