forked from quic-go/quic-go
http3: reject reserved frame types (#4467)
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"github.com/quic-go/quic-go/quicvarint"
|
||||
)
|
||||
|
||||
@@ -18,13 +19,19 @@ type frame interface{}
|
||||
|
||||
var errHijacked = errors.New("hijacked")
|
||||
|
||||
func parseNextFrame(r io.Reader, unknownFrameHandler unknownFrameHandlerFunc) (frame, error) {
|
||||
qr := quicvarint.NewReader(r)
|
||||
type frameParser struct {
|
||||
r io.Reader
|
||||
conn quic.Connection
|
||||
unknownFrameHandler unknownFrameHandlerFunc
|
||||
}
|
||||
|
||||
func (p *frameParser) ParseNext() (frame, error) {
|
||||
qr := quicvarint.NewReader(p.r)
|
||||
for {
|
||||
t, err := quicvarint.Read(qr)
|
||||
if err != nil {
|
||||
if unknownFrameHandler != nil {
|
||||
hijacked, err := unknownFrameHandler(0, err)
|
||||
if p.unknownFrameHandler != nil {
|
||||
hijacked, err := p.unknownFrameHandler(0, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -35,8 +42,8 @@ func parseNextFrame(r io.Reader, unknownFrameHandler unknownFrameHandlerFunc) (f
|
||||
return nil, err
|
||||
}
|
||||
// Call the unknownFrameHandler for frames not defined in the HTTP/3 spec
|
||||
if t > 0xd && unknownFrameHandler != nil {
|
||||
hijacked, err := unknownFrameHandler(FrameType(t), nil)
|
||||
if t > 0xd && p.unknownFrameHandler != nil {
|
||||
hijacked, err := p.unknownFrameHandler(FrameType(t), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -56,11 +63,14 @@ func parseNextFrame(r io.Reader, unknownFrameHandler unknownFrameHandlerFunc) (f
|
||||
case 0x1:
|
||||
return &headersFrame{Length: l}, nil
|
||||
case 0x4:
|
||||
return parseSettingsFrame(r, l)
|
||||
return parseSettingsFrame(p.r, l)
|
||||
case 0x3: // CANCEL_PUSH
|
||||
case 0x5: // PUSH_PROMISE
|
||||
case 0x7: // GOAWAY
|
||||
case 0xd: // MAX_PUSH_ID
|
||||
case 0x2, 0x6, 0x8, 0x9:
|
||||
p.conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "")
|
||||
return nil, fmt.Errorf("http3: reserved frame type: %d", t)
|
||||
}
|
||||
// skip over unknown frames
|
||||
if _, err := io.CopyN(io.Discard, qr, int64(l)); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user