github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/stream.go (about) 1 package quic 2 3 import ( 4 "net" 5 "os" 6 "sync" 7 "time" 8 9 "github.com/TugasAkhir-QUIC/quic-go/internal/ackhandler" 10 "github.com/TugasAkhir-QUIC/quic-go/internal/flowcontrol" 11 "github.com/TugasAkhir-QUIC/quic-go/internal/protocol" 12 "github.com/TugasAkhir-QUIC/quic-go/internal/wire" 13 ) 14 15 type deadlineError struct{} 16 17 func (deadlineError) Error() string { return "deadline exceeded" } 18 func (deadlineError) Temporary() bool { return true } 19 func (deadlineError) Timeout() bool { return true } 20 func (deadlineError) Unwrap() error { return os.ErrDeadlineExceeded } 21 22 var errDeadline net.Error = &deadlineError{} 23 24 // The streamSender is notified by the stream about various events. 25 type streamSender interface { 26 queueControlFrame(wire.Frame) 27 onHasStreamData(protocol.StreamID) 28 // must be called without holding the mutex that is acquired by closeForShutdown 29 onStreamCompleted(protocol.StreamID) 30 } 31 32 // Each of the both stream halves gets its own uniStreamSender. 33 // This is necessary in order to keep track when both halves have been completed. 34 type uniStreamSender struct { 35 streamSender 36 onStreamCompletedImpl func() 37 } 38 39 func (s *uniStreamSender) queueControlFrame(f wire.Frame) { 40 s.streamSender.queueControlFrame(f) 41 } 42 43 func (s *uniStreamSender) onHasStreamData(id protocol.StreamID) { 44 s.streamSender.onHasStreamData(id) 45 } 46 47 func (s *uniStreamSender) onStreamCompleted(protocol.StreamID) { 48 s.onStreamCompletedImpl() 49 } 50 51 var _ streamSender = &uniStreamSender{} 52 53 type streamI interface { 54 Stream 55 closeForShutdown(error) 56 // for receiving 57 handleStreamFrame(*wire.StreamFrame) error 58 handleResetStreamFrame(*wire.ResetStreamFrame) error 59 getWindowUpdate() protocol.ByteCount 60 // for sending 61 hasData() bool 62 handleStopSendingFrame(*wire.StopSendingFrame) 63 popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, bool, bool) 64 updateSendWindow(protocol.ByteCount) 65 getPriority() int 66 } 67 68 var ( 69 _ receiveStreamI = (streamI)(nil) 70 _ sendStreamI = (streamI)(nil) 71 ) 72 73 // A Stream assembles the data from StreamFrames and provides a super-convenient Read-Interface 74 // 75 // Read() and Write() may be called concurrently, but multiple calls to Read() or Write() individually must be synchronized manually. 76 type stream struct { 77 receiveStream 78 sendStream 79 80 completedMutex sync.Mutex 81 sender streamSender 82 receiveStreamCompleted bool 83 sendStreamCompleted bool 84 } 85 86 var _ Stream = &stream{} 87 88 // newStream creates a new Stream 89 func newStream(streamID protocol.StreamID, 90 sender streamSender, 91 flowController flowcontrol.StreamFlowController, 92 ) *stream { 93 s := &stream{sender: sender} 94 senderForSendStream := &uniStreamSender{ 95 streamSender: sender, 96 onStreamCompletedImpl: func() { 97 s.completedMutex.Lock() 98 s.sendStreamCompleted = true 99 s.checkIfCompleted() 100 s.completedMutex.Unlock() 101 }, 102 } 103 s.sendStream = *newSendStream(streamID, senderForSendStream, flowController) 104 senderForReceiveStream := &uniStreamSender{ 105 streamSender: sender, 106 onStreamCompletedImpl: func() { 107 s.completedMutex.Lock() 108 s.receiveStreamCompleted = true 109 s.checkIfCompleted() 110 s.completedMutex.Unlock() 111 }, 112 } 113 s.receiveStream = *newReceiveStream(streamID, senderForReceiveStream, flowController) 114 return s 115 } 116 117 // need to define StreamID() here, since both receiveStream and readStream have a StreamID() 118 func (s *stream) StreamID() protocol.StreamID { 119 // the result is same for receiveStream and sendStream 120 return s.sendStream.StreamID() 121 } 122 123 func (s *stream) Close() error { 124 return s.sendStream.Close() 125 } 126 127 func (s *stream) SetDeadline(t time.Time) error { 128 _ = s.SetReadDeadline(t) // SetReadDeadline never errors 129 _ = s.SetWriteDeadline(t) // SetWriteDeadline never errors 130 return nil 131 } 132 133 // CloseForShutdown closes a stream abruptly. 134 // It makes Read and Write unblock (and return the error) immediately. 135 // The peer will NOT be informed about this: the stream is closed without sending a FIN or RST. 136 func (s *stream) closeForShutdown(err error) { 137 s.sendStream.closeForShutdown(err) 138 s.receiveStream.closeForShutdown(err) 139 } 140 141 // checkIfCompleted is called from the uniStreamSender, when one of the stream halves is completed. 142 // It makes sure that the onStreamCompleted callback is only called if both receive and send side have completed. 143 func (s *stream) checkIfCompleted() { 144 if s.sendStreamCompleted && s.receiveStreamCompleted { 145 s.sender.onStreamCompleted(s.StreamID()) 146 } 147 } 148 149 func (s *stream) getPriority() int { 150 return s.sendStream.getPriority() 151 } 152 153 func (s *stream) SetPriority(priority int) { 154 s.sendStream.SetPriority(priority) 155 }