golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/stream_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "bytes" 11 "context" 12 "crypto/rand" 13 "errors" 14 "fmt" 15 "io" 16 "strings" 17 "testing" 18 ) 19 20 func TestStreamWriteBlockedByOutputBuffer(t *testing.T) { 21 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 22 want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 23 const writeBufferSize = 4 24 tc := newTestConn(t, clientSide, permissiveTransportParameters, func(c *Config) { 25 c.MaxStreamWriteBufferSize = writeBufferSize 26 }) 27 tc.handshake() 28 tc.ignoreFrame(frameTypeAck) 29 30 s := newLocalStream(t, tc, styp) 31 32 // Non-blocking write. 33 n, err := s.Write(want) 34 if n != writeBufferSize || err != context.Canceled { 35 t.Fatalf("s.Write() = %v, %v; want %v, context.Canceled", n, err, writeBufferSize) 36 } 37 s.Flush() 38 tc.wantFrame("first write buffer of data sent", 39 packetType1RTT, debugFrameStream{ 40 id: s.id, 41 data: want[:writeBufferSize], 42 }) 43 off := int64(writeBufferSize) 44 45 // Blocking write, which must wait for buffer space. 46 w := runAsync(tc, func(ctx context.Context) (int, error) { 47 s.SetWriteContext(ctx) 48 n, err := s.Write(want[writeBufferSize:]) 49 s.Flush() 50 return n, err 51 }) 52 tc.wantIdle("write buffer is full, no more data can be sent") 53 54 // The peer's ack of the STREAM frame allows progress. 55 tc.writeAckForAll() 56 tc.wantFrame("second write buffer of data sent", 57 packetType1RTT, debugFrameStream{ 58 id: s.id, 59 off: off, 60 data: want[off:][:writeBufferSize], 61 }) 62 off += writeBufferSize 63 tc.wantIdle("write buffer is full, no more data can be sent") 64 65 // The peer's ack of the second STREAM frame allows sending the remaining data. 66 tc.writeAckForAll() 67 tc.wantFrame("remaining data sent", 68 packetType1RTT, debugFrameStream{ 69 id: s.id, 70 off: off, 71 data: want[off:], 72 }) 73 74 if n, err := w.result(); n != len(want)-writeBufferSize || err != nil { 75 t.Fatalf("s.Write() = %v, %v; want %v, nil", 76 len(want)-writeBufferSize, err, writeBufferSize) 77 } 78 }) 79 } 80 81 func TestStreamWriteBlockedByStreamFlowControl(t *testing.T) { 82 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 83 ctx := canceledContext() 84 want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 85 tc := newTestConn(t, clientSide, func(p *transportParameters) { 86 p.initialMaxStreamsBidi = 100 87 p.initialMaxStreamsUni = 100 88 p.initialMaxData = 1 << 20 89 }) 90 tc.handshake() 91 tc.ignoreFrame(frameTypeAck) 92 93 s, err := tc.conn.newLocalStream(ctx, styp) 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 // Data is written to the stream output buffer, but we have no flow control. 99 _, err = s.Write(want[:1]) 100 if err != nil { 101 t.Fatalf("write with available output buffer: unexpected error: %v", err) 102 } 103 s.Flush() 104 tc.wantFrame("write blocked by flow control triggers a STREAM_DATA_BLOCKED frame", 105 packetType1RTT, debugFrameStreamDataBlocked{ 106 id: s.id, 107 max: 0, 108 }) 109 110 // Write more data. 111 _, err = s.Write(want[1:]) 112 if err != nil { 113 t.Fatalf("write with available output buffer: unexpected error: %v", err) 114 } 115 s.Flush() 116 tc.wantIdle("adding more blocked data does not trigger another STREAM_DATA_BLOCKED") 117 118 // Provide some flow control window. 119 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 120 id: s.id, 121 max: 4, 122 }) 123 tc.wantFrame("stream window extended, but still more data to write", 124 packetType1RTT, debugFrameStreamDataBlocked{ 125 id: s.id, 126 max: 4, 127 }) 128 tc.wantFrame("stream window extended to 4, expect blocked write to progress", 129 packetType1RTT, debugFrameStream{ 130 id: s.id, 131 data: want[:4], 132 }) 133 134 // Provide more flow control window. 135 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 136 id: s.id, 137 max: int64(len(want)), 138 }) 139 tc.wantFrame("stream window extended further, expect blocked write to finish", 140 packetType1RTT, debugFrameStream{ 141 id: s.id, 142 off: 4, 143 data: want[4:], 144 }) 145 }) 146 } 147 148 func TestStreamIgnoresMaxStreamDataReduction(t *testing.T) { 149 // "A sender MUST ignore any MAX_STREAM_DATA [...] frames that 150 // do not increase flow control limits." 151 // https://www.rfc-editor.org/rfc/rfc9000#section-4.1-9 152 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 153 ctx := canceledContext() 154 want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 155 tc := newTestConn(t, clientSide, func(p *transportParameters) { 156 if styp == uniStream { 157 p.initialMaxStreamsUni = 1 158 p.initialMaxStreamDataUni = 4 159 } else { 160 p.initialMaxStreamsBidi = 1 161 p.initialMaxStreamDataBidiRemote = 4 162 } 163 p.initialMaxData = 1 << 20 164 }) 165 tc.handshake() 166 tc.ignoreFrame(frameTypeAck) 167 tc.ignoreFrame(frameTypeStreamDataBlocked) 168 169 // Write [0,1). 170 s, err := tc.conn.newLocalStream(ctx, styp) 171 if err != nil { 172 t.Fatal(err) 173 } 174 s.Write(want[:1]) 175 s.Flush() 176 tc.wantFrame("sent data (1 byte) fits within flow control limit", 177 packetType1RTT, debugFrameStream{ 178 id: s.id, 179 off: 0, 180 data: want[:1], 181 }) 182 183 // MAX_STREAM_DATA tries to decrease limit, and is ignored. 184 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 185 id: s.id, 186 max: 2, 187 }) 188 189 // Write [1,4). 190 s.Write(want[1:]) 191 tc.wantFrame("stream limit is 4 bytes, ignoring decrease in MAX_STREAM_DATA", 192 packetType1RTT, debugFrameStream{ 193 id: s.id, 194 off: 1, 195 data: want[1:4], 196 }) 197 198 // MAX_STREAM_DATA increases limit. 199 // Second MAX_STREAM_DATA decreases it, and is ignored. 200 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 201 id: s.id, 202 max: 8, 203 }) 204 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 205 id: s.id, 206 max: 6, 207 }) 208 209 // Write [1,4). 210 s.Write(want[4:]) 211 tc.wantFrame("stream limit is 8 bytes, ignoring decrease in MAX_STREAM_DATA", 212 packetType1RTT, debugFrameStream{ 213 id: s.id, 214 off: 4, 215 data: want[4:8], 216 }) 217 }) 218 } 219 220 func TestStreamWriteBlockedByWriteBufferLimit(t *testing.T) { 221 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 222 want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 223 const maxWriteBuffer = 4 224 tc := newTestConn(t, clientSide, func(p *transportParameters) { 225 p.initialMaxStreamsBidi = 100 226 p.initialMaxStreamsUni = 100 227 p.initialMaxData = 1 << 20 228 p.initialMaxStreamDataBidiRemote = 1 << 20 229 p.initialMaxStreamDataUni = 1 << 20 230 }, func(c *Config) { 231 c.MaxStreamWriteBufferSize = maxWriteBuffer 232 }) 233 tc.handshake() 234 tc.ignoreFrame(frameTypeAck) 235 236 // Write more data than StreamWriteBufferSize. 237 // The peer has given us plenty of flow control, 238 // so we're just blocked by our local limit. 239 s := newLocalStream(t, tc, styp) 240 w := runAsync(tc, func(ctx context.Context) (int, error) { 241 s.SetWriteContext(ctx) 242 return s.Write(want) 243 }) 244 tc.wantFrame("stream write should send as much data as write buffer allows", 245 packetType1RTT, debugFrameStream{ 246 id: s.id, 247 off: 0, 248 data: want[:maxWriteBuffer], 249 }) 250 tc.wantIdle("no STREAM_DATA_BLOCKED, we're blocked locally not by flow control") 251 252 // ACK for previously-sent data allows making more progress. 253 tc.writeAckForAll() 254 tc.wantFrame("ACK for previous data allows making progress", 255 packetType1RTT, debugFrameStream{ 256 id: s.id, 257 off: maxWriteBuffer, 258 data: want[maxWriteBuffer:][:maxWriteBuffer], 259 }) 260 261 // Cancel the write with data left to send. 262 w.cancel() 263 n, err := w.result() 264 if n != 2*maxWriteBuffer || err == nil { 265 t.Fatalf("Write() = %v, %v; want %v bytes, error", n, err, 2*maxWriteBuffer) 266 } 267 }) 268 } 269 270 func TestStreamReceive(t *testing.T) { 271 // "Endpoints MUST be able to deliver stream data to an application as 272 // an ordered byte stream." 273 // https://www.rfc-editor.org/rfc/rfc9000#section-2.2-2 274 want := make([]byte, 5000) 275 for i := range want { 276 want[i] = byte(i) 277 } 278 type frame struct { 279 start int64 280 end int64 281 fin bool 282 want int 283 wantEOF bool 284 } 285 for _, test := range []struct { 286 name string 287 frames []frame 288 }{{ 289 name: "linear", 290 frames: []frame{{ 291 start: 0, 292 end: 1000, 293 want: 1000, 294 }, { 295 start: 1000, 296 end: 2000, 297 want: 2000, 298 }, { 299 start: 2000, 300 end: 3000, 301 want: 3000, 302 fin: true, 303 wantEOF: true, 304 }}, 305 }, { 306 name: "out of order", 307 frames: []frame{{ 308 start: 1000, 309 end: 2000, 310 }, { 311 start: 2000, 312 end: 3000, 313 }, { 314 start: 0, 315 end: 1000, 316 want: 3000, 317 }}, 318 }, { 319 name: "resent", 320 frames: []frame{{ 321 start: 0, 322 end: 1000, 323 want: 1000, 324 }, { 325 start: 0, 326 end: 1000, 327 want: 1000, 328 }, { 329 start: 1000, 330 end: 2000, 331 want: 2000, 332 }, { 333 start: 0, 334 end: 1000, 335 want: 2000, 336 }, { 337 start: 1000, 338 end: 2000, 339 want: 2000, 340 }}, 341 }, { 342 name: "overlapping", 343 frames: []frame{{ 344 start: 0, 345 end: 1000, 346 want: 1000, 347 }, { 348 start: 3000, 349 end: 4000, 350 want: 1000, 351 }, { 352 start: 2000, 353 end: 3000, 354 want: 1000, 355 }, { 356 start: 1000, 357 end: 3000, 358 want: 4000, 359 }}, 360 }, { 361 name: "early eof", 362 frames: []frame{{ 363 start: 3000, 364 end: 3000, 365 fin: true, 366 want: 0, 367 }, { 368 start: 1000, 369 end: 2000, 370 want: 0, 371 }, { 372 start: 0, 373 end: 1000, 374 want: 2000, 375 }, { 376 start: 2000, 377 end: 3000, 378 want: 3000, 379 wantEOF: true, 380 }}, 381 }, { 382 name: "empty eof", 383 frames: []frame{{ 384 start: 0, 385 end: 1000, 386 want: 1000, 387 }, { 388 start: 1000, 389 end: 1000, 390 fin: true, 391 want: 1000, 392 wantEOF: true, 393 }}, 394 }} { 395 testStreamTypes(t, test.name, func(t *testing.T, styp streamType) { 396 tc := newTestConn(t, serverSide) 397 tc.handshake() 398 sid := newStreamID(clientSide, styp, 0) 399 var s *Stream 400 got := make([]byte, len(want)) 401 var total int 402 for _, f := range test.frames { 403 t.Logf("receive [%v,%v)", f.start, f.end) 404 tc.writeFrames(packetType1RTT, debugFrameStream{ 405 id: sid, 406 off: f.start, 407 data: want[f.start:f.end], 408 fin: f.fin, 409 }) 410 if s == nil { 411 s = tc.acceptStream() 412 } 413 for { 414 n, err := s.Read(got[total:]) 415 t.Logf("s.Read() = %v, %v", n, err) 416 total += n 417 if f.wantEOF && err != io.EOF { 418 t.Fatalf("Read() error = %v; want io.EOF", err) 419 } 420 if !f.wantEOF && err == io.EOF { 421 t.Fatalf("Read() error = io.EOF, want something else") 422 } 423 if err != nil { 424 break 425 } 426 } 427 if total != f.want { 428 t.Fatalf("total bytes read = %v, want %v", total, f.want) 429 } 430 for i := 0; i < total; i++ { 431 if got[i] != want[i] { 432 t.Fatalf("byte %v differs: got %v, want %v", i, got[i], want[i]) 433 } 434 } 435 } 436 }) 437 } 438 439 } 440 441 func TestStreamReceiveExtendsStreamWindow(t *testing.T) { 442 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 443 const maxWindowSize = 20 444 ctx := canceledContext() 445 tc := newTestConn(t, serverSide, func(c *Config) { 446 c.MaxStreamReadBufferSize = maxWindowSize 447 }) 448 tc.handshake() 449 tc.ignoreFrame(frameTypeAck) 450 sid := newStreamID(clientSide, styp, 0) 451 tc.writeFrames(packetType1RTT, debugFrameStream{ 452 id: sid, 453 off: 0, 454 data: make([]byte, maxWindowSize), 455 }) 456 s, err := tc.conn.AcceptStream(ctx) 457 if err != nil { 458 t.Fatalf("AcceptStream: %v", err) 459 } 460 tc.wantIdle("stream window is not extended before data is read") 461 buf := make([]byte, maxWindowSize+1) 462 if n, err := s.Read(buf); n != maxWindowSize || err != nil { 463 t.Fatalf("s.Read() = %v, %v; want %v, nil", n, err, maxWindowSize) 464 } 465 tc.wantFrame("stream window is extended after reading data", 466 packetType1RTT, debugFrameMaxStreamData{ 467 id: sid, 468 max: maxWindowSize * 2, 469 }) 470 tc.writeFrames(packetType1RTT, debugFrameStream{ 471 id: sid, 472 off: maxWindowSize, 473 data: make([]byte, maxWindowSize), 474 fin: true, 475 }) 476 if n, err := s.Read(buf); n != maxWindowSize || err != io.EOF { 477 t.Fatalf("s.Read() = %v, %v; want %v, io.EOF", n, err, maxWindowSize) 478 } 479 tc.wantIdle("stream window is not extended after FIN") 480 }) 481 } 482 483 func TestStreamReceiveViolatesStreamDataLimit(t *testing.T) { 484 // "A receiver MUST close the connection with an error of type FLOW_CONTROL_ERROR if 485 // the sender violates the advertised [...] stream data limits [...]" 486 // https://www.rfc-editor.org/rfc/rfc9000#section-4.1-8 487 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 488 const maxStreamData = 10 489 for _, test := range []struct { 490 off int64 491 size int64 492 }{{ 493 off: maxStreamData, 494 size: 1, 495 }, { 496 off: 0, 497 size: maxStreamData + 1, 498 }, { 499 off: maxStreamData - 1, 500 size: 2, 501 }} { 502 tc := newTestConn(t, serverSide, func(c *Config) { 503 c.MaxStreamReadBufferSize = maxStreamData 504 }) 505 tc.handshake() 506 tc.ignoreFrame(frameTypeAck) 507 tc.writeFrames(packetType1RTT, debugFrameStream{ 508 id: newStreamID(clientSide, styp, 0), 509 off: test.off, 510 data: make([]byte, test.size), 511 }) 512 tc.wantFrame( 513 fmt.Sprintf("data [%v,%v) violates stream data limit and closes connection", 514 test.off, test.off+test.size), 515 packetType1RTT, debugFrameConnectionCloseTransport{ 516 code: errFlowControl, 517 }, 518 ) 519 } 520 }) 521 } 522 523 func TestStreamReceiveDuplicateDataDoesNotViolateLimits(t *testing.T) { 524 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 525 const maxData = 10 526 tc := newTestConn(t, serverSide, func(c *Config) { 527 // TODO: Add connection-level maximum data here as well. 528 c.MaxStreamReadBufferSize = maxData 529 }) 530 tc.handshake() 531 tc.ignoreFrame(frameTypeAck) 532 for i := 0; i < 3; i++ { 533 tc.writeFrames(packetType1RTT, debugFrameStream{ 534 id: newStreamID(clientSide, styp, 0), 535 off: 0, 536 data: make([]byte, maxData), 537 }) 538 tc.wantIdle(fmt.Sprintf("conn sends no frames after receiving data frame %v", i)) 539 } 540 }) 541 } 542 543 func TestStreamReceiveEmptyEOF(t *testing.T) { 544 // A stream receives some data, we read a byte of that data 545 // (causing the rest to be pulled into the s.inbuf buffer), 546 // and then we receive a FIN with no additional data. 547 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 548 tc, s := newTestConnAndRemoteStream(t, serverSide, styp, permissiveTransportParameters) 549 want := []byte{1, 2, 3} 550 tc.writeFrames(packetType1RTT, debugFrameStream{ 551 id: s.id, 552 data: want, 553 }) 554 if got, err := s.ReadByte(); got != want[0] || err != nil { 555 t.Fatalf("s.ReadByte() = %v, %v; want %v, nil", got, err, want[0]) 556 } 557 558 tc.writeFrames(packetType1RTT, debugFrameStream{ 559 id: s.id, 560 off: 3, 561 fin: true, 562 }) 563 if got, err := io.ReadAll(s); !bytes.Equal(got, want[1:]) || err != nil { 564 t.Fatalf("io.ReadAll(s) = {%x}, %v; want {%x}, nil", got, err, want[1:]) 565 } 566 }) 567 } 568 569 func finalSizeTest(t *testing.T, wantErr transportError, f func(tc *testConn, sid streamID) (finalSize int64), opts ...any) { 570 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 571 for _, test := range []struct { 572 name string 573 finalFrame func(tc *testConn, sid streamID, finalSize int64) 574 }{{ 575 name: "FIN", 576 finalFrame: func(tc *testConn, sid streamID, finalSize int64) { 577 tc.writeFrames(packetType1RTT, debugFrameStream{ 578 id: sid, 579 off: finalSize, 580 fin: true, 581 }) 582 }, 583 }, { 584 name: "RESET_STREAM", 585 finalFrame: func(tc *testConn, sid streamID, finalSize int64) { 586 tc.writeFrames(packetType1RTT, debugFrameResetStream{ 587 id: sid, 588 finalSize: finalSize, 589 }) 590 }, 591 }} { 592 t.Run(test.name, func(t *testing.T) { 593 tc := newTestConn(t, serverSide, opts...) 594 tc.handshake() 595 sid := newStreamID(clientSide, styp, 0) 596 finalSize := f(tc, sid) 597 test.finalFrame(tc, sid, finalSize) 598 tc.wantFrame("change in final size of stream is an error", 599 packetType1RTT, debugFrameConnectionCloseTransport{ 600 code: wantErr, 601 }, 602 ) 603 }) 604 } 605 }) 606 } 607 608 func TestStreamFinalSizeChangedAfterFin(t *testing.T) { 609 // "If a RESET_STREAM or STREAM frame is received indicating a change 610 // in the final size for the stream, an endpoint SHOULD respond with 611 // an error of type FINAL_SIZE_ERROR [...]" 612 // https://www.rfc-editor.org/rfc/rfc9000#section-4.5-5 613 finalSizeTest(t, errFinalSize, func(tc *testConn, sid streamID) (finalSize int64) { 614 tc.writeFrames(packetType1RTT, debugFrameStream{ 615 id: sid, 616 off: 10, 617 fin: true, 618 }) 619 return 9 620 }) 621 } 622 623 func TestStreamFinalSizeBeforePreviousData(t *testing.T) { 624 finalSizeTest(t, errFinalSize, func(tc *testConn, sid streamID) (finalSize int64) { 625 tc.writeFrames(packetType1RTT, debugFrameStream{ 626 id: sid, 627 off: 10, 628 data: []byte{0}, 629 }) 630 return 9 631 }) 632 } 633 634 func TestStreamFinalSizePastMaxStreamData(t *testing.T) { 635 finalSizeTest(t, errFlowControl, func(tc *testConn, sid streamID) (finalSize int64) { 636 return 11 637 }, func(c *Config) { 638 c.MaxStreamReadBufferSize = 10 639 }) 640 } 641 642 func TestStreamDataBeyondFinalSize(t *testing.T) { 643 // "A receiver SHOULD treat receipt of data at or beyond 644 // the final size as an error of type FINAL_SIZE_ERROR [...]" 645 // https://www.rfc-editor.org/rfc/rfc9000#section-4.5-5 646 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 647 tc := newTestConn(t, serverSide) 648 tc.handshake() 649 sid := newStreamID(clientSide, styp, 0) 650 651 const write1size = 4 652 tc.writeFrames(packetType1RTT, debugFrameStream{ 653 id: sid, 654 off: 0, 655 data: make([]byte, 16), 656 fin: true, 657 }) 658 tc.writeFrames(packetType1RTT, debugFrameStream{ 659 id: sid, 660 off: 16, 661 data: []byte{0}, 662 }) 663 tc.wantFrame("received data past final size of stream", 664 packetType1RTT, debugFrameConnectionCloseTransport{ 665 code: errFinalSize, 666 }, 667 ) 668 }) 669 } 670 671 func TestStreamReceiveUnblocksReader(t *testing.T) { 672 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 673 tc := newTestConn(t, serverSide) 674 tc.handshake() 675 want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 676 sid := newStreamID(clientSide, styp, 0) 677 678 // AcceptStream blocks until a STREAM frame is received. 679 accept := runAsync(tc, func(ctx context.Context) (*Stream, error) { 680 return tc.conn.AcceptStream(ctx) 681 }) 682 const write1size = 4 683 tc.writeFrames(packetType1RTT, debugFrameStream{ 684 id: sid, 685 off: 0, 686 data: want[:write1size], 687 }) 688 s, err := accept.result() 689 if err != nil { 690 t.Fatalf("AcceptStream() = %v", err) 691 } 692 693 // Read succeeds immediately, since we already have data. 694 got := make([]byte, len(want)) 695 read := runAsync(tc, func(ctx context.Context) (int, error) { 696 return s.Read(got) 697 }) 698 if n, err := read.result(); n != write1size || err != nil { 699 t.Fatalf("Read = %v, %v; want %v, nil", n, err, write1size) 700 } 701 702 // Read blocks waiting for more data. 703 read = runAsync(tc, func(ctx context.Context) (int, error) { 704 s.SetReadContext(ctx) 705 return s.Read(got[write1size:]) 706 }) 707 tc.writeFrames(packetType1RTT, debugFrameStream{ 708 id: sid, 709 off: write1size, 710 data: want[write1size:], 711 fin: true, 712 }) 713 if n, err := read.result(); n != len(want)-write1size || err != io.EOF { 714 t.Fatalf("Read = %v, %v; want %v, io.EOF", n, err, len(want)-write1size) 715 } 716 if !bytes.Equal(got, want) { 717 t.Fatalf("read bytes %x, want %x", got, want) 718 } 719 }) 720 } 721 722 // testStreamSendFrameInvalidState calls the test func with a stream ID for: 723 // 724 // - a remote bidirectional stream that the peer has not created 725 // - a remote unidirectional stream 726 // 727 // It then sends the returned frame (STREAM, STREAM_DATA_BLOCKED, etc.) 728 // to the conn and expects a STREAM_STATE_ERROR. 729 func testStreamSendFrameInvalidState(t *testing.T, f func(sid streamID) debugFrame) { 730 testSides(t, "stream_not_created", func(t *testing.T, side connSide) { 731 tc := newTestConn(t, side, permissiveTransportParameters) 732 tc.handshake() 733 tc.writeFrames(packetType1RTT, f(newStreamID(side, bidiStream, 0))) 734 tc.wantFrame("frame for local stream which has not been created", 735 packetType1RTT, debugFrameConnectionCloseTransport{ 736 code: errStreamState, 737 }) 738 }) 739 testSides(t, "uni_stream", func(t *testing.T, side connSide) { 740 ctx := canceledContext() 741 tc := newTestConn(t, side, permissiveTransportParameters) 742 tc.handshake() 743 sid := newStreamID(side, uniStream, 0) 744 s, err := tc.conn.NewSendOnlyStream(ctx) 745 if err != nil { 746 t.Fatal(err) 747 } 748 s.Flush() // open the stream 749 tc.wantFrame("new stream is opened", 750 packetType1RTT, debugFrameStream{ 751 id: sid, 752 data: []byte{}, 753 }) 754 tc.writeFrames(packetType1RTT, f(sid)) 755 tc.wantFrame("send-oriented frame for send-only stream", 756 packetType1RTT, debugFrameConnectionCloseTransport{ 757 code: errStreamState, 758 }) 759 }) 760 } 761 762 func TestStreamResetStreamInvalidState(t *testing.T) { 763 // "An endpoint that receives a RESET_STREAM frame for a send-only 764 // stream MUST terminate the connection with error STREAM_STATE_ERROR." 765 // https://www.rfc-editor.org/rfc/rfc9000#section-19.4-3 766 testStreamSendFrameInvalidState(t, func(sid streamID) debugFrame { 767 return debugFrameResetStream{ 768 id: sid, 769 code: 0, 770 finalSize: 0, 771 } 772 }) 773 } 774 775 func TestStreamStreamFrameInvalidState(t *testing.T) { 776 // "An endpoint MUST terminate the connection with error STREAM_STATE_ERROR 777 // if it receives a STREAM frame for a locally initiated stream 778 // that has not yet been created, or for a send-only stream." 779 // https://www.rfc-editor.org/rfc/rfc9000.html#section-19.8-3 780 testStreamSendFrameInvalidState(t, func(sid streamID) debugFrame { 781 return debugFrameStream{ 782 id: sid, 783 } 784 }) 785 } 786 787 func TestStreamDataBlockedInvalidState(t *testing.T) { 788 // "An endpoint MUST terminate the connection with error STREAM_STATE_ERROR 789 // if it receives a STREAM frame for a locally initiated stream 790 // that has not yet been created, or for a send-only stream." 791 // https://www.rfc-editor.org/rfc/rfc9000.html#section-19.8-3 792 testStreamSendFrameInvalidState(t, func(sid streamID) debugFrame { 793 return debugFrameStream{ 794 id: sid, 795 } 796 }) 797 } 798 799 // testStreamReceiveFrameInvalidState calls the test func with a stream ID for: 800 // 801 // - a remote bidirectional stream that the peer has not created 802 // - a local unidirectional stream 803 // 804 // It then sends the returned frame (MAX_STREAM_DATA, STOP_SENDING, etc.) 805 // to the conn and expects a STREAM_STATE_ERROR. 806 func testStreamReceiveFrameInvalidState(t *testing.T, f func(sid streamID) debugFrame) { 807 testSides(t, "stream_not_created", func(t *testing.T, side connSide) { 808 tc := newTestConn(t, side) 809 tc.handshake() 810 tc.writeFrames(packetType1RTT, f(newStreamID(side, bidiStream, 0))) 811 tc.wantFrame("frame for local stream which has not been created", 812 packetType1RTT, debugFrameConnectionCloseTransport{ 813 code: errStreamState, 814 }) 815 }) 816 testSides(t, "uni_stream", func(t *testing.T, side connSide) { 817 tc := newTestConn(t, side) 818 tc.handshake() 819 tc.writeFrames(packetType1RTT, f(newStreamID(side.peer(), uniStream, 0))) 820 tc.wantFrame("receive-oriented frame for receive-only stream", 821 packetType1RTT, debugFrameConnectionCloseTransport{ 822 code: errStreamState, 823 }) 824 }) 825 } 826 827 func TestStreamStopSendingInvalidState(t *testing.T) { 828 // "Receiving a STOP_SENDING frame for a locally initiated stream 829 // that has not yet been created MUST be treated as a connection error 830 // of type STREAM_STATE_ERROR. An endpoint that receives a STOP_SENDING 831 // frame for a receive-only stream MUST terminate the connection with 832 // error STREAM_STATE_ERROR." 833 // https://www.rfc-editor.org/rfc/rfc9000#section-19.5-2 834 testStreamReceiveFrameInvalidState(t, func(sid streamID) debugFrame { 835 return debugFrameStopSending{ 836 id: sid, 837 } 838 }) 839 } 840 841 func TestStreamMaxStreamDataInvalidState(t *testing.T) { 842 // "Receiving a MAX_STREAM_DATA frame for a locally initiated stream 843 // that has not yet been created MUST be treated as a connection error 844 // of type STREAM_STATE_ERROR. An endpoint that receives a MAX_STREAM_DATA 845 // frame for a receive-only stream MUST terminate the connection 846 // with error STREAM_STATE_ERROR." 847 // https://www.rfc-editor.org/rfc/rfc9000#section-19.10-2 848 testStreamReceiveFrameInvalidState(t, func(sid streamID) debugFrame { 849 return debugFrameMaxStreamData{ 850 id: sid, 851 max: 1000, 852 } 853 }) 854 } 855 856 func TestStreamOffsetTooLarge(t *testing.T) { 857 // "Receipt of a frame that exceeds [2^62-1] MUST be treated as a 858 // connection error of type FRAME_ENCODING_ERROR or FLOW_CONTROL_ERROR." 859 // https://www.rfc-editor.org/rfc/rfc9000.html#section-19.8-9 860 tc := newTestConn(t, serverSide) 861 tc.handshake() 862 863 tc.writeFrames(packetType1RTT, 864 debugFrameStream{ 865 id: newStreamID(clientSide, bidiStream, 0), 866 off: 1<<62 - 1, 867 data: []byte{0}, 868 }) 869 got, _ := tc.readFrame() 870 want1 := debugFrameConnectionCloseTransport{code: errFrameEncoding} 871 want2 := debugFrameConnectionCloseTransport{code: errFlowControl} 872 if !frameEqual(got, want1) && !frameEqual(got, want2) { 873 t.Fatalf("STREAM offset exceeds 2^62-1\ngot: %v\nwant: %v\n or: %v", got, want1, want2) 874 } 875 } 876 877 func TestStreamReadFromWriteOnlyStream(t *testing.T) { 878 _, s := newTestConnAndLocalStream(t, serverSide, uniStream, permissiveTransportParameters) 879 buf := make([]byte, 10) 880 wantErr := "read from write-only stream" 881 if n, err := s.Read(buf); err == nil || !strings.Contains(err.Error(), wantErr) { 882 t.Errorf("s.Read() = %v, %v; want error %q", n, err, wantErr) 883 } 884 } 885 886 func TestStreamWriteToReadOnlyStream(t *testing.T) { 887 _, s := newTestConnAndRemoteStream(t, serverSide, uniStream) 888 buf := make([]byte, 10) 889 wantErr := "write to read-only stream" 890 if n, err := s.Write(buf); err == nil || !strings.Contains(err.Error(), wantErr) { 891 t.Errorf("s.Write() = %v, %v; want error %q", n, err, wantErr) 892 } 893 } 894 895 func TestStreamReadFromClosedStream(t *testing.T) { 896 tc, s := newTestConnAndRemoteStream(t, serverSide, bidiStream, permissiveTransportParameters) 897 s.CloseRead() 898 tc.wantFrame("CloseRead sends a STOP_SENDING frame", 899 packetType1RTT, debugFrameStopSending{ 900 id: s.id, 901 }) 902 wantErr := "read from closed stream" 903 if n, err := s.Read(make([]byte, 16)); err == nil || !strings.Contains(err.Error(), wantErr) { 904 t.Errorf("s.Read() = %v, %v; want error %q", n, err, wantErr) 905 } 906 // Data which shows up after STOP_SENDING is discarded. 907 tc.writeFrames(packetType1RTT, debugFrameStream{ 908 id: s.id, 909 data: []byte{1, 2, 3}, 910 fin: true, 911 }) 912 if n, err := s.Read(make([]byte, 16)); err == nil || !strings.Contains(err.Error(), wantErr) { 913 t.Errorf("s.Read() = %v, %v; want error %q", n, err, wantErr) 914 } 915 } 916 917 func TestStreamCloseReadWithAllDataReceived(t *testing.T) { 918 tc, s := newTestConnAndRemoteStream(t, serverSide, bidiStream, permissiveTransportParameters) 919 tc.writeFrames(packetType1RTT, debugFrameStream{ 920 id: s.id, 921 data: []byte{1, 2, 3}, 922 fin: true, 923 }) 924 s.CloseRead() 925 tc.wantIdle("CloseRead in Data Recvd state doesn't need to send STOP_SENDING") 926 // We had all the data for the stream, but CloseRead discarded it. 927 wantErr := "read from closed stream" 928 if n, err := s.Read(make([]byte, 16)); err == nil || !strings.Contains(err.Error(), wantErr) { 929 t.Errorf("s.Read() = %v, %v; want error %q", n, err, wantErr) 930 } 931 } 932 933 func TestStreamWriteToClosedStream(t *testing.T) { 934 tc, s := newTestConnAndLocalStream(t, serverSide, bidiStream, permissiveTransportParameters) 935 s.CloseWrite() 936 tc.wantFrame("stream is opened after being closed", 937 packetType1RTT, debugFrameStream{ 938 id: s.id, 939 off: 0, 940 fin: true, 941 data: []byte{}, 942 }) 943 wantErr := "write to closed stream" 944 if n, err := s.Write([]byte{}); err == nil || !strings.Contains(err.Error(), wantErr) { 945 t.Errorf("s.Write() = %v, %v; want error %q", n, err, wantErr) 946 } 947 } 948 949 func TestStreamResetBlockedStream(t *testing.T) { 950 tc, s := newTestConnAndLocalStream(t, serverSide, bidiStream, permissiveTransportParameters, 951 func(c *Config) { 952 c.MaxStreamWriteBufferSize = 4 953 }) 954 tc.ignoreFrame(frameTypeStreamDataBlocked) 955 writing := runAsync(tc, func(ctx context.Context) (int, error) { 956 s.SetWriteContext(ctx) 957 return s.Write([]byte{0, 1, 2, 3, 4, 5, 6, 7}) 958 }) 959 tc.wantFrame("stream writes data until write buffer fills", 960 packetType1RTT, debugFrameStream{ 961 id: s.id, 962 off: 0, 963 data: []byte{0, 1, 2, 3}, 964 }) 965 s.Reset(42) 966 tc.wantFrame("stream is reset", 967 packetType1RTT, debugFrameResetStream{ 968 id: s.id, 969 code: 42, 970 finalSize: 4, 971 }) 972 wantErr := "write to reset stream" 973 if n, err := writing.result(); n != 4 || !strings.Contains(err.Error(), wantErr) { 974 t.Errorf("s.Write() interrupted by Reset: %v, %q; want 4, %q", n, err, wantErr) 975 } 976 tc.writeAckForAll() 977 tc.wantIdle("buffer space is available, but stream has been reset") 978 s.Reset(100) 979 tc.wantIdle("resetting stream a second time has no effect") 980 if n, err := s.Write([]byte{}); err == nil || !strings.Contains(err.Error(), wantErr) { 981 t.Errorf("s.Write() = %v, %v; want error %q", n, err, wantErr) 982 } 983 } 984 985 func TestStreamWriteMoreThanOnePacketOfData(t *testing.T) { 986 tc, s := newTestConnAndLocalStream(t, serverSide, uniStream, func(p *transportParameters) { 987 p.initialMaxStreamsUni = 1 988 p.initialMaxData = 1 << 20 989 p.initialMaxStreamDataUni = 1 << 20 990 }) 991 want := make([]byte, 4096) 992 rand.Read(want) // doesn't need to be crypto/rand, but non-deprecated and harmless 993 w := runAsync(tc, func(ctx context.Context) (int, error) { 994 n, err := s.Write(want) 995 s.Flush() 996 return n, err 997 }) 998 got := make([]byte, 0, len(want)) 999 for { 1000 f, _ := tc.readFrame() 1001 if f == nil { 1002 break 1003 } 1004 sf, ok := f.(debugFrameStream) 1005 if !ok { 1006 t.Fatalf("unexpected frame: %v", sf) 1007 } 1008 if len(got) != int(sf.off) { 1009 t.Fatalf("got frame: %v\nwant offset %v", sf, len(got)) 1010 } 1011 got = append(got, sf.data...) 1012 } 1013 if n, err := w.result(); n != len(want) || err != nil { 1014 t.Fatalf("s.Write() = %v, %v; want %v, nil", n, err, len(want)) 1015 } 1016 if !bytes.Equal(got, want) { 1017 t.Fatalf("mismatch in received stream data") 1018 } 1019 } 1020 1021 func TestStreamCloseWaitsForAcks(t *testing.T) { 1022 tc, s := newTestConnAndLocalStream(t, serverSide, uniStream, permissiveTransportParameters) 1023 data := make([]byte, 100) 1024 s.Write(data) 1025 s.Flush() 1026 tc.wantFrame("conn sends data for the stream", 1027 packetType1RTT, debugFrameStream{ 1028 id: s.id, 1029 data: data, 1030 }) 1031 if err := s.Close(); err != context.Canceled { 1032 t.Fatalf("s.Close() = %v, want context.Canceled (data not acked yet)", err) 1033 } 1034 tc.wantFrame("conn sends FIN for closed stream", 1035 packetType1RTT, debugFrameStream{ 1036 id: s.id, 1037 off: int64(len(data)), 1038 fin: true, 1039 data: []byte{}, 1040 }) 1041 closing := runAsync(tc, func(ctx context.Context) (struct{}, error) { 1042 s.SetWriteContext(ctx) 1043 return struct{}{}, s.Close() 1044 }) 1045 if _, err := closing.result(); err != errNotDone { 1046 t.Fatalf("s.Close() = %v, want it to block waiting for acks", err) 1047 } 1048 tc.writeAckForAll() 1049 if _, err := closing.result(); err != nil { 1050 t.Fatalf("s.Close() = %v, want nil (all data acked)", err) 1051 } 1052 } 1053 1054 func TestStreamCloseReadOnly(t *testing.T) { 1055 tc, s := newTestConnAndRemoteStream(t, serverSide, uniStream, permissiveTransportParameters) 1056 if err := s.Close(); err != nil { 1057 t.Errorf("s.Close() = %v, want nil", err) 1058 } 1059 tc.wantFrame("closed stream sends STOP_SENDING", 1060 packetType1RTT, debugFrameStopSending{ 1061 id: s.id, 1062 }) 1063 } 1064 1065 func TestStreamCloseUnblocked(t *testing.T) { 1066 for _, test := range []struct { 1067 name string 1068 unblock func(tc *testConn, s *Stream) 1069 success bool 1070 }{{ 1071 name: "data received", 1072 unblock: func(tc *testConn, s *Stream) { 1073 tc.writeAckForAll() 1074 }, 1075 success: true, 1076 }, { 1077 name: "stop sending received", 1078 unblock: func(tc *testConn, s *Stream) { 1079 tc.writeFrames(packetType1RTT, debugFrameStopSending{ 1080 id: s.id, 1081 }) 1082 }, 1083 }, { 1084 name: "stream reset", 1085 unblock: func(tc *testConn, s *Stream) { 1086 s.Reset(0) 1087 tc.wait() // wait for test conn to process the Reset 1088 }, 1089 }} { 1090 t.Run(test.name, func(t *testing.T) { 1091 tc, s := newTestConnAndLocalStream(t, serverSide, uniStream, permissiveTransportParameters) 1092 data := make([]byte, 100) 1093 s.Write(data) 1094 s.Flush() 1095 tc.wantFrame("conn sends data for the stream", 1096 packetType1RTT, debugFrameStream{ 1097 id: s.id, 1098 data: data, 1099 }) 1100 if err := s.Close(); err != context.Canceled { 1101 t.Fatalf("s.Close() = %v, want context.Canceled (data not acked yet)", err) 1102 } 1103 tc.wantFrame("conn sends FIN for closed stream", 1104 packetType1RTT, debugFrameStream{ 1105 id: s.id, 1106 off: int64(len(data)), 1107 fin: true, 1108 data: []byte{}, 1109 }) 1110 closing := runAsync(tc, func(ctx context.Context) (struct{}, error) { 1111 s.SetWriteContext(ctx) 1112 return struct{}{}, s.Close() 1113 }) 1114 if _, err := closing.result(); err != errNotDone { 1115 t.Fatalf("s.Close() = %v, want it to block waiting for acks", err) 1116 } 1117 test.unblock(tc, s) 1118 _, err := closing.result() 1119 switch { 1120 case err == errNotDone: 1121 t.Fatalf("s.Close() still blocking; want it to have returned") 1122 case err == nil && !test.success: 1123 t.Fatalf("s.Close() = nil, want error") 1124 case err != nil && test.success: 1125 t.Fatalf("s.Close() = %v, want nil (all data acked)", err) 1126 } 1127 }) 1128 } 1129 } 1130 1131 func TestStreamCloseWriteWhenBlockedByStreamFlowControl(t *testing.T) { 1132 tc, s := newTestConnAndLocalStream(t, serverSide, uniStream, permissiveTransportParameters, 1133 func(p *transportParameters) { 1134 //p.initialMaxData = 0 1135 p.initialMaxStreamDataUni = 0 1136 }) 1137 tc.ignoreFrame(frameTypeStreamDataBlocked) 1138 if _, err := s.Write([]byte{0, 1}); err != nil { 1139 t.Fatalf("s.Write = %v", err) 1140 } 1141 s.CloseWrite() 1142 tc.wantIdle("stream write is blocked by flow control") 1143 1144 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 1145 id: s.id, 1146 max: 1, 1147 }) 1148 tc.wantFrame("send data up to flow control limit", 1149 packetType1RTT, debugFrameStream{ 1150 id: s.id, 1151 data: []byte{0}, 1152 }) 1153 tc.wantIdle("stream write is again blocked by flow control") 1154 1155 tc.writeFrames(packetType1RTT, debugFrameMaxStreamData{ 1156 id: s.id, 1157 max: 2, 1158 }) 1159 tc.wantFrame("send remaining data and FIN", 1160 packetType1RTT, debugFrameStream{ 1161 id: s.id, 1162 off: 1, 1163 data: []byte{1}, 1164 fin: true, 1165 }) 1166 } 1167 1168 func TestStreamPeerResetsWithUnreadAndUnsentData(t *testing.T) { 1169 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1170 tc, s := newTestConnAndRemoteStream(t, serverSide, styp) 1171 data := []byte{0, 1, 2, 3, 4, 5, 6, 7} 1172 tc.writeFrames(packetType1RTT, debugFrameStream{ 1173 id: s.id, 1174 data: data, 1175 }) 1176 got := make([]byte, 4) 1177 if n, err := s.Read(got); n != len(got) || err != nil { 1178 t.Fatalf("Read start of stream: got %v, %v; want %v, nil", n, err, len(got)) 1179 } 1180 const sentCode = 42 1181 tc.writeFrames(packetType1RTT, debugFrameResetStream{ 1182 id: s.id, 1183 finalSize: 20, 1184 code: sentCode, 1185 }) 1186 wantErr := StreamErrorCode(sentCode) 1187 if _, err := io.ReadAll(s); !errors.Is(err, wantErr) { 1188 t.Fatalf("Read reset stream: ReadAll got error %v; want %v", err, wantErr) 1189 } 1190 }) 1191 } 1192 1193 func TestStreamPeerResetWakesBlockedRead(t *testing.T) { 1194 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1195 tc, s := newTestConnAndRemoteStream(t, serverSide, styp) 1196 reader := runAsync(tc, func(ctx context.Context) (int, error) { 1197 s.SetReadContext(ctx) 1198 got := make([]byte, 4) 1199 return s.Read(got) 1200 }) 1201 const sentCode = 42 1202 tc.writeFrames(packetType1RTT, debugFrameResetStream{ 1203 id: s.id, 1204 finalSize: 20, 1205 code: sentCode, 1206 }) 1207 wantErr := StreamErrorCode(sentCode) 1208 if n, err := reader.result(); n != 0 || !errors.Is(err, wantErr) { 1209 t.Fatalf("Read reset stream: got %v, %v; want 0, %v", n, err, wantErr) 1210 } 1211 }) 1212 } 1213 1214 func TestStreamPeerResetFollowedByData(t *testing.T) { 1215 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1216 tc, s := newTestConnAndRemoteStream(t, serverSide, styp) 1217 tc.writeFrames(packetType1RTT, debugFrameResetStream{ 1218 id: s.id, 1219 finalSize: 4, 1220 code: 1, 1221 }) 1222 tc.writeFrames(packetType1RTT, debugFrameStream{ 1223 id: s.id, 1224 data: []byte{0, 1, 2, 3}, 1225 }) 1226 // Another reset with a different code, for good measure. 1227 tc.writeFrames(packetType1RTT, debugFrameResetStream{ 1228 id: s.id, 1229 finalSize: 4, 1230 code: 2, 1231 }) 1232 wantErr := StreamErrorCode(1) 1233 if n, err := s.Read(make([]byte, 16)); n != 0 || !errors.Is(err, wantErr) { 1234 t.Fatalf("Read from reset stream: got %v, %v; want 0, %v", n, err, wantErr) 1235 } 1236 }) 1237 } 1238 1239 func TestStreamResetInvalidCode(t *testing.T) { 1240 tc, s := newTestConnAndLocalStream(t, serverSide, uniStream, permissiveTransportParameters) 1241 s.Reset(1 << 62) 1242 tc.wantFrame("reset with invalid code sends a RESET_STREAM anyway", 1243 packetType1RTT, debugFrameResetStream{ 1244 id: s.id, 1245 // The code we send here isn't specified, 1246 // so this could really be any value. 1247 code: (1 << 62) - 1, 1248 }) 1249 } 1250 1251 func TestStreamResetReceiveOnly(t *testing.T) { 1252 tc, s := newTestConnAndRemoteStream(t, serverSide, uniStream) 1253 s.Reset(0) 1254 tc.wantIdle("resetting a receive-only stream has no effect") 1255 } 1256 1257 func TestStreamPeerStopSendingForActiveStream(t *testing.T) { 1258 // "An endpoint that receives a STOP_SENDING frame MUST send a RESET_STREAM frame if 1259 // the stream is in the "Ready" or "Send" state." 1260 // https://www.rfc-editor.org/rfc/rfc9000#section-3.5-4 1261 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1262 tc, s := newTestConnAndLocalStream(t, serverSide, styp, permissiveTransportParameters) 1263 for i := 0; i < 4; i++ { 1264 s.Write([]byte{byte(i)}) 1265 s.Flush() 1266 tc.wantFrame("write sends a STREAM frame to peer", 1267 packetType1RTT, debugFrameStream{ 1268 id: s.id, 1269 off: int64(i), 1270 data: []byte{byte(i)}, 1271 }) 1272 } 1273 tc.writeFrames(packetType1RTT, debugFrameStopSending{ 1274 id: s.id, 1275 code: 42, 1276 }) 1277 tc.wantFrame("receiving STOP_SENDING causes stream reset", 1278 packetType1RTT, debugFrameResetStream{ 1279 id: s.id, 1280 code: 42, 1281 finalSize: 4, 1282 }) 1283 if n, err := s.Write([]byte{0}); err == nil { 1284 t.Errorf("s.Write() after STOP_SENDING = %v, %v; want error", n, err) 1285 } 1286 // This ack will result in some of the previous frames being marked as lost. 1287 tc.writeAckForLatest() 1288 tc.wantIdle("lost STREAM frames for reset stream are not resent") 1289 }) 1290 } 1291 1292 func TestStreamReceiveDataBlocked(t *testing.T) { 1293 tc := newTestConn(t, serverSide, permissiveTransportParameters) 1294 tc.handshake() 1295 tc.ignoreFrame(frameTypeAck) 1296 1297 // We don't do anything with these frames, 1298 // but should accept them if the peer sends one. 1299 tc.writeFrames(packetType1RTT, debugFrameStreamDataBlocked{ 1300 id: newStreamID(clientSide, bidiStream, 0), 1301 max: 100, 1302 }) 1303 tc.writeFrames(packetType1RTT, debugFrameDataBlocked{ 1304 max: 100, 1305 }) 1306 tc.wantIdle("no response to STREAM_DATA_BLOCKED and DATA_BLOCKED") 1307 } 1308 1309 func TestStreamFlushExplicit(t *testing.T) { 1310 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1311 tc, s := newTestConnAndLocalStream(t, clientSide, styp, permissiveTransportParameters) 1312 want := []byte{0, 1, 2, 3} 1313 n, err := s.Write(want) 1314 if n != len(want) || err != nil { 1315 t.Fatalf("s.Write() = %v, %v; want %v, nil", n, err, len(want)) 1316 } 1317 tc.wantIdle("unflushed data is not sent") 1318 s.Flush() 1319 tc.wantFrame("data is sent after flush", 1320 packetType1RTT, debugFrameStream{ 1321 id: s.id, 1322 data: want, 1323 }) 1324 }) 1325 } 1326 1327 func TestStreamFlushImplicitExact(t *testing.T) { 1328 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1329 const writeBufferSize = 4 1330 tc, s := newTestConnAndLocalStream(t, clientSide, styp, 1331 permissiveTransportParameters, 1332 func(c *Config) { 1333 c.MaxStreamWriteBufferSize = writeBufferSize 1334 }) 1335 want := []byte{0, 1, 2, 3, 4, 5, 6} 1336 1337 // This write doesn't quite fill the output buffer. 1338 n, err := s.Write(want[:3]) 1339 if n != 3 || err != nil { 1340 t.Fatalf("s.Write() = %v, %v; want %v, nil", n, err, len(want)) 1341 } 1342 tc.wantIdle("unflushed data is not sent") 1343 1344 // This write fills the output buffer exactly. 1345 n, err = s.Write(want[3:4]) 1346 if n != 1 || err != nil { 1347 t.Fatalf("s.Write() = %v, %v; want %v, nil", n, err, len(want)) 1348 } 1349 tc.wantFrame("data is sent after write buffer fills", 1350 packetType1RTT, debugFrameStream{ 1351 id: s.id, 1352 data: want[0:4], 1353 }) 1354 }) 1355 } 1356 1357 func TestStreamFlushImplicitLargerThanBuffer(t *testing.T) { 1358 testStreamTypes(t, "", func(t *testing.T, styp streamType) { 1359 const writeBufferSize = 4 1360 tc, s := newTestConnAndLocalStream(t, clientSide, styp, 1361 permissiveTransportParameters, 1362 func(c *Config) { 1363 c.MaxStreamWriteBufferSize = writeBufferSize 1364 }) 1365 want := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 1366 1367 w := runAsync(tc, func(ctx context.Context) (int, error) { 1368 s.SetWriteContext(ctx) 1369 n, err := s.Write(want) 1370 return n, err 1371 }) 1372 1373 tc.wantFrame("data is sent after write buffer fills", 1374 packetType1RTT, debugFrameStream{ 1375 id: s.id, 1376 data: want[0:4], 1377 }) 1378 tc.writeAckForAll() 1379 tc.wantFrame("ack permits sending more data", 1380 packetType1RTT, debugFrameStream{ 1381 id: s.id, 1382 off: 4, 1383 data: want[4:8], 1384 }) 1385 tc.writeAckForAll() 1386 1387 tc.wantIdle("write buffer is not full") 1388 if n, err := w.result(); n != len(want) || err != nil { 1389 t.Fatalf("Write() = %v, %v; want %v, nil", n, err, len(want)) 1390 } 1391 1392 s.Flush() 1393 tc.wantFrame("flush sends last buffer of data", 1394 packetType1RTT, debugFrameStream{ 1395 id: s.id, 1396 off: 8, 1397 data: want[8:], 1398 }) 1399 }) 1400 } 1401 1402 type streamSide string 1403 1404 const ( 1405 localStream = streamSide("local") 1406 remoteStream = streamSide("remote") 1407 ) 1408 1409 func newTestConnAndStream(t *testing.T, side connSide, sside streamSide, styp streamType, opts ...any) (*testConn, *Stream) { 1410 if sside == localStream { 1411 return newTestConnAndLocalStream(t, side, styp, opts...) 1412 } else { 1413 return newTestConnAndRemoteStream(t, side, styp, opts...) 1414 } 1415 } 1416 1417 func newTestConnAndLocalStream(t *testing.T, side connSide, styp streamType, opts ...any) (*testConn, *Stream) { 1418 t.Helper() 1419 tc := newTestConn(t, side, opts...) 1420 tc.handshake() 1421 tc.ignoreFrame(frameTypeAck) 1422 s := newLocalStream(t, tc, styp) 1423 s.SetReadContext(canceledContext()) 1424 s.SetWriteContext(canceledContext()) 1425 return tc, s 1426 } 1427 1428 func newLocalStream(t *testing.T, tc *testConn, styp streamType) *Stream { 1429 t.Helper() 1430 ctx := canceledContext() 1431 s, err := tc.conn.newLocalStream(ctx, styp) 1432 if err != nil { 1433 t.Fatalf("conn.newLocalStream(%v) = %v", styp, err) 1434 } 1435 s.SetReadContext(canceledContext()) 1436 s.SetWriteContext(canceledContext()) 1437 return s 1438 } 1439 1440 func newTestConnAndRemoteStream(t *testing.T, side connSide, styp streamType, opts ...any) (*testConn, *Stream) { 1441 t.Helper() 1442 tc := newTestConn(t, side, opts...) 1443 tc.handshake() 1444 tc.ignoreFrame(frameTypeAck) 1445 s := newRemoteStream(t, tc, styp) 1446 s.SetReadContext(canceledContext()) 1447 s.SetWriteContext(canceledContext()) 1448 return tc, s 1449 } 1450 1451 func newRemoteStream(t *testing.T, tc *testConn, styp streamType) *Stream { 1452 t.Helper() 1453 ctx := canceledContext() 1454 tc.writeFrames(packetType1RTT, debugFrameStream{ 1455 id: newStreamID(tc.conn.side.peer(), styp, 0), 1456 }) 1457 s, err := tc.conn.AcceptStream(ctx) 1458 if err != nil { 1459 t.Fatalf("conn.AcceptStream() = %v", err) 1460 } 1461 s.SetReadContext(canceledContext()) 1462 s.SetWriteContext(canceledContext()) 1463 return s 1464 } 1465 1466 // permissiveTransportParameters may be passed as an option to newTestConn. 1467 func permissiveTransportParameters(p *transportParameters) { 1468 p.initialMaxStreamsBidi = maxStreamsLimit 1469 p.initialMaxStreamsUni = maxStreamsLimit 1470 p.initialMaxData = maxVarint 1471 p.initialMaxStreamDataBidiRemote = maxVarint 1472 p.initialMaxStreamDataBidiLocal = maxVarint 1473 p.initialMaxStreamDataUni = maxVarint 1474 } 1475 1476 func makeTestData(n int) []byte { 1477 b := make([]byte, n) 1478 for i := 0; i < n; i++ { 1479 b[i] = byte(i) 1480 } 1481 return b 1482 }