packet_unpacker.go 3.3 KB

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