| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- package quic
- import (
- "fmt"
- "github.com/Psiphon-Labs/quic-go/internal/protocol"
- "github.com/Psiphon-Labs/quic-go/internal/qerr"
- "github.com/Psiphon-Labs/quic-go/internal/wire"
- )
- type cryptoStream struct {
- queue frameSorter
- highestOffset protocol.ByteCount
- finished bool
- writeOffset protocol.ByteCount
- writeBuf []byte
- }
- func newCryptoStream() *cryptoStream {
- return &cryptoStream{queue: *newFrameSorter()}
- }
- func (s *cryptoStream) HandleCryptoFrame(f *wire.CryptoFrame) error {
- highestOffset := f.Offset + protocol.ByteCount(len(f.Data))
- if maxOffset := highestOffset; maxOffset > protocol.MaxCryptoStreamOffset {
- return &qerr.TransportError{
- ErrorCode: qerr.CryptoBufferExceeded,
- ErrorMessage: fmt.Sprintf("received invalid offset %d on crypto stream, maximum allowed %d", maxOffset, protocol.MaxCryptoStreamOffset),
- }
- }
- if s.finished {
- if highestOffset > s.highestOffset {
- // reject crypto data received after this stream was already finished
- return &qerr.TransportError{
- ErrorCode: qerr.ProtocolViolation,
- ErrorMessage: "received crypto data after change of encryption level",
- }
- }
- // ignore data with a smaller offset than the highest received
- // could e.g. be a retransmission
- return nil
- }
- s.highestOffset = max(s.highestOffset, highestOffset)
- return s.queue.Push(f.Data, f.Offset, nil)
- }
- // GetCryptoData retrieves data that was received in CRYPTO frames
- func (s *cryptoStream) GetCryptoData() []byte {
- _, data, _ := s.queue.Pop()
- return data
- }
- func (s *cryptoStream) Finish() error {
- if s.queue.HasMoreData() {
- return &qerr.TransportError{
- ErrorCode: qerr.ProtocolViolation,
- ErrorMessage: "encryption level changed, but crypto stream has more data to read",
- }
- }
- s.finished = true
- return nil
- }
- // Writes writes data that should be sent out in CRYPTO frames
- func (s *cryptoStream) Write(p []byte) (int, error) {
- s.writeBuf = append(s.writeBuf, p...)
- return len(p), nil
- }
- func (s *cryptoStream) HasData() bool {
- return len(s.writeBuf) > 0
- }
- func (s *cryptoStream) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame {
- f := &wire.CryptoFrame{Offset: s.writeOffset}
- n := min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf)))
- f.Data = s.writeBuf[:n]
- s.writeBuf = s.writeBuf[n:]
- s.writeOffset += n
- return f
- }
|