Merge pull request #482 from lucas-clemente/fix-479

send a HeadersStreamDataDecompressFailure error when H2 frame parsing fails
This commit is contained in:
Marten Seemann
2017-03-15 17:15:21 +07:00
committed by GitHub
6 changed files with 13 additions and 6 deletions

View File

@@ -111,7 +111,7 @@ func (c *Client) handleHeaderStream() {
for { for {
frame, err := h2framer.ReadFrame() frame, err := h2framer.ReadFrame()
if err != nil { if err != nil {
c.headerErr = qerr.Error(qerr.InvalidStreamData, "cannot read frame") c.headerErr = qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame")
break break
} }
lastStream = protocol.StreamID(frame.Header().StreamID) lastStream = protocol.StreamID(frame.Header().StreamID)

View File

@@ -182,7 +182,7 @@ var _ = Describe("Client", func() {
client.handleHeaderStream() client.handleHeaderStream()
Eventually(func() bool { return doReturned }).Should(BeTrue()) 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(doErr).To(MatchError(client.headerErr))
Expect(doRsp).To(BeNil()) Expect(doRsp).To(BeNil())
Expect(client.session.(*mockSession).closedWithError).To(MatchError(client.headerErr)) Expect(client.session.(*mockSession).closedWithError).To(MatchError(client.headerErr))

View File

@@ -128,7 +128,7 @@ func (s *Server) handleHeaderStream(session streamCreator) {
if _, ok := err.(*qerr.QuicError); !ok { if _, ok := err.(*qerr.QuicError); !ok {
utils.Errorf("error handling h2 request: %s", err.Error()) utils.Errorf("error handling h2 request: %s", err.Error())
} }
session.Close(qerr.Error(qerr.InvalidHeadersStreamData, err.Error())) session.Close(err)
return 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 { func (s *Server) handleRequest(session streamCreator, headerStream quic.Stream, headerStreamMutex *sync.Mutex, hpackDecoder *hpack.Decoder, h2framer *http2.Framer) error {
h2frame, err := h2framer.ReadFrame() h2frame, err := h2framer.ReadFrame()
if err != nil { if err != nil {
return err return qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame")
} }
h2headersFrame, ok := h2frame.(*http2.HeadersFrame) h2headersFrame, ok := h2frame.(*http2.HeadersFrame)
if !ok { if !ok {

View File

@@ -266,7 +266,7 @@ var _ = Describe("H2 server", func() {
go s.handleHeaderStream(session) go s.handleHeaderStream(session)
Consistently(func() bool { return handlerCalled }).Should(BeFalse()) Consistently(func() bool { return handlerCalled }).Should(BeFalse())
Eventually(func() bool { return session.closed }).Should(BeTrue()) 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() { It("errors if the accepted header stream has the wrong stream ID", func() {

View File

@@ -89,6 +89,9 @@ const (
EmptyStreamFrameNoFin ErrorCode = 50 EmptyStreamFrameNoFin ErrorCode = 50
// We received invalid data on the headers stream. // We received invalid data on the headers stream.
InvalidHeadersStreamData ErrorCode = 56 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. // The peer received too much data, violating flow control.
FlowControlReceivedTooMuchData ErrorCode = 59 FlowControlReceivedTooMuchData ErrorCode = 59
// The peer sent too much data, violating flow control. // The peer sent too much data, violating flow control.

View File

@@ -10,6 +10,7 @@ const (
_ErrorCode_name_2 = "InvalidHeaderIDInvalidNegotiatedValueDecompressionFailureNetworkIdleTimeoutErrorMigratingAddressPacketWriteErrorHandshakeFailedCryptoTagsOutOfOrderCryptoTooManyEntriesCryptoInvalidValueLengthCryptoMessageAfterHandshakeCompleteInvalidCryptoMessageTypeInvalidCryptoMessageParameterCryptoMessageParameterNotFoundCryptoMessageParameterNoOverlapCryptoMessageIndexNotFoundCryptoInternalErrorCryptoVersionNotSupportedCryptoNoSupportCryptoTooManyRejectsProofInvalidCryptoDuplicateTagCryptoEncryptionLevelIncorrectCryptoServerConfigExpiredInvalidStreamData" _ErrorCode_name_2 = "InvalidHeaderIDInvalidNegotiatedValueDecompressionFailureNetworkIdleTimeoutErrorMigratingAddressPacketWriteErrorHandshakeFailedCryptoTagsOutOfOrderCryptoTooManyEntriesCryptoInvalidValueLengthCryptoMessageAfterHandshakeCompleteInvalidCryptoMessageTypeInvalidCryptoMessageParameterCryptoMessageParameterNotFoundCryptoMessageParameterNoOverlapCryptoMessageIndexNotFoundCryptoInternalErrorCryptoVersionNotSupportedCryptoNoSupportCryptoTooManyRejectsProofInvalidCryptoDuplicateTagCryptoEncryptionLevelIncorrectCryptoServerConfigExpiredInvalidStreamData"
_ErrorCode_name_3 = "MissingPayloadInvalidPriorityEmptyStreamFrameNoFinPacketReadErrorInvalidChannelIDSignatureCryptoSymmetricKeySetupFailedCryptoMessageWhileValidatingClientHelloVersionNegotiationMismatchInvalidHeadersStreamDataInvalidWindowUpdateDataInvalidBlockedDataFlowControlReceivedTooMuchDataInvalidStopWaitingDataUnencryptedStreamDataConnectionIPPooledFlowControlSentTooMuchDataFlowControlInvalidWindowCryptoUpdateBeforeHandshakeComplete" _ErrorCode_name_3 = "MissingPayloadInvalidPriorityEmptyStreamFrameNoFinPacketReadErrorInvalidChannelIDSignatureCryptoSymmetricKeySetupFailedCryptoMessageWhileValidatingClientHelloVersionNegotiationMismatchInvalidHeadersStreamDataInvalidWindowUpdateDataInvalidBlockedDataFlowControlReceivedTooMuchDataInvalidStopWaitingDataUnencryptedStreamDataConnectionIPPooledFlowControlSentTooMuchDataFlowControlInvalidWindowCryptoUpdateBeforeHandshakeComplete"
_ErrorCode_name_4 = "HandshakeTimeoutTooManyOutstandingSentPacketsTooManyOutstandingReceivedPacketsConnectionCancelledBadPacketLossRateCryptoHandshakeStatelessRejectPublicResetsPostHandshakeTimeoutsWithOpenStreamsFailedToSerializePacketTooManyAvailableStreamsUnencryptedFecDataInvalidPathCloseDataBadMultipathFlagIPAddressChangedConnectionMigrationNoMigratableStreamsConnectionMigrationTooManyChangesConnectionMigrationNoNewNetworkConnectionMigrationNonMigratableStreamTooManyRtosErrorMigratingPortOverlappingStreamDataAttemptToSendUnencryptedStreamData" _ErrorCode_name_4 = "HandshakeTimeoutTooManyOutstandingSentPacketsTooManyOutstandingReceivedPacketsConnectionCancelledBadPacketLossRateCryptoHandshakeStatelessRejectPublicResetsPostHandshakeTimeoutsWithOpenStreamsFailedToSerializePacketTooManyAvailableStreamsUnencryptedFecDataInvalidPathCloseDataBadMultipathFlagIPAddressChangedConnectionMigrationNoMigratableStreamsConnectionMigrationTooManyChangesConnectionMigrationNoNewNetworkConnectionMigrationNonMigratableStreamTooManyRtosErrorMigratingPortOverlappingStreamDataAttemptToSendUnencryptedStreamData"
_ErrorCode_name_5 = "HeadersStreamDataDecompressFailure"
) )
var ( 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_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_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_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 { func (i ErrorCode) String() string {
switch { switch {
case 1 <= i && i <= 14: case 1 <= i && i <= 14:
i-- i -= 1
return _ErrorCode_name_0[_ErrorCode_index_0[i]:_ErrorCode_index_0[i+1]] return _ErrorCode_name_0[_ErrorCode_index_0[i]:_ErrorCode_index_0[i+1]]
case 16 <= i && i <= 20: case 16 <= i && i <= 20:
i -= 16 i -= 16
@@ -37,6 +39,8 @@ func (i ErrorCode) String() string {
case 67 <= i && i <= 88: case 67 <= i && i <= 88:
i -= 67 i -= 67
return _ErrorCode_name_4[_ErrorCode_index_4[i]:_ErrorCode_index_4[i+1]] return _ErrorCode_name_4[_ErrorCode_index_4[i]:_ErrorCode_index_4[i+1]]
case i == 97:
return _ErrorCode_name_5
default: default:
return fmt.Sprintf("ErrorCode(%d)", i) return fmt.Sprintf("ErrorCode(%d)", i)
} }