1package quic 2 3import ( 4 "fmt" 5 6 "github.com/lucas-clemente/quic-go/internal/protocol" 7 "github.com/lucas-clemente/quic-go/internal/wire" 8) 9 10type cryptoDataHandler interface { 11 HandleMessage([]byte, protocol.EncryptionLevel) bool 12} 13 14type cryptoStreamManager struct { 15 cryptoHandler cryptoDataHandler 16 17 initialStream cryptoStream 18 handshakeStream cryptoStream 19 oneRTTStream cryptoStream 20} 21 22func newCryptoStreamManager( 23 cryptoHandler cryptoDataHandler, 24 initialStream cryptoStream, 25 handshakeStream cryptoStream, 26 oneRTTStream cryptoStream, 27) *cryptoStreamManager { 28 return &cryptoStreamManager{ 29 cryptoHandler: cryptoHandler, 30 initialStream: initialStream, 31 handshakeStream: handshakeStream, 32 oneRTTStream: oneRTTStream, 33 } 34} 35 36func (m *cryptoStreamManager) HandleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel) (bool /* encryption level changed */, error) { 37 var str cryptoStream 38 //nolint:exhaustive // CRYPTO frames cannot be sent in 0-RTT packets. 39 switch encLevel { 40 case protocol.EncryptionInitial: 41 str = m.initialStream 42 case protocol.EncryptionHandshake: 43 str = m.handshakeStream 44 case protocol.Encryption1RTT: 45 str = m.oneRTTStream 46 default: 47 return false, fmt.Errorf("received CRYPTO frame with unexpected encryption level: %s", encLevel) 48 } 49 if err := str.HandleCryptoFrame(frame); err != nil { 50 return false, err 51 } 52 for { 53 data := str.GetCryptoData() 54 if data == nil { 55 return false, nil 56 } 57 if encLevelFinished := m.cryptoHandler.HandleMessage(data, encLevel); encLevelFinished { 58 return true, str.Finish() 59 } 60 } 61} 62