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  }