1
2
3
4
5 package quic
6
7 import (
8 "context"
9 "errors"
10 "fmt"
11 "io"
12 "math"
13 "sync"
14
15 "golang.org/x/net/internal/quic/quicwire"
16 )
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 type Stream struct {
34 id streamID
35 conn *Conn
36
37
38
39 inctx context.Context
40 outctx context.Context
41
42
43
44
45
46 ingate gate
47 in pipe
48 inwin int64
49 insendmax sentVal
50 inmaxbuf int64
51 insize int64
52 inset rangeset[int64]
53 inclosed sentVal
54 inresetcode int64
55
56
57
58
59
60
61 outgate gate
62 out pipe
63 outflushed int64
64 outwin int64
65 outmaxsent int64
66 outmaxbuf int64
67 outunsent rangeset[int64]
68 outacked rangeset[int64]
69 outopened sentVal
70 outclosed sentVal
71 outblocked sentVal
72 outreset sentVal
73 outresetcode uint64
74 outdone chan struct{}
75
76
77 inbufmu sync.Mutex
78 inbuf []byte
79 inbufoff int
80
81 outbufmu sync.Mutex
82 outbuf []byte
83 outbufoff int
84
85
86
87
88
89
90
91
92
93
94 state atomicBits[streamState]
95
96 prev, next *Stream
97 }
98
99 type streamState uint32
100
101 const (
102
103
104
105 streamInSendMeta = streamState(1 << iota)
106
107
108
109
110
111
112
113 streamOutSendMeta
114 streamOutSendData
115
116
117
118
119 streamInDone
120 streamOutDone
121
122
123 streamConnRemoved
124
125
126
127 streamQueueMeta
128 streamQueueData
129 )
130
131 type streamQueue int
132
133 const (
134 noQueue = streamQueue(iota)
135 metaQueue
136 dataQueue
137 )
138
139
140
141
142 const streamResetByConnClose = math.MaxInt64
143
144
145 func (s streamState) wantQueue() streamQueue {
146 switch {
147 case s&(streamInSendMeta|streamOutSendMeta) != 0:
148 return metaQueue
149 case s&(streamInDone|streamOutDone|streamConnRemoved) == streamInDone|streamOutDone:
150 return metaQueue
151 case s&streamOutSendData != 0:
152
153
154
155 return dataQueue
156 }
157 return noQueue
158 }
159
160
161 func (s streamState) inQueue() streamQueue {
162 switch {
163 case s&streamQueueMeta != 0:
164 return metaQueue
165 case s&streamQueueData != 0:
166 return dataQueue
167 }
168 return noQueue
169 }
170
171
172
173
174
175
176
177 func newStream(c *Conn, id streamID) *Stream {
178 s := &Stream{
179 conn: c,
180 id: id,
181 insize: -1,
182 inresetcode: -1,
183 ingate: newLockedGate(),
184 outgate: newLockedGate(),
185 inctx: context.Background(),
186 outctx: context.Background(),
187 }
188 if !s.IsReadOnly() {
189 s.outdone = make(chan struct{})
190 }
191 return s
192 }
193
194
195
196
197
198
199 func (s *Stream) ID() int64 {
200 return int64(s.id)
201 }
202
203
204
205
206 func (s *Stream) SetReadContext(ctx context.Context) {
207 s.inctx = ctx
208 }
209
210
211
212
213
214
215 func (s *Stream) SetWriteContext(ctx context.Context) {
216 s.outctx = ctx
217 }
218
219
220
221 func (s *Stream) IsReadOnly() bool {
222 return s.id.streamType() == uniStream && s.id.initiator() != s.conn.side
223 }
224
225
226
227 func (s *Stream) IsWriteOnly() bool {
228 return s.id.streamType() == uniStream && s.id.initiator() == s.conn.side
229 }
230
231
232
233
234
235
236
237
238
239
240
241 func (s *Stream) Read(b []byte) (n int, err error) {
242 if s.IsWriteOnly() {
243 return 0, errors.New("read from write-only stream")
244 }
245
246 fastPath := false
247 s.inbufmu.Lock()
248 if len(s.inbuf) > s.inbufoff {
249
250
251 n = copy(b, s.inbuf[s.inbufoff:])
252 s.inbufoff += n
253 fastPath = true
254 }
255 s.inbufmu.Unlock()
256 if fastPath {
257 return n, nil
258 }
259
260 if err := s.ingate.waitAndLock(s.inctx); err != nil {
261 return 0, err
262 }
263
264 if s.inbufoff > 0 {
265
266 s.in.discardBefore(s.in.start + int64(s.inbufoff))
267 s.inbufmu.Lock()
268 s.inbufoff = 0
269 s.inbuf = nil
270 s.inbufmu.Unlock()
271 }
272
273
274
275
276 var bytesRead int64
277 defer func() {
278 s.inUnlock()
279 s.conn.handleStreamBytesReadOffLoop(bytesRead)
280 }()
281 if s.inresetcode != -1 {
282 if s.inresetcode == streamResetByConnClose {
283 if err := s.conn.finalError(); err != nil {
284 return 0, err
285 }
286 }
287 return 0, fmt.Errorf("stream reset by peer: %w", StreamErrorCode(s.inresetcode))
288 }
289 if s.inclosed.isSet() {
290 return 0, errors.New("read from closed stream")
291 }
292 if s.insize == s.in.start {
293 return 0, io.EOF
294 }
295
296 if len(s.inset) < 1 || s.inset[0].start != 0 || s.inset[0].end <= s.in.start {
297 panic("BUG: inconsistent input stream state")
298 }
299 if size := int(s.inset[0].end - s.in.start); size < len(b) {
300 b = b[:size]
301 }
302 bytesRead = int64(len(b))
303 start := s.in.start
304 end := start + int64(len(b))
305 raceAcquire()
306 s.in.copy(start, b)
307 s.in.discardBefore(end)
308 if end == s.insize {
309
310
311 return len(b), io.EOF
312 }
313
314 if len(s.inset) > 0 && s.inset[0].start <= s.in.start && s.inset[0].end > s.in.start {
315
316
317 s.inbufmu.Lock()
318 s.inbuf = s.in.peek(s.inset[0].end - s.in.start)
319 s.inbufmu.Unlock()
320 bytesRead += int64(len(s.inbuf))
321 }
322 if s.insize == -1 || s.insize > s.inwin {
323 newWindow := s.in.start + int64(len(s.inbuf)) + s.inmaxbuf
324 addedWindow := newWindow - s.inwin
325 if shouldUpdateFlowControl(s.inmaxbuf, addedWindow) {
326
327 s.insendmax.setUnsent()
328 }
329 }
330
331 return len(b), nil
332 }
333
334
335
336
337 func (s *Stream) ReadByte() (byte, error) {
338 fastPath := false
339 s.inbufmu.Lock()
340 var readByte byte
341 if len(s.inbuf) > s.inbufoff {
342 readByte = s.inbuf[s.inbufoff]
343 s.inbufoff++
344 fastPath = true
345 }
346 s.inbufmu.Unlock()
347 if fastPath {
348 return readByte, nil
349 }
350
351 var b [1]byte
352 n, err := s.Read(b[:])
353 if n > 0 {
354 return b[0], nil
355 }
356 return 0, err
357 }
358
359
360
361
362
363 func shouldUpdateFlowControl(maxWindow, addedWindow int64) bool {
364 return addedWindow >= maxWindow/8
365 }
366
367
368
369
370
371
372 func (s *Stream) Write(b []byte) (n int, err error) {
373 if s.IsReadOnly() {
374 return 0, errors.New("write to read-only stream")
375 }
376
377 fastPath := false
378 s.outbufmu.Lock()
379 if len(b) > 0 && len(s.outbuf)-s.outbufoff >= len(b) {
380
381 copy(s.outbuf[s.outbufoff:], b)
382 s.outbufoff += len(b)
383 fastPath = true
384 }
385 s.outbufmu.Unlock()
386 if fastPath {
387 return len(b), nil
388 }
389
390 canWrite := s.outgate.lock()
391 s.flushFastOutputBuffer()
392 for {
393
394
395
396 if len(b) > 0 && !canWrite {
397
398 s.outUnlock()
399 if err := s.outgate.waitAndLock(s.outctx); err != nil {
400 return n, err
401 }
402
403
404
405 }
406 if err := s.writeErrorLocked(); err != nil {
407 s.outUnlock()
408 return n, err
409 }
410 if len(b) == 0 {
411 break
412 }
413
414
415 lim := s.out.start + s.outmaxbuf
416
417
418 nn := min(int64(len(b)), lim-s.out.end)
419
420 s.out.writeAt(b[:nn], s.out.end)
421 b = b[nn:]
422 n += int(nn)
423
424
425
426
427
428
429
430
431
432 const autoFlushSize = smallestMaxDatagramSize - 1 - connIDLen - 1 - aeadOverhead
433 shouldFlush := s.out.end >= s.outwin ||
434 s.out.end >= lim ||
435 (s.out.end-s.outflushed) >= autoFlushSize
436 if shouldFlush {
437 s.flushLocked()
438 }
439 if s.out.end > s.outwin {
440
441
442 s.outblocked.set()
443 }
444
445 canWrite = false
446 }
447 if lim := s.out.start + s.outmaxbuf - s.out.end - 1; lim > 0 {
448
449
450
451
452
453
454
455
456
457
458
459 s.outbufmu.Lock()
460 s.outbuf = s.out.availableBuffer()
461 if int64(len(s.outbuf)) > lim {
462 s.outbuf = s.outbuf[:lim]
463 }
464 s.outbufmu.Unlock()
465 }
466 raceReleaseMerge()
467 s.outUnlock()
468 return n, nil
469 }
470
471
472 func (s *Stream) WriteByte(c byte) error {
473 fastPath := false
474 s.outbufmu.Lock()
475 if s.outbufoff < len(s.outbuf) {
476 s.outbuf[s.outbufoff] = c
477 s.outbufoff++
478 fastPath = true
479 }
480 s.outbufmu.Unlock()
481 if fastPath {
482 return nil
483 }
484
485 b := [1]byte{c}
486 _, err := s.Write(b[:])
487 return err
488 }
489
490 func (s *Stream) flushFastOutputBuffer() {
491 s.outbufmu.Lock()
492 defer s.outbufmu.Unlock()
493 if s.outbuf == nil {
494 return
495 }
496
497
498
499 s.out.end += int64(s.outbufoff)
500 s.outbuf = nil
501 s.outbufoff = 0
502 }
503
504
505
506
507 func (s *Stream) Flush() error {
508 if s.IsReadOnly() {
509 return errors.New("flush of read-only stream")
510 }
511 s.outgate.lock()
512 defer s.outUnlock()
513 if err := s.writeErrorLocked(); err != nil {
514 return err
515 }
516 s.flushLocked()
517 return nil
518 }
519
520
521
522 func (s *Stream) writeErrorLocked() error {
523 if s.outreset.isSet() {
524 if s.outresetcode == streamResetByConnClose {
525 if err := s.conn.finalError(); err != nil {
526 return err
527 }
528 }
529 return errors.New("write to reset stream")
530 }
531 if s.outclosed.isSet() {
532 return errors.New("write to closed stream")
533 }
534 return nil
535 }
536
537 func (s *Stream) flushLocked() {
538 s.flushFastOutputBuffer()
539 s.outopened.set()
540 if s.outflushed < s.outwin {
541 s.outunsent.add(s.outflushed, min(s.outwin, s.out.end))
542 }
543 s.outflushed = s.out.end
544 }
545
546
547
548
549
550
551
552
553
554 func (s *Stream) Close() error {
555 s.CloseRead()
556 if s.IsReadOnly() {
557 return nil
558 }
559 s.CloseWrite()
560
561 if err := s.conn.waitOnDone(s.outctx, s.outdone); err != nil {
562 return err
563 }
564 s.outgate.lock()
565 defer s.outUnlock()
566 if s.outclosed.isReceived() && s.outacked.isrange(0, s.out.end) {
567 return nil
568 }
569 return errors.New("stream reset")
570 }
571
572
573
574
575
576
577
578 func (s *Stream) CloseRead() {
579 if s.IsWriteOnly() {
580 return
581 }
582 s.ingate.lock()
583 if s.inset.isrange(0, s.insize) || s.inresetcode != -1 {
584
585
586
587 s.inclosed.setReceived()
588 } else {
589 s.inclosed.set()
590 }
591 discarded := s.in.end - s.in.start
592 s.in.discardBefore(s.in.end)
593 s.inUnlock()
594 s.conn.handleStreamBytesReadOffLoop(discarded)
595 }
596
597
598
599
600
601
602
603 func (s *Stream) CloseWrite() {
604 if s.IsReadOnly() {
605 return
606 }
607 s.outgate.lock()
608 defer s.outUnlock()
609 s.outclosed.set()
610 s.flushLocked()
611 }
612
613
614
615
616
617
618
619
620
621
622
623
624 func (s *Stream) Reset(code uint64) {
625 const userClosed = true
626 s.resetInternal(code, userClosed)
627 }
628
629
630
631
632
633 func (s *Stream) resetInternal(code uint64, userClosed bool) {
634 s.outgate.lock()
635 defer s.outUnlock()
636 if s.IsReadOnly() {
637 return
638 }
639 if userClosed {
640
641 s.outclosed.set()
642 }
643 if s.outreset.isSet() {
644 return
645 }
646 if code > quicwire.MaxVarint {
647 code = quicwire.MaxVarint
648 }
649
650
651
652 s.outreset.set()
653 s.outresetcode = code
654 s.outbufmu.Lock()
655 s.outbuf = nil
656 s.outbufoff = 0
657 s.outbufmu.Unlock()
658 s.out.discardBefore(s.out.end)
659 s.outunsent = rangeset[int64]{}
660 s.outblocked.clear()
661 }
662
663
664 func (s *Stream) connHasClosed() {
665
666
667
668 localClose := s.conn.lifetime.state == connStateClosing
669
670 s.ingate.lock()
671 if !s.inset.isrange(0, s.insize) && s.inresetcode == -1 {
672 if localClose {
673 s.inclosed.set()
674 } else {
675 s.inresetcode = streamResetByConnClose
676 }
677 }
678 s.inUnlock()
679
680 s.outgate.lock()
681 if localClose {
682 s.outclosed.set()
683 s.outreset.set()
684 } else {
685 s.outresetcode = streamResetByConnClose
686 s.outreset.setReceived()
687 }
688 s.outUnlock()
689 }
690
691
692
693
694
695 func (s *Stream) inUnlock() {
696 state := s.inUnlockNoQueue()
697 s.conn.maybeQueueStreamForSend(s, state)
698 }
699
700
701
702 func (s *Stream) inUnlockNoQueue() streamState {
703 nextByte := s.in.start + int64(len(s.inbuf))
704 canRead := s.inset.contains(nextByte) ||
705 s.insize == s.in.start+int64(len(s.inbuf)) ||
706 s.inresetcode != -1 ||
707 s.inclosed.isSet()
708 defer s.ingate.unlock(canRead)
709 var state streamState
710 switch {
711 case s.IsWriteOnly():
712 state = streamInDone
713 case s.inresetcode != -1:
714 fallthrough
715 case s.in.start == s.insize:
716
717
718 if s.inclosed.isSet() {
719 state = streamInDone
720 }
721 case s.insendmax.shouldSend():
722 state = streamInSendMeta
723 case s.inclosed.shouldSend():
724 state = streamInSendMeta
725 }
726 const mask = streamInDone | streamInSendMeta
727 return s.state.set(state, mask)
728 }
729
730
731
732
733
734 func (s *Stream) outUnlock() {
735 state := s.outUnlockNoQueue()
736 s.conn.maybeQueueStreamForSend(s, state)
737 }
738
739
740
741 func (s *Stream) outUnlockNoQueue() streamState {
742 isDone := s.outclosed.isReceived() && s.outacked.isrange(0, s.out.end) ||
743 s.outreset.isSet()
744 if isDone {
745 select {
746 case <-s.outdone:
747 default:
748 if !s.IsReadOnly() {
749 close(s.outdone)
750 }
751 }
752 }
753 lim := s.out.start + s.outmaxbuf
754 canWrite := lim > s.out.end ||
755 s.outclosed.isSet() ||
756 s.outreset.isSet()
757 defer s.outgate.unlock(canWrite)
758 var state streamState
759 switch {
760 case s.IsReadOnly():
761 state = streamOutDone
762 case s.outclosed.isReceived() && s.outacked.isrange(0, s.out.end):
763 fallthrough
764 case s.outreset.isReceived():
765
766
767 if s.outclosed.isSet() {
768 state = streamOutDone
769 }
770 case s.outreset.shouldSend():
771 state = streamOutSendMeta
772 case s.outreset.isSet():
773 case s.outblocked.shouldSend():
774 state = streamOutSendMeta
775 case len(s.outunsent) > 0:
776 if s.outunsent.min() < s.outmaxsent {
777 state = streamOutSendMeta
778 } else {
779 state = streamOutSendData
780 }
781 case s.outclosed.shouldSend() && s.out.end == s.outmaxsent:
782 state = streamOutSendMeta
783 case s.outopened.shouldSend():
784 state = streamOutSendMeta
785 }
786 const mask = streamOutDone | streamOutSendMeta | streamOutSendData
787 return s.state.set(state, mask)
788 }
789
790
791 func (s *Stream) handleData(off int64, b []byte, fin bool) error {
792 s.ingate.lock()
793 defer s.inUnlock()
794 end := off + int64(len(b))
795 if err := s.checkStreamBounds(end, fin); err != nil {
796 return err
797 }
798 if s.inclosed.isSet() || s.inresetcode != -1 {
799
800
801 return nil
802 }
803 if s.insize == -1 && end > s.in.end {
804 added := end - s.in.end
805 if err := s.conn.handleStreamBytesReceived(added); err != nil {
806 return err
807 }
808 }
809 if len(s.inset) > 0 && s.inset[0].contains(off) {
810
811
812
813
814
815
816
817
818
819 newOff := min(end, s.inset[0].end)
820 b = b[newOff-off:]
821 off = newOff
822 }
823 s.in.writeAt(b, off)
824 s.inset.add(off, end)
825 if fin {
826 s.insize = end
827
828 s.insendmax.clear()
829 }
830 return nil
831 }
832
833
834 func (s *Stream) handleReset(code uint64, finalSize int64) error {
835 s.ingate.lock()
836 defer s.inUnlock()
837 const fin = true
838 if err := s.checkStreamBounds(finalSize, fin); err != nil {
839 return err
840 }
841 if s.inresetcode != -1 {
842
843 return nil
844 }
845 if s.insize == -1 {
846 added := finalSize - s.in.end
847 if err := s.conn.handleStreamBytesReceived(added); err != nil {
848 return err
849 }
850 }
851 s.conn.handleStreamBytesReadOnLoop(finalSize - s.in.start)
852 s.in.discardBefore(s.in.end)
853 s.inresetcode = int64(code)
854 s.insize = finalSize
855 return nil
856 }
857
858
859 func (s *Stream) checkStreamBounds(end int64, fin bool) error {
860 if end > s.inwin {
861
862 return localTransportError{
863 code: errFlowControl,
864 reason: "stream flow control window exceeded",
865 }
866 }
867 if s.insize != -1 && end > s.insize {
868
869 return localTransportError{
870 code: errFinalSize,
871 reason: "data received past end of stream",
872 }
873 }
874 if fin && s.insize != -1 && end != s.insize {
875
876 return localTransportError{
877 code: errFinalSize,
878 reason: "final size of stream changed",
879 }
880 }
881 if fin && end < s.in.end {
882
883 return localTransportError{
884 code: errFinalSize,
885 reason: "end of stream occurs before prior data",
886 }
887 }
888 return nil
889 }
890
891
892 func (s *Stream) handleStopSending(code uint64) error {
893
894
895 const userReset = false
896 s.resetInternal(code, userReset)
897 return nil
898 }
899
900
901 func (s *Stream) handleMaxStreamData(maxStreamData int64) error {
902 s.outgate.lock()
903 defer s.outUnlock()
904 if maxStreamData <= s.outwin {
905 return nil
906 }
907 if s.outflushed > s.outwin {
908 s.outunsent.add(s.outwin, min(maxStreamData, s.outflushed))
909 }
910 s.outwin = maxStreamData
911 if s.out.end > s.outwin {
912
913 s.outblocked.setUnsent()
914 } else {
915 s.outblocked.clear()
916 }
917 return nil
918 }
919
920
921 func (s *Stream) ackOrLoss(pnum packetNumber, ftype byte, fate packetFate) {
922
923
924
925
926
927
928 switch ftype {
929 case frameTypeResetStream:
930 s.outgate.lock()
931 s.outreset.ackOrLoss(pnum, fate)
932 s.outUnlock()
933 case frameTypeStopSending:
934 s.ingate.lock()
935 s.inclosed.ackOrLoss(pnum, fate)
936 s.inUnlock()
937 case frameTypeMaxStreamData:
938 s.ingate.lock()
939 s.insendmax.ackLatestOrLoss(pnum, fate)
940 s.inUnlock()
941 case frameTypeStreamDataBlocked:
942 s.outgate.lock()
943 s.outblocked.ackLatestOrLoss(pnum, fate)
944 s.outUnlock()
945 default:
946 panic("unhandled frame type")
947 }
948 }
949
950
951 func (s *Stream) ackOrLossData(pnum packetNumber, start, end int64, fin bool, fate packetFate) {
952 s.outgate.lock()
953 defer s.outUnlock()
954 s.outopened.ackOrLoss(pnum, fate)
955 if fin {
956 s.outclosed.ackOrLoss(pnum, fate)
957 }
958 if s.outreset.isSet() {
959
960 return
961 }
962 switch fate {
963 case packetAcked:
964 s.outacked.add(start, end)
965 s.outunsent.sub(start, end)
966
967 if s.outacked.contains(s.out.start) {
968 s.out.discardBefore(s.outacked[0].end)
969 }
970 case packetLost:
971
972
973
974 s.outunsent.add(start, end)
975 for _, a := range s.outacked {
976 s.outunsent.sub(a.start, a.end)
977 }
978 }
979 }
980
981
982
983
984
985
986 func (s *Stream) appendInFramesLocked(w *packetWriter, pnum packetNumber, pto bool) bool {
987 if s.inclosed.shouldSendPTO(pto) {
988
989
990 code := uint64(0)
991 if !w.appendStopSendingFrame(s.id, code) {
992 return false
993 }
994 s.inclosed.setSent(pnum)
995 }
996
997 if s.insendmax.shouldSendPTO(pto) {
998
999 maxStreamData := s.in.start + s.inmaxbuf
1000 if !w.appendMaxStreamDataFrame(s.id, maxStreamData) {
1001 return false
1002 }
1003 s.inwin = maxStreamData
1004 s.insendmax.setSent(pnum)
1005 }
1006 return true
1007 }
1008
1009
1010
1011
1012
1013
1014 func (s *Stream) appendOutFramesLocked(w *packetWriter, pnum packetNumber, pto bool) bool {
1015 if s.outreset.isSet() {
1016
1017 if s.outreset.shouldSendPTO(pto) {
1018 if !w.appendResetStreamFrame(s.id, s.outresetcode, s.outmaxsent) {
1019 return false
1020 }
1021 s.outreset.setSent(pnum)
1022 s.frameOpensStream(pnum)
1023 }
1024 return true
1025 }
1026 if s.outblocked.shouldSendPTO(pto) {
1027
1028 if !w.appendStreamDataBlockedFrame(s.id, s.outwin) {
1029 return false
1030 }
1031 s.outblocked.setSent(pnum)
1032 s.frameOpensStream(pnum)
1033 }
1034 for {
1035
1036 off, size := dataToSend(min(s.out.start, s.outwin), min(s.outflushed, s.outwin), s.outunsent, s.outacked, pto)
1037 if end := off + size; end > s.outmaxsent {
1038
1039 end = min(end, s.outmaxsent+s.conn.streams.outflow.avail())
1040 end = max(end, off)
1041 size = end - off
1042 }
1043 fin := s.outclosed.isSet() && off+size == s.out.end
1044 shouldSend := size > 0 ||
1045 s.outopened.shouldSendPTO(pto) ||
1046 (fin && s.outclosed.shouldSendPTO(pto))
1047 if !shouldSend {
1048 return true
1049 }
1050 b, added := w.appendStreamFrame(s.id, off, int(size), fin)
1051 if !added {
1052 return false
1053 }
1054 s.out.copy(off, b)
1055 end := off + int64(len(b))
1056 if end > s.outmaxsent {
1057 s.conn.streams.outflow.consume(end - s.outmaxsent)
1058 s.outmaxsent = end
1059 }
1060 s.outunsent.sub(off, end)
1061 s.frameOpensStream(pnum)
1062 if fin {
1063 s.outclosed.setSent(pnum)
1064 }
1065 if pto {
1066 return true
1067 }
1068 if int64(len(b)) < size {
1069 return false
1070 }
1071 }
1072 }
1073
1074
1075
1076
1077
1078 func (s *Stream) frameOpensStream(pnum packetNumber) {
1079 if !s.outopened.isReceived() {
1080 s.outopened.setSent(pnum)
1081 }
1082 }
1083
1084
1085 func dataToSend(start, end int64, outunsent, outacked rangeset[int64], pto bool) (sendStart, size int64) {
1086 switch {
1087 case pto:
1088
1089
1090
1091
1092
1093
1094
1095 for _, r := range outacked {
1096 if r.start > start {
1097 return start, r.start - start
1098 }
1099 }
1100 return start, end - start
1101 case outunsent.numRanges() > 0:
1102 return outunsent.min(), outunsent[0].size()
1103 default:
1104 return end, 0
1105 }
1106 }
1107
View as plain text