github.com/tumi8/quic-go@v0.37.4-tum/noninternal/wire/frame_parser_test.go (about) 1 package wire 2 3 import ( 4 "time" 5 6 "github.com/tumi8/quic-go/noninternal/protocol" 7 "github.com/tumi8/quic-go/noninternal/qerr" 8 . "github.com/onsi/ginkgo/v2" 9 . "github.com/onsi/gomega" 10 ) 11 12 var _ = Describe("Frame parsing", func() { 13 var parser FrameParser 14 15 BeforeEach(func() { 16 parser = NewFrameParser(true) 17 }) 18 19 It("returns nil if there's nothing more to read", func() { 20 l, f, err := parser.ParseNext(nil, protocol.Encryption1RTT, protocol.Version1) 21 Expect(err).ToNot(HaveOccurred()) 22 Expect(l).To(BeZero()) 23 Expect(f).To(BeNil()) 24 }) 25 26 It("skips PADDING frames", func() { 27 b := []byte{0, 0} // 2 PADDING frames 28 b, err := (&PingFrame{}).Append(b, protocol.Version1) 29 Expect(err).ToNot(HaveOccurred()) 30 l, f, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 31 Expect(err).ToNot(HaveOccurred()) 32 Expect(f).To(Equal(&PingFrame{})) 33 Expect(l).To(Equal(2 + 1)) 34 }) 35 36 It("handles PADDING at the end", func() { 37 l, f, err := parser.ParseNext([]byte{0, 0, 0}, protocol.Encryption1RTT, protocol.Version1) 38 Expect(err).ToNot(HaveOccurred()) 39 Expect(f).To(BeNil()) 40 Expect(l).To(Equal(3)) 41 }) 42 43 It("parses a single frame", func() { 44 var b []byte 45 for i := 0; i < 10; i++ { 46 var err error 47 b, err = (&PingFrame{}).Append(b, protocol.Version1) 48 Expect(err).ToNot(HaveOccurred()) 49 } 50 l, f, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 51 Expect(err).ToNot(HaveOccurred()) 52 Expect(f).To(BeAssignableToTypeOf(&PingFrame{})) 53 Expect(l).To(Equal(1)) 54 }) 55 56 It("unpacks ACK frames", func() { 57 f := &AckFrame{AckRanges: []AckRange{{Smallest: 1, Largest: 0x13}}} 58 b, err := f.Append(nil, protocol.Version1) 59 Expect(err).ToNot(HaveOccurred()) 60 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 61 Expect(err).ToNot(HaveOccurred()) 62 Expect(frame).ToNot(BeNil()) 63 Expect(frame).To(BeAssignableToTypeOf(f)) 64 Expect(frame.(*AckFrame).LargestAcked()).To(Equal(protocol.PacketNumber(0x13))) 65 Expect(l).To(Equal(len(b))) 66 }) 67 68 It("uses the custom ack delay exponent for 1RTT packets", func() { 69 parser.SetAckDelayExponent(protocol.AckDelayExponent + 2) 70 f := &AckFrame{ 71 AckRanges: []AckRange{{Smallest: 1, Largest: 1}}, 72 DelayTime: time.Second, 73 } 74 b, err := f.Append(nil, protocol.Version1) 75 Expect(err).ToNot(HaveOccurred()) 76 _, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 77 Expect(err).ToNot(HaveOccurred()) 78 // The ACK frame is always written using the protocol.AckDelayExponent. 79 // That's why we expect a different value when parsing. 80 Expect(frame.(*AckFrame).DelayTime).To(Equal(4 * time.Second)) 81 }) 82 83 It("uses the default ack delay exponent for non-1RTT packets", func() { 84 parser.SetAckDelayExponent(protocol.AckDelayExponent + 2) 85 f := &AckFrame{ 86 AckRanges: []AckRange{{Smallest: 1, Largest: 1}}, 87 DelayTime: time.Second, 88 } 89 b, err := f.Append(nil, protocol.Version1) 90 Expect(err).ToNot(HaveOccurred()) 91 _, frame, err := parser.ParseNext(b, protocol.EncryptionHandshake, protocol.Version1) 92 Expect(err).ToNot(HaveOccurred()) 93 Expect(frame.(*AckFrame).DelayTime).To(Equal(time.Second)) 94 }) 95 96 It("unpacks RESET_STREAM frames", func() { 97 f := &ResetStreamFrame{ 98 StreamID: 0xdeadbeef, 99 FinalSize: 0xdecafbad1234, 100 ErrorCode: 0x1337, 101 } 102 b, err := f.Append(nil, protocol.Version1) 103 Expect(err).ToNot(HaveOccurred()) 104 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 105 Expect(err).ToNot(HaveOccurred()) 106 Expect(frame).To(Equal(f)) 107 Expect(l).To(Equal(len(b))) 108 }) 109 110 It("unpacks STOP_SENDING frames", func() { 111 f := &StopSendingFrame{StreamID: 0x42} 112 b, err := f.Append(nil, protocol.Version1) 113 Expect(err).ToNot(HaveOccurred()) 114 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 115 Expect(err).ToNot(HaveOccurred()) 116 Expect(frame).To(Equal(f)) 117 Expect(l).To(Equal(len(b))) 118 }) 119 120 It("unpacks CRYPTO frames", func() { 121 f := &CryptoFrame{ 122 Offset: 0x1337, 123 Data: []byte("lorem ipsum"), 124 } 125 b, err := f.Append(nil, protocol.Version1) 126 Expect(err).ToNot(HaveOccurred()) 127 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 128 Expect(err).ToNot(HaveOccurred()) 129 Expect(frame).ToNot(BeNil()) 130 Expect(frame).To(Equal(f)) 131 Expect(l).To(Equal(len(b))) 132 }) 133 134 It("unpacks NEW_TOKEN frames", func() { 135 f := &NewTokenFrame{Token: []byte("foobar")} 136 b, err := f.Append(nil, protocol.Version1) 137 Expect(err).ToNot(HaveOccurred()) 138 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 139 Expect(err).ToNot(HaveOccurred()) 140 Expect(frame).ToNot(BeNil()) 141 Expect(frame).To(Equal(f)) 142 Expect(l).To(Equal(len(b))) 143 }) 144 145 It("unpacks STREAM frames", func() { 146 f := &StreamFrame{ 147 StreamID: 0x42, 148 Offset: 0x1337, 149 Fin: true, 150 Data: []byte("foobar"), 151 } 152 b, err := f.Append(nil, protocol.Version1) 153 Expect(err).ToNot(HaveOccurred()) 154 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 155 Expect(err).ToNot(HaveOccurred()) 156 Expect(frame).ToNot(BeNil()) 157 Expect(frame).To(Equal(f)) 158 Expect(l).To(Equal(len(b))) 159 }) 160 161 It("unpacks MAX_DATA frames", func() { 162 f := &MaxDataFrame{ 163 MaximumData: 0xcafe, 164 } 165 b, err := f.Append(nil, protocol.Version1) 166 Expect(err).ToNot(HaveOccurred()) 167 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 168 Expect(err).ToNot(HaveOccurred()) 169 Expect(frame).To(Equal(f)) 170 Expect(l).To(Equal(len(b))) 171 }) 172 173 It("unpacks MAX_STREAM_DATA frames", func() { 174 f := &MaxStreamDataFrame{ 175 StreamID: 0xdeadbeef, 176 MaximumStreamData: 0xdecafbad, 177 } 178 b, err := f.Append(nil, protocol.Version1) 179 Expect(err).ToNot(HaveOccurred()) 180 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 181 Expect(err).ToNot(HaveOccurred()) 182 Expect(frame).To(Equal(f)) 183 Expect(l).To(Equal(len(b))) 184 }) 185 186 It("unpacks MAX_STREAMS frames", func() { 187 f := &MaxStreamsFrame{ 188 Type: protocol.StreamTypeBidi, 189 MaxStreamNum: 0x1337, 190 } 191 b, err := f.Append(nil, protocol.Version1) 192 Expect(err).ToNot(HaveOccurred()) 193 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 194 Expect(err).ToNot(HaveOccurred()) 195 Expect(frame).To(Equal(f)) 196 Expect(l).To(Equal(len(b))) 197 }) 198 199 It("unpacks DATA_BLOCKED frames", func() { 200 f := &DataBlockedFrame{MaximumData: 0x1234} 201 b, err := f.Append(nil, protocol.Version1) 202 Expect(err).ToNot(HaveOccurred()) 203 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 204 Expect(err).ToNot(HaveOccurred()) 205 Expect(frame).To(Equal(f)) 206 Expect(l).To(Equal(len(b))) 207 }) 208 209 It("unpacks STREAM_DATA_BLOCKED frames", func() { 210 f := &StreamDataBlockedFrame{ 211 StreamID: 0xdeadbeef, 212 MaximumStreamData: 0xdead, 213 } 214 b, err := f.Append(nil, protocol.Version1) 215 Expect(err).ToNot(HaveOccurred()) 216 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 217 Expect(err).ToNot(HaveOccurred()) 218 Expect(frame).To(Equal(f)) 219 Expect(l).To(Equal(len(b))) 220 }) 221 222 It("unpacks STREAMS_BLOCKED frames", func() { 223 f := &StreamsBlockedFrame{ 224 Type: protocol.StreamTypeBidi, 225 StreamLimit: 0x1234567, 226 } 227 b, err := f.Append(nil, protocol.Version1) 228 Expect(err).ToNot(HaveOccurred()) 229 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 230 Expect(err).ToNot(HaveOccurred()) 231 Expect(frame).To(Equal(f)) 232 Expect(l).To(Equal(len(b))) 233 }) 234 235 It("unpacks NEW_CONNECTION_ID frames", func() { 236 f := &NewConnectionIDFrame{ 237 SequenceNumber: 0x1337, 238 ConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}), 239 StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 240 } 241 b, err := f.Append(nil, protocol.Version1) 242 Expect(err).ToNot(HaveOccurred()) 243 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 244 Expect(err).ToNot(HaveOccurred()) 245 Expect(frame).To(Equal(f)) 246 Expect(l).To(Equal(len(b))) 247 }) 248 249 It("unpacks RETIRE_CONNECTION_ID frames", func() { 250 f := &RetireConnectionIDFrame{SequenceNumber: 0x1337} 251 b, err := f.Append(nil, protocol.Version1) 252 Expect(err).ToNot(HaveOccurred()) 253 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 254 Expect(err).ToNot(HaveOccurred()) 255 Expect(frame).To(Equal(f)) 256 Expect(l).To(Equal(len(b))) 257 }) 258 259 It("unpacks PATH_CHALLENGE frames", func() { 260 f := &PathChallengeFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}} 261 b, err := f.Append(nil, protocol.Version1) 262 Expect(err).ToNot(HaveOccurred()) 263 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 264 Expect(err).ToNot(HaveOccurred()) 265 Expect(frame).ToNot(BeNil()) 266 Expect(frame).To(BeAssignableToTypeOf(f)) 267 Expect(frame.(*PathChallengeFrame).Data).To(Equal([8]byte{1, 2, 3, 4, 5, 6, 7, 8})) 268 Expect(l).To(Equal(len(b))) 269 }) 270 271 It("unpacks PATH_RESPONSE frames", func() { 272 f := &PathResponseFrame{Data: [8]byte{1, 2, 3, 4, 5, 6, 7, 8}} 273 b, err := f.Append(nil, protocol.Version1) 274 Expect(err).ToNot(HaveOccurred()) 275 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 276 Expect(err).ToNot(HaveOccurred()) 277 Expect(frame).ToNot(BeNil()) 278 Expect(frame).To(BeAssignableToTypeOf(f)) 279 Expect(frame.(*PathResponseFrame).Data).To(Equal([8]byte{1, 2, 3, 4, 5, 6, 7, 8})) 280 Expect(l).To(Equal(len(b))) 281 }) 282 283 It("unpacks CONNECTION_CLOSE frames", func() { 284 f := &ConnectionCloseFrame{ 285 IsApplicationError: true, 286 ReasonPhrase: "foobar", 287 } 288 b, err := f.Append(nil, protocol.Version1) 289 Expect(err).ToNot(HaveOccurred()) 290 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 291 Expect(err).ToNot(HaveOccurred()) 292 Expect(frame).To(Equal(f)) 293 Expect(l).To(Equal(len(b))) 294 }) 295 296 It("unpacks HANDSHAKE_DONE frames", func() { 297 f := &HandshakeDoneFrame{} 298 b, err := f.Append(nil, protocol.Version1) 299 Expect(err).ToNot(HaveOccurred()) 300 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 301 Expect(err).ToNot(HaveOccurred()) 302 Expect(frame).To(Equal(f)) 303 Expect(l).To(Equal(len(b))) 304 }) 305 306 It("unpacks DATAGRAM frames", func() { 307 f := &DatagramFrame{Data: []byte("foobar")} 308 b, err := f.Append(nil, protocol.Version1) 309 Expect(err).ToNot(HaveOccurred()) 310 l, frame, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 311 Expect(err).ToNot(HaveOccurred()) 312 Expect(frame).To(Equal(f)) 313 Expect(l).To(Equal(len(b))) 314 }) 315 316 It("errors when DATAGRAM frames are not supported", func() { 317 parser = NewFrameParser(false) 318 f := &DatagramFrame{Data: []byte("foobar")} 319 b, err := f.Append(nil, protocol.Version1) 320 Expect(err).ToNot(HaveOccurred()) 321 _, _, err = parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 322 Expect(err).To(MatchError(&qerr.TransportError{ 323 ErrorCode: qerr.FrameEncodingError, 324 FrameType: 0x30, 325 ErrorMessage: "unknown frame type", 326 })) 327 }) 328 329 It("errors on invalid type", func() { 330 _, _, err := parser.ParseNext(encodeVarInt(0x42), protocol.Encryption1RTT, protocol.Version1) 331 Expect(err).To(MatchError(&qerr.TransportError{ 332 ErrorCode: qerr.FrameEncodingError, 333 FrameType: 0x42, 334 ErrorMessage: "unknown frame type", 335 })) 336 }) 337 338 It("errors on invalid frames", func() { 339 f := &MaxStreamDataFrame{ 340 StreamID: 0x1337, 341 MaximumStreamData: 0xdeadbeef, 342 } 343 b, err := f.Append(nil, protocol.Version1) 344 Expect(err).ToNot(HaveOccurred()) 345 _, _, err = parser.ParseNext(b[:len(b)-2], protocol.Encryption1RTT, protocol.Version1) 346 Expect(err).To(HaveOccurred()) 347 Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.FrameEncodingError)) 348 }) 349 350 Context("encryption level check", func() { 351 frames := []Frame{ 352 &PingFrame{}, 353 &AckFrame{AckRanges: []AckRange{{Smallest: 1, Largest: 42}}}, 354 &ResetStreamFrame{}, 355 &StopSendingFrame{}, 356 &CryptoFrame{}, 357 &NewTokenFrame{Token: []byte("lorem ipsum")}, 358 &StreamFrame{Data: []byte("foobar")}, 359 &MaxDataFrame{}, 360 &MaxStreamDataFrame{}, 361 &MaxStreamsFrame{}, 362 &DataBlockedFrame{}, 363 &StreamDataBlockedFrame{}, 364 &StreamsBlockedFrame{}, 365 &NewConnectionIDFrame{ConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef})}, 366 &RetireConnectionIDFrame{}, 367 &PathChallengeFrame{}, 368 &PathResponseFrame{}, 369 &ConnectionCloseFrame{}, 370 &HandshakeDoneFrame{}, 371 &DatagramFrame{}, 372 } 373 374 var framesSerialized [][]byte 375 376 BeforeEach(func() { 377 framesSerialized = nil 378 for _, frame := range frames { 379 b, err := frame.Append(nil, protocol.Version1) 380 Expect(err).ToNot(HaveOccurred()) 381 framesSerialized = append(framesSerialized, b) 382 } 383 }) 384 385 It("rejects all frames but ACK, CRYPTO, PING and CONNECTION_CLOSE in Initial packets", func() { 386 for i, b := range framesSerialized { 387 _, _, err := parser.ParseNext(b, protocol.EncryptionInitial, protocol.Version1) 388 switch frames[i].(type) { 389 case *AckFrame, *ConnectionCloseFrame, *CryptoFrame, *PingFrame: 390 Expect(err).ToNot(HaveOccurred()) 391 default: 392 Expect(err).To(BeAssignableToTypeOf(&qerr.TransportError{})) 393 Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.FrameEncodingError)) 394 Expect(err.(*qerr.TransportError).ErrorMessage).To(ContainSubstring("not allowed at encryption level Initial")) 395 } 396 } 397 }) 398 399 It("rejects all frames but ACK, CRYPTO, PING and CONNECTION_CLOSE in Handshake packets", func() { 400 for i, b := range framesSerialized { 401 _, _, err := parser.ParseNext(b, protocol.EncryptionHandshake, protocol.Version1) 402 switch frames[i].(type) { 403 case *AckFrame, *ConnectionCloseFrame, *CryptoFrame, *PingFrame: 404 Expect(err).ToNot(HaveOccurred()) 405 default: 406 Expect(err).To(BeAssignableToTypeOf(&qerr.TransportError{})) 407 Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.FrameEncodingError)) 408 Expect(err.(*qerr.TransportError).ErrorMessage).To(ContainSubstring("not allowed at encryption level Handshake")) 409 } 410 } 411 }) 412 413 It("rejects all frames but ACK, CRYPTO, CONNECTION_CLOSE, NEW_TOKEN, PATH_RESPONSE and RETIRE_CONNECTION_ID in 0-RTT packets", func() { 414 for i, b := range framesSerialized { 415 _, _, err := parser.ParseNext(b, protocol.Encryption0RTT, protocol.Version1) 416 switch frames[i].(type) { 417 case *AckFrame, *ConnectionCloseFrame, *CryptoFrame, *NewTokenFrame, *PathResponseFrame, *RetireConnectionIDFrame: 418 Expect(err).To(BeAssignableToTypeOf(&qerr.TransportError{})) 419 Expect(err.(*qerr.TransportError).ErrorCode).To(Equal(qerr.FrameEncodingError)) 420 Expect(err.(*qerr.TransportError).ErrorMessage).To(ContainSubstring("not allowed at encryption level 0-RTT")) 421 default: 422 Expect(err).ToNot(HaveOccurred()) 423 } 424 } 425 }) 426 427 It("accepts all frame types in 1-RTT packets", func() { 428 for _, b := range framesSerialized { 429 _, _, err := parser.ParseNext(b, protocol.Encryption1RTT, protocol.Version1) 430 Expect(err).ToNot(HaveOccurred()) 431 } 432 }) 433 }) 434 })