github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/internal/wire/frame_parser.go (about) 1 package wire 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "reflect" 8 9 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol" 10 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qerr" 11 ) 12 13 type frameParser struct { 14 ackDelayExponent uint8 15 16 supportsDatagrams bool 17 18 version protocol.VersionNumber 19 } 20 21 // NewFrameParser creates a new frame parser. 22 func NewFrameParser(supportsDatagrams bool, v protocol.VersionNumber) FrameParser { 23 return &frameParser{ 24 supportsDatagrams: supportsDatagrams, 25 version: v, 26 } 27 } 28 29 // ParseNext parses the next frame. 30 // It skips PADDING frames. 31 func (p *frameParser) ParseNext(r *bytes.Reader, encLevel protocol.EncryptionLevel) (Frame, error) { 32 for r.Len() != 0 { 33 typeByte, _ := r.ReadByte() 34 if typeByte == 0x0 { // PADDING frame 35 continue 36 } 37 r.UnreadByte() 38 39 f, err := p.parseFrame(r, typeByte, encLevel) 40 if err != nil { 41 return nil, &qerr.TransportError{ 42 FrameType: uint64(typeByte), 43 ErrorCode: qerr.FrameEncodingError, 44 ErrorMessage: err.Error(), 45 } 46 } 47 return f, nil 48 } 49 return nil, nil 50 } 51 52 func (p *frameParser) parseFrame(r *bytes.Reader, typeByte byte, encLevel protocol.EncryptionLevel) (Frame, error) { 53 var frame Frame 54 var err error 55 if typeByte&0xf8 == 0x8 { 56 frame, err = parseStreamFrame(r, p.version) 57 } else { 58 switch typeByte { 59 case 0x1: 60 frame, err = parsePingFrame(r, p.version) 61 case 0x2, 0x3: 62 ackDelayExponent := p.ackDelayExponent 63 if encLevel != protocol.Encryption1RTT { 64 ackDelayExponent = protocol.DefaultAckDelayExponent 65 } 66 frame, err = parseAckFrame(r, ackDelayExponent, p.version) 67 case 0x4: 68 frame, err = parseResetStreamFrame(r, p.version) 69 case 0x5: 70 frame, err = parseStopSendingFrame(r, p.version) 71 case 0x6: 72 frame, err = parseCryptoFrame(r, p.version) 73 case 0x7: 74 frame, err = parseNewTokenFrame(r, p.version) 75 case 0x10: 76 frame, err = parseMaxDataFrame(r, p.version) 77 case 0x11: 78 frame, err = parseMaxStreamDataFrame(r, p.version) 79 case 0x12, 0x13: 80 frame, err = parseMaxStreamsFrame(r, p.version) 81 case 0x14: 82 frame, err = parseDataBlockedFrame(r, p.version) 83 case 0x15: 84 frame, err = parseStreamDataBlockedFrame(r, p.version) 85 case 0x16, 0x17: 86 frame, err = parseStreamsBlockedFrame(r, p.version) 87 case 0x18: 88 frame, err = parseNewConnectionIDFrame(r, p.version) 89 case 0x19: 90 frame, err = parseRetireConnectionIDFrame(r, p.version) 91 case 0x1a: 92 frame, err = parsePathChallengeFrame(r, p.version) 93 case 0x1b: 94 frame, err = parsePathResponseFrame(r, p.version) 95 case 0x1c, 0x1d: 96 frame, err = parseConnectionCloseFrame(r, p.version) 97 case 0x1e: 98 frame, err = parseHandshakeDoneFrame(r, p.version) 99 case 0x30, 0x31: 100 if p.supportsDatagrams { 101 frame, err = parseDatagramFrame(r, p.version) 102 break 103 } 104 fallthrough 105 default: 106 err = errors.New("unknown frame type") 107 } 108 } 109 if err != nil { 110 return nil, err 111 } 112 if !p.isAllowedAtEncLevel(frame, encLevel) { 113 return nil, fmt.Errorf("%s not allowed at encryption level %s", reflect.TypeOf(frame).Elem().Name(), encLevel) 114 } 115 return frame, nil 116 } 117 118 func (p *frameParser) isAllowedAtEncLevel(f Frame, encLevel protocol.EncryptionLevel) bool { 119 switch encLevel { 120 case protocol.EncryptionInitial, protocol.EncryptionHandshake: 121 switch f.(type) { 122 case *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *PingFrame: 123 return true 124 default: 125 return false 126 } 127 case protocol.Encryption0RTT: 128 switch f.(type) { 129 case *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *NewTokenFrame, *PathResponseFrame, *RetireConnectionIDFrame: 130 return false 131 default: 132 return true 133 } 134 case protocol.Encryption1RTT: 135 return true 136 default: 137 panic("unknown encryption level") 138 } 139 } 140 141 func (p *frameParser) SetAckDelayExponent(exp uint8) { 142 p.ackDelayExponent = exp 143 }