github.com/Psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/quic/gquic-go/packet_unpacker.go (about) 1 package gquic 2 3 import ( 4 "bytes" 5 6 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/internal/protocol" 7 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/internal/wire" 8 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/qerr" 9 ) 10 11 type unpackedPacket struct { 12 encryptionLevel protocol.EncryptionLevel 13 frames []wire.Frame 14 } 15 16 type gQUICAEAD interface { 17 Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel, error) 18 } 19 20 type quicAEAD interface { 21 OpenHandshake(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) 22 Open1RTT(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) 23 } 24 25 type packetUnpackerBase struct { 26 version protocol.VersionNumber 27 } 28 29 func (u *packetUnpackerBase) parseFrames(decrypted []byte, hdr *wire.Header) ([]wire.Frame, error) { 30 r := bytes.NewReader(decrypted) 31 if r.Len() == 0 { 32 return nil, qerr.MissingPayload 33 } 34 35 fs := make([]wire.Frame, 0, 2) 36 // Read all frames in the packet 37 for { 38 frame, err := wire.ParseNextFrame(r, hdr, u.version) 39 if err != nil { 40 return nil, err 41 } 42 if frame == nil { 43 break 44 } 45 fs = append(fs, frame) 46 } 47 return fs, nil 48 } 49 50 // The packetUnpackerGQUIC unpacks gQUIC packets. 51 type packetUnpackerGQUIC struct { 52 packetUnpackerBase 53 aead gQUICAEAD 54 } 55 56 var _ unpacker = &packetUnpackerGQUIC{} 57 58 func newPacketUnpackerGQUIC(aead gQUICAEAD, version protocol.VersionNumber) unpacker { 59 return &packetUnpackerGQUIC{ 60 packetUnpackerBase: packetUnpackerBase{version: version}, 61 aead: aead, 62 } 63 } 64 65 func (u *packetUnpackerGQUIC) Unpack(headerBinary []byte, hdr *wire.Header, data []byte) (*unpackedPacket, error) { 66 decrypted, encryptionLevel, err := u.aead.Open(data[:0], data, hdr.PacketNumber, headerBinary) 67 if err != nil { 68 // Wrap err in quicError so that public reset is sent by session 69 return nil, qerr.Error(qerr.DecryptionFailure, err.Error()) 70 } 71 72 fs, err := u.parseFrames(decrypted, hdr) 73 if err != nil { 74 return nil, err 75 } 76 77 return &unpackedPacket{ 78 encryptionLevel: encryptionLevel, 79 frames: fs, 80 }, nil 81 } 82 83 // The packetUnpacker unpacks IETF QUIC packets. 84 type packetUnpacker struct { 85 packetUnpackerBase 86 aead quicAEAD 87 } 88 89 var _ unpacker = &packetUnpacker{} 90 91 func newPacketUnpacker(aead quicAEAD, version protocol.VersionNumber) unpacker { 92 return &packetUnpacker{ 93 packetUnpackerBase: packetUnpackerBase{version: version}, 94 aead: aead, 95 } 96 } 97 98 func (u *packetUnpacker) Unpack(headerBinary []byte, hdr *wire.Header, data []byte) (*unpackedPacket, error) { 99 buf := *getPacketBuffer() 100 buf = buf[:0] 101 defer putPacketBuffer(&buf) 102 103 var decrypted []byte 104 var encryptionLevel protocol.EncryptionLevel 105 var err error 106 if hdr.IsLongHeader { 107 decrypted, err = u.aead.OpenHandshake(buf, data, hdr.PacketNumber, headerBinary) 108 encryptionLevel = protocol.EncryptionUnencrypted 109 } else { 110 decrypted, err = u.aead.Open1RTT(buf, data, hdr.PacketNumber, headerBinary) 111 encryptionLevel = protocol.EncryptionForwardSecure 112 } 113 if err != nil { 114 // Wrap err in quicError so that public reset is sent by session 115 return nil, qerr.Error(qerr.DecryptionFailure, err.Error()) 116 } 117 118 fs, err := u.parseFrames(decrypted, hdr) 119 if err != nil { 120 return nil, err 121 } 122 123 return &unpackedPacket{ 124 encryptionLevel: encryptionLevel, 125 frames: fs, 126 }, nil 127 }