github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/packet_packer.go (about)

     1  package quic
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"time"
     9  
    10  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/ackhandler"
    11  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/handshake"
    12  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol"
    13  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qerr"
    14  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/utils"
    15  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/wire"
    16  )
    17  
    18  type packer interface {
    19  	PackCoalescedPacket() (*coalescedPacket, error)
    20  	PackPacket() (*packedPacket, error)
    21  	MaybePackProbePacket(protocol.EncryptionLevel) (*packedPacket, error)
    22  	MaybePackAckPacket(handshakeConfirmed bool) (*packedPacket, error)
    23  	PackConnectionClose(*qerr.TransportError) (*coalescedPacket, error)
    24  	PackApplicationClose(*qerr.ApplicationError) (*coalescedPacket, error)
    25  
    26  	SetMaxPacketSize(protocol.ByteCount)
    27  	PackMTUProbePacket(ping ackhandler.Frame, size protocol.ByteCount) (*packedPacket, error)
    28  
    29  	HandleTransportParameters(*wire.TransportParameters)
    30  	SetToken([]byte)
    31  }
    32  
    33  type sealer interface {
    34  	handshake.LongHeaderSealer
    35  }
    36  
    37  type payload struct {
    38  	frames []ackhandler.Frame
    39  	ack    *wire.AckFrame
    40  	length protocol.ByteCount
    41  }
    42  
    43  type packedPacket struct {
    44  	buffer *packetBuffer
    45  	*packetContents
    46  }
    47  
    48  type packetContents struct {
    49  	header *wire.ExtendedHeader
    50  	ack    *wire.AckFrame
    51  	frames []ackhandler.Frame
    52  
    53  	length protocol.ByteCount
    54  
    55  	isMTUProbePacket bool
    56  }
    57  
    58  type coalescedPacket struct {
    59  	buffer  *packetBuffer
    60  	packets []*packetContents
    61  }
    62  
    63  func (p *packetContents) EncryptionLevel() protocol.EncryptionLevel {
    64  	if !p.header.IsLongHeader {
    65  		return protocol.Encryption1RTT
    66  	}
    67  	//nolint:exhaustive // Will never be called for Retry packets (and they don't have encrypted data).
    68  	switch p.header.Type {
    69  	case protocol.PacketTypeInitial:
    70  		return protocol.EncryptionInitial
    71  	case protocol.PacketTypeHandshake:
    72  		return protocol.EncryptionHandshake
    73  	case protocol.PacketType0RTT:
    74  		return protocol.Encryption0RTT
    75  	default:
    76  		panic("can't determine encryption level")
    77  	}
    78  }
    79  
    80  func (p *packetContents) IsAckEliciting() bool {
    81  	return ackhandler.HasAckElicitingFrames(p.frames)
    82  }
    83  
    84  func (p *packetContents) ToAckHandlerPacket(now time.Time, q *retransmissionQueue) *ackhandler.Packet {
    85  	largestAcked := protocol.InvalidPacketNumber
    86  	if p.ack != nil {
    87  		largestAcked = p.ack.LargestAcked()
    88  	}
    89  	encLevel := p.EncryptionLevel()
    90  	for i := range p.frames {
    91  		if p.frames[i].OnLost != nil {
    92  			continue
    93  		}
    94  		switch encLevel {
    95  		case protocol.EncryptionInitial:
    96  			p.frames[i].OnLost = q.AddInitial
    97  		case protocol.EncryptionHandshake:
    98  			p.frames[i].OnLost = q.AddHandshake
    99  		case protocol.Encryption0RTT, protocol.Encryption1RTT:
   100  			p.frames[i].OnLost = q.AddAppData
   101  		}
   102  	}
   103  	return &ackhandler.Packet{
   104  		PacketNumber:         p.header.PacketNumber,
   105  		LargestAcked:         largestAcked,
   106  		Frames:               p.frames,
   107  		Length:               p.length,
   108  		EncryptionLevel:      encLevel,
   109  		SendTime:             now,
   110  		IsPathMTUProbePacket: p.isMTUProbePacket,
   111  	}
   112  }
   113  
   114  func getMaxPacketSize(addr net.Addr, maxPacketSizeAdustment int) protocol.ByteCount {
   115  	maxSize := protocol.ByteCount(protocol.MinInitialPacketSize)
   116  	// If this is not a UDP address, we don't know anything about the MTU.
   117  	// Use the minimum size of an Initial packet as the max packet size.
   118  	if udpAddr, ok := addr.(*net.UDPAddr); ok {
   119  		if utils.IsIPv4(udpAddr.IP) {
   120  			maxSize = protocol.InitialPacketSizeIPv4
   121  		} else {
   122  			maxSize = protocol.InitialPacketSizeIPv6
   123  		}
   124  
   125  		// [Psiphon]
   126  		//
   127  		// Adjust the max packet size to allow for obfuscation overhead. This
   128  		// is a best-effort operation. In practice, maxPacketSizeAdustment
   129  		// will be tens of bytes and maxSize is over 1200 bytes; the
   130  		// condition here is a sanity check guard to prevent negative sizes
   131  		// and possible panics. We don't expect to need to make the largest
   132  		// adustment that would be possible when the condition is false.
   133  		//
   134  		// TODO: internal/congestion.cubicSender continues to use
   135  		// initialMaxDatagramSize = protocol.InitialPacketSizeIPv4
   136  		if maxSize > protocol.ByteCount(maxPacketSizeAdustment) {
   137  			maxSize -= protocol.ByteCount(maxPacketSizeAdustment)
   138  		}
   139  
   140  	}
   141  	return maxSize
   142  }
   143  
   144  type packetNumberManager interface {
   145  	PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)
   146  	PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber
   147  }
   148  
   149  type sealingManager interface {
   150  	GetInitialSealer() (handshake.LongHeaderSealer, error)
   151  	GetHandshakeSealer() (handshake.LongHeaderSealer, error)
   152  	Get0RTTSealer() (handshake.LongHeaderSealer, error)
   153  	Get1RTTSealer() (handshake.ShortHeaderSealer, error)
   154  }
   155  
   156  type frameSource interface {
   157  	HasData() bool
   158  	AppendStreamFrames([]ackhandler.Frame, protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount)
   159  	AppendControlFrames([]ackhandler.Frame, protocol.ByteCount) ([]ackhandler.Frame, protocol.ByteCount)
   160  }
   161  
   162  type ackFrameSource interface {
   163  	GetAckFrame(encLevel protocol.EncryptionLevel, onlyIfQueued bool) *wire.AckFrame
   164  }
   165  
   166  type packetPacker struct {
   167  	srcConnID     protocol.ConnectionID
   168  	getDestConnID func() protocol.ConnectionID
   169  
   170  	perspective protocol.Perspective
   171  	version     protocol.VersionNumber
   172  	cryptoSetup sealingManager
   173  
   174  	initialStream   cryptoStream
   175  	handshakeStream cryptoStream
   176  
   177  	token []byte
   178  
   179  	pnManager           packetNumberManager
   180  	framer              frameSource
   181  	acks                ackFrameSource
   182  	datagramQueue       *datagramQueue
   183  	retransmissionQueue *retransmissionQueue
   184  
   185  	maxPacketSize          protocol.ByteCount
   186  	numNonAckElicitingAcks int
   187  }
   188  
   189  var _ packer = &packetPacker{}
   190  
   191  func newPacketPacker(
   192  	srcConnID protocol.ConnectionID,
   193  	getDestConnID func() protocol.ConnectionID,
   194  	initialStream cryptoStream,
   195  	handshakeStream cryptoStream,
   196  	packetNumberManager packetNumberManager,
   197  	retransmissionQueue *retransmissionQueue,
   198  	remoteAddr net.Addr, // only used for determining the max packet size
   199  
   200  	// [Psiphon]
   201  	maxPacketSizeAdustment int,
   202  
   203  	cryptoSetup sealingManager,
   204  	framer frameSource,
   205  	acks ackFrameSource,
   206  	datagramQueue *datagramQueue,
   207  	perspective protocol.Perspective,
   208  	version protocol.VersionNumber,
   209  ) *packetPacker {
   210  	return &packetPacker{
   211  		cryptoSetup:         cryptoSetup,
   212  		getDestConnID:       getDestConnID,
   213  		srcConnID:           srcConnID,
   214  		initialStream:       initialStream,
   215  		handshakeStream:     handshakeStream,
   216  		retransmissionQueue: retransmissionQueue,
   217  		datagramQueue:       datagramQueue,
   218  		perspective:         perspective,
   219  		version:             version,
   220  		framer:              framer,
   221  		acks:                acks,
   222  		pnManager:           packetNumberManager,
   223  		maxPacketSize:       getMaxPacketSize(remoteAddr, maxPacketSizeAdustment),
   224  	}
   225  }
   226  
   227  // PackConnectionClose packs a packet that closes the connection with a transport error.
   228  func (p *packetPacker) PackConnectionClose(e *qerr.TransportError) (*coalescedPacket, error) {
   229  	var reason string
   230  	// don't send details of crypto errors
   231  	if !e.ErrorCode.IsCryptoError() {
   232  		reason = e.ErrorMessage
   233  	}
   234  	return p.packConnectionClose(false, uint64(e.ErrorCode), e.FrameType, reason)
   235  }
   236  
   237  // PackApplicationClose packs a packet that closes the connection with an application error.
   238  func (p *packetPacker) PackApplicationClose(e *qerr.ApplicationError) (*coalescedPacket, error) {
   239  	return p.packConnectionClose(true, uint64(e.ErrorCode), 0, e.ErrorMessage)
   240  }
   241  
   242  func (p *packetPacker) packConnectionClose(
   243  	isApplicationError bool,
   244  	errorCode uint64,
   245  	frameType uint64,
   246  	reason string,
   247  ) (*coalescedPacket, error) {
   248  	var sealers [4]sealer
   249  	var hdrs [4]*wire.ExtendedHeader
   250  	var payloads [4]*payload
   251  	var size protocol.ByteCount
   252  	var numPackets uint8
   253  	encLevels := [4]protocol.EncryptionLevel{protocol.EncryptionInitial, protocol.EncryptionHandshake, protocol.Encryption0RTT, protocol.Encryption1RTT}
   254  	for i, encLevel := range encLevels {
   255  		if p.perspective == protocol.PerspectiveServer && encLevel == protocol.Encryption0RTT {
   256  			continue
   257  		}
   258  		ccf := &wire.ConnectionCloseFrame{
   259  			IsApplicationError: isApplicationError,
   260  			ErrorCode:          errorCode,
   261  			FrameType:          frameType,
   262  			ReasonPhrase:       reason,
   263  		}
   264  		// don't send application errors in Initial or Handshake packets
   265  		if isApplicationError && (encLevel == protocol.EncryptionInitial || encLevel == protocol.EncryptionHandshake) {
   266  			ccf.IsApplicationError = false
   267  			ccf.ErrorCode = uint64(qerr.ApplicationErrorErrorCode)
   268  			ccf.ReasonPhrase = ""
   269  		}
   270  		payload := &payload{
   271  			frames: []ackhandler.Frame{{Frame: ccf}},
   272  			length: ccf.Length(p.version),
   273  		}
   274  
   275  		var sealer sealer
   276  		var err error
   277  		var keyPhase protocol.KeyPhaseBit // only set for 1-RTT
   278  		switch encLevel {
   279  		case protocol.EncryptionInitial:
   280  			sealer, err = p.cryptoSetup.GetInitialSealer()
   281  		case protocol.EncryptionHandshake:
   282  			sealer, err = p.cryptoSetup.GetHandshakeSealer()
   283  		case protocol.Encryption0RTT:
   284  			sealer, err = p.cryptoSetup.Get0RTTSealer()
   285  		case protocol.Encryption1RTT:
   286  			var s handshake.ShortHeaderSealer
   287  			s, err = p.cryptoSetup.Get1RTTSealer()
   288  			if err == nil {
   289  				keyPhase = s.KeyPhase()
   290  			}
   291  			sealer = s
   292  		}
   293  		if err == handshake.ErrKeysNotYetAvailable || err == handshake.ErrKeysDropped {
   294  			continue
   295  		}
   296  		if err != nil {
   297  			return nil, err
   298  		}
   299  		sealers[i] = sealer
   300  		var hdr *wire.ExtendedHeader
   301  		if encLevel == protocol.Encryption1RTT {
   302  			hdr = p.getShortHeader(keyPhase)
   303  		} else {
   304  			hdr = p.getLongHeader(encLevel)
   305  		}
   306  		hdrs[i] = hdr
   307  		payloads[i] = payload
   308  		size += p.packetLength(hdr, payload) + protocol.ByteCount(sealer.Overhead())
   309  		numPackets++
   310  	}
   311  	contents := make([]*packetContents, 0, numPackets)
   312  	buffer := getPacketBuffer()
   313  	for i, encLevel := range encLevels {
   314  		if sealers[i] == nil {
   315  			continue
   316  		}
   317  		var paddingLen protocol.ByteCount
   318  		if encLevel == protocol.EncryptionInitial {
   319  			paddingLen = p.initialPaddingLen(payloads[i].frames, size)
   320  		}
   321  		c, err := p.appendPacket(buffer, hdrs[i], payloads[i], paddingLen, encLevel, sealers[i], false)
   322  		if err != nil {
   323  			return nil, err
   324  		}
   325  		contents = append(contents, c)
   326  	}
   327  	return &coalescedPacket{buffer: buffer, packets: contents}, nil
   328  }
   329  
   330  // packetLength calculates the length of the serialized packet.
   331  // It takes into account that packets that have a tiny payload need to be padded,
   332  // such that len(payload) + packet number len >= 4 + AEAD overhead
   333  func (p *packetPacker) packetLength(hdr *wire.ExtendedHeader, payload *payload) protocol.ByteCount {
   334  	var paddingLen protocol.ByteCount
   335  	pnLen := protocol.ByteCount(hdr.PacketNumberLen)
   336  	if payload.length < 4-pnLen {
   337  		paddingLen = 4 - pnLen - payload.length
   338  	}
   339  	return hdr.GetLength(p.version) + payload.length + paddingLen
   340  }
   341  
   342  func (p *packetPacker) MaybePackAckPacket(handshakeConfirmed bool) (*packedPacket, error) {
   343  	var encLevel protocol.EncryptionLevel
   344  	var ack *wire.AckFrame
   345  	if !handshakeConfirmed {
   346  		ack = p.acks.GetAckFrame(protocol.EncryptionInitial, true)
   347  		if ack != nil {
   348  			encLevel = protocol.EncryptionInitial
   349  		} else {
   350  			ack = p.acks.GetAckFrame(protocol.EncryptionHandshake, true)
   351  			if ack != nil {
   352  				encLevel = protocol.EncryptionHandshake
   353  			}
   354  		}
   355  	}
   356  	if ack == nil {
   357  		ack = p.acks.GetAckFrame(protocol.Encryption1RTT, true)
   358  		if ack == nil {
   359  			return nil, nil
   360  		}
   361  		encLevel = protocol.Encryption1RTT
   362  	}
   363  	payload := &payload{
   364  		ack:    ack,
   365  		length: ack.Length(p.version),
   366  	}
   367  
   368  	sealer, hdr, err := p.getSealerAndHeader(encLevel)
   369  	if err != nil {
   370  		return nil, err
   371  	}
   372  	return p.writeSinglePacket(hdr, payload, encLevel, sealer)
   373  }
   374  
   375  // size is the expected size of the packet, if no padding was applied.
   376  func (p *packetPacker) initialPaddingLen(frames []ackhandler.Frame, size protocol.ByteCount) protocol.ByteCount {
   377  	// For the server, only ack-eliciting Initial packets need to be padded.
   378  	if p.perspective == protocol.PerspectiveServer && !ackhandler.HasAckElicitingFrames(frames) {
   379  		return 0
   380  	}
   381  	if size >= p.maxPacketSize {
   382  		return 0
   383  	}
   384  	return p.maxPacketSize - size
   385  }
   386  
   387  // PackCoalescedPacket packs a new packet.
   388  // It packs an Initial / Handshake if there is data to send in these packet number spaces.
   389  // It should only be called before the handshake is confirmed.
   390  func (p *packetPacker) PackCoalescedPacket() (*coalescedPacket, error) {
   391  	maxPacketSize := p.maxPacketSize
   392  	if p.perspective == protocol.PerspectiveClient {
   393  		maxPacketSize = protocol.MinInitialPacketSize
   394  	}
   395  	var initialHdr, handshakeHdr, appDataHdr *wire.ExtendedHeader
   396  	var initialPayload, handshakePayload, appDataPayload *payload
   397  	var numPackets int
   398  	// Try packing an Initial packet.
   399  	initialSealer, err := p.cryptoSetup.GetInitialSealer()
   400  	if err != nil && err != handshake.ErrKeysDropped {
   401  		return nil, err
   402  	}
   403  	var size protocol.ByteCount
   404  	if initialSealer != nil {
   405  		initialHdr, initialPayload = p.maybeGetCryptoPacket(maxPacketSize-protocol.ByteCount(initialSealer.Overhead()), size, protocol.EncryptionInitial)
   406  		if initialPayload != nil {
   407  			size += p.packetLength(initialHdr, initialPayload) + protocol.ByteCount(initialSealer.Overhead())
   408  			numPackets++
   409  		}
   410  	}
   411  
   412  	// Add a Handshake packet.
   413  	var handshakeSealer sealer
   414  	if size < maxPacketSize-protocol.MinCoalescedPacketSize {
   415  		var err error
   416  		handshakeSealer, err = p.cryptoSetup.GetHandshakeSealer()
   417  		if err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {
   418  			return nil, err
   419  		}
   420  		if handshakeSealer != nil {
   421  			handshakeHdr, handshakePayload = p.maybeGetCryptoPacket(maxPacketSize-size-protocol.ByteCount(handshakeSealer.Overhead()), size, protocol.EncryptionHandshake)
   422  			if handshakePayload != nil {
   423  				s := p.packetLength(handshakeHdr, handshakePayload) + protocol.ByteCount(handshakeSealer.Overhead())
   424  				size += s
   425  				numPackets++
   426  			}
   427  		}
   428  	}
   429  
   430  	// Add a 0-RTT / 1-RTT packet.
   431  	var appDataSealer sealer
   432  	appDataEncLevel := protocol.Encryption1RTT
   433  	if size < maxPacketSize-protocol.MinCoalescedPacketSize {
   434  		var err error
   435  		appDataSealer, appDataHdr, appDataPayload = p.maybeGetAppDataPacket(maxPacketSize-size, size)
   436  		if err != nil {
   437  			return nil, err
   438  		}
   439  		if appDataHdr != nil {
   440  			if appDataHdr.IsLongHeader {
   441  				appDataEncLevel = protocol.Encryption0RTT
   442  			}
   443  			if appDataPayload != nil {
   444  				size += p.packetLength(appDataHdr, appDataPayload) + protocol.ByteCount(appDataSealer.Overhead())
   445  				numPackets++
   446  			}
   447  		}
   448  	}
   449  
   450  	if numPackets == 0 {
   451  		return nil, nil
   452  	}
   453  
   454  	buffer := getPacketBuffer()
   455  	packet := &coalescedPacket{
   456  		buffer:  buffer,
   457  		packets: make([]*packetContents, 0, numPackets),
   458  	}
   459  	if initialPayload != nil {
   460  		padding := p.initialPaddingLen(initialPayload.frames, size)
   461  		cont, err := p.appendPacket(buffer, initialHdr, initialPayload, padding, protocol.EncryptionInitial, initialSealer, false)
   462  		if err != nil {
   463  			return nil, err
   464  		}
   465  		packet.packets = append(packet.packets, cont)
   466  	}
   467  	if handshakePayload != nil {
   468  		cont, err := p.appendPacket(buffer, handshakeHdr, handshakePayload, 0, protocol.EncryptionHandshake, handshakeSealer, false)
   469  		if err != nil {
   470  			return nil, err
   471  		}
   472  		packet.packets = append(packet.packets, cont)
   473  	}
   474  	if appDataPayload != nil {
   475  		cont, err := p.appendPacket(buffer, appDataHdr, appDataPayload, 0, appDataEncLevel, appDataSealer, false)
   476  		if err != nil {
   477  			return nil, err
   478  		}
   479  		packet.packets = append(packet.packets, cont)
   480  	}
   481  	return packet, nil
   482  }
   483  
   484  // PackPacket packs a packet in the application data packet number space.
   485  // It should be called after the handshake is confirmed.
   486  func (p *packetPacker) PackPacket() (*packedPacket, error) {
   487  	sealer, hdr, payload := p.maybeGetAppDataPacket(p.maxPacketSize, 0)
   488  	if payload == nil {
   489  		return nil, nil
   490  	}
   491  	buffer := getPacketBuffer()
   492  	encLevel := protocol.Encryption1RTT
   493  	if hdr.IsLongHeader {
   494  		encLevel = protocol.Encryption0RTT
   495  	}
   496  	cont, err := p.appendPacket(buffer, hdr, payload, 0, encLevel, sealer, false)
   497  	if err != nil {
   498  		return nil, err
   499  	}
   500  	return &packedPacket{
   501  		buffer:         buffer,
   502  		packetContents: cont,
   503  	}, nil
   504  }
   505  
   506  func (p *packetPacker) maybeGetCryptoPacket(maxPacketSize, currentSize protocol.ByteCount, encLevel protocol.EncryptionLevel) (*wire.ExtendedHeader, *payload) {
   507  	var s cryptoStream
   508  	var hasRetransmission bool
   509  	//nolint:exhaustive // Initial and Handshake are the only two encryption levels here.
   510  	switch encLevel {
   511  	case protocol.EncryptionInitial:
   512  		s = p.initialStream
   513  		hasRetransmission = p.retransmissionQueue.HasInitialData()
   514  	case protocol.EncryptionHandshake:
   515  		s = p.handshakeStream
   516  		hasRetransmission = p.retransmissionQueue.HasHandshakeData()
   517  	}
   518  
   519  	hasData := s.HasData()
   520  	var ack *wire.AckFrame
   521  	if encLevel == protocol.EncryptionInitial || currentSize == 0 {
   522  		ack = p.acks.GetAckFrame(encLevel, !hasRetransmission && !hasData)
   523  	}
   524  	if !hasData && !hasRetransmission && ack == nil {
   525  		// nothing to send
   526  		return nil, nil
   527  	}
   528  
   529  	var payload payload
   530  	if ack != nil {
   531  		payload.ack = ack
   532  		payload.length = ack.Length(p.version)
   533  		maxPacketSize -= payload.length
   534  	}
   535  	hdr := p.getLongHeader(encLevel)
   536  	maxPacketSize -= hdr.GetLength(p.version)
   537  	if hasRetransmission {
   538  		for {
   539  			var f wire.Frame
   540  			//nolint:exhaustive // 0-RTT packets can't contain any retransmission.s
   541  			switch encLevel {
   542  			case protocol.EncryptionInitial:
   543  				f = p.retransmissionQueue.GetInitialFrame(maxPacketSize)
   544  			case protocol.EncryptionHandshake:
   545  				f = p.retransmissionQueue.GetHandshakeFrame(maxPacketSize)
   546  			}
   547  			if f == nil {
   548  				break
   549  			}
   550  			payload.frames = append(payload.frames, ackhandler.Frame{Frame: f})
   551  			frameLen := f.Length(p.version)
   552  			payload.length += frameLen
   553  			maxPacketSize -= frameLen
   554  		}
   555  	} else if s.HasData() {
   556  		cf := s.PopCryptoFrame(maxPacketSize)
   557  		payload.frames = []ackhandler.Frame{{Frame: cf}}
   558  		payload.length += cf.Length(p.version)
   559  	}
   560  	return hdr, &payload
   561  }
   562  
   563  func (p *packetPacker) maybeGetAppDataPacket(maxPacketSize, currentSize protocol.ByteCount) (sealer, *wire.ExtendedHeader, *payload) {
   564  	var sealer sealer
   565  	var encLevel protocol.EncryptionLevel
   566  	var hdr *wire.ExtendedHeader
   567  	oneRTTSealer, err := p.cryptoSetup.Get1RTTSealer()
   568  	if err == nil {
   569  		encLevel = protocol.Encryption1RTT
   570  		sealer = oneRTTSealer
   571  		hdr = p.getShortHeader(oneRTTSealer.KeyPhase())
   572  	} else {
   573  		// 1-RTT sealer not yet available
   574  		if p.perspective != protocol.PerspectiveClient {
   575  			return nil, nil, nil
   576  		}
   577  		sealer, err = p.cryptoSetup.Get0RTTSealer()
   578  		if sealer == nil || err != nil {
   579  			return nil, nil, nil
   580  		}
   581  		encLevel = protocol.Encryption0RTT
   582  		hdr = p.getLongHeader(protocol.Encryption0RTT)
   583  	}
   584  
   585  	maxPayloadSize := maxPacketSize - hdr.GetLength(p.version) - protocol.ByteCount(sealer.Overhead())
   586  	payload := p.maybeGetAppDataPacketWithEncLevel(maxPayloadSize, encLevel == protocol.Encryption1RTT && currentSize == 0)
   587  	return sealer, hdr, payload
   588  }
   589  
   590  func (p *packetPacker) maybeGetAppDataPacketWithEncLevel(maxPayloadSize protocol.ByteCount, ackAllowed bool) *payload {
   591  	payload := p.composeNextPacket(maxPayloadSize, ackAllowed)
   592  
   593  	// check if we have anything to send
   594  	if len(payload.frames) == 0 {
   595  		if payload.ack == nil {
   596  			return nil
   597  		}
   598  		// the packet only contains an ACK
   599  		if p.numNonAckElicitingAcks >= protocol.MaxNonAckElicitingAcks {
   600  			ping := &wire.PingFrame{}
   601  			// don't retransmit the PING frame when it is lost
   602  			payload.frames = append(payload.frames, ackhandler.Frame{Frame: ping, OnLost: func(wire.Frame) {}})
   603  			payload.length += ping.Length(p.version)
   604  			p.numNonAckElicitingAcks = 0
   605  		} else {
   606  			p.numNonAckElicitingAcks++
   607  		}
   608  	} else {
   609  		p.numNonAckElicitingAcks = 0
   610  	}
   611  	return payload
   612  }
   613  
   614  func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount, ackAllowed bool) *payload {
   615  	payload := &payload{frames: make([]ackhandler.Frame, 0, 1)}
   616  
   617  	var hasDatagram bool
   618  	if p.datagramQueue != nil {
   619  		if datagram := p.datagramQueue.Get(); datagram != nil {
   620  			payload.frames = append(payload.frames, ackhandler.Frame{
   621  				Frame: datagram,
   622  				// set it to a no-op. Then we won't set the default callback, which would retransmit the frame.
   623  				OnLost: func(wire.Frame) {},
   624  			})
   625  			payload.length += datagram.Length(p.version)
   626  			hasDatagram = true
   627  		}
   628  	}
   629  
   630  	var ack *wire.AckFrame
   631  	hasData := p.framer.HasData()
   632  	hasRetransmission := p.retransmissionQueue.HasAppData()
   633  	// TODO: make sure ACKs are sent when a lot of DATAGRAMs are queued
   634  	if !hasDatagram && ackAllowed {
   635  		ack = p.acks.GetAckFrame(protocol.Encryption1RTT, !hasRetransmission && !hasData)
   636  		if ack != nil {
   637  			payload.ack = ack
   638  			payload.length += ack.Length(p.version)
   639  		}
   640  	}
   641  
   642  	if ack == nil && !hasData && !hasRetransmission {
   643  		return payload
   644  	}
   645  
   646  	if hasRetransmission {
   647  		for {
   648  			remainingLen := maxFrameSize - payload.length
   649  			if remainingLen < protocol.MinStreamFrameSize {
   650  				break
   651  			}
   652  			f := p.retransmissionQueue.GetAppDataFrame(remainingLen)
   653  			if f == nil {
   654  				break
   655  			}
   656  			payload.frames = append(payload.frames, ackhandler.Frame{Frame: f})
   657  			payload.length += f.Length(p.version)
   658  		}
   659  	}
   660  
   661  	if hasData {
   662  		var lengthAdded protocol.ByteCount
   663  		payload.frames, lengthAdded = p.framer.AppendControlFrames(payload.frames, maxFrameSize-payload.length)
   664  		payload.length += lengthAdded
   665  
   666  		payload.frames, lengthAdded = p.framer.AppendStreamFrames(payload.frames, maxFrameSize-payload.length)
   667  		payload.length += lengthAdded
   668  	}
   669  	return payload
   670  }
   671  
   672  func (p *packetPacker) MaybePackProbePacket(encLevel protocol.EncryptionLevel) (*packedPacket, error) {
   673  	var hdr *wire.ExtendedHeader
   674  	var payload *payload
   675  	var sealer sealer
   676  	//nolint:exhaustive // Probe packets are never sent for 0-RTT.
   677  	switch encLevel {
   678  	case protocol.EncryptionInitial:
   679  		var err error
   680  		sealer, err = p.cryptoSetup.GetInitialSealer()
   681  		if err != nil {
   682  			return nil, err
   683  		}
   684  		hdr, payload = p.maybeGetCryptoPacket(p.maxPacketSize-protocol.ByteCount(sealer.Overhead()), 0, protocol.EncryptionInitial)
   685  	case protocol.EncryptionHandshake:
   686  		var err error
   687  		sealer, err = p.cryptoSetup.GetHandshakeSealer()
   688  		if err != nil {
   689  			return nil, err
   690  		}
   691  		hdr, payload = p.maybeGetCryptoPacket(p.maxPacketSize-protocol.ByteCount(sealer.Overhead()), 0, protocol.EncryptionHandshake)
   692  	case protocol.Encryption1RTT:
   693  		oneRTTSealer, err := p.cryptoSetup.Get1RTTSealer()
   694  		if err != nil {
   695  			return nil, err
   696  		}
   697  		sealer = oneRTTSealer
   698  		hdr = p.getShortHeader(oneRTTSealer.KeyPhase())
   699  		payload = p.maybeGetAppDataPacketWithEncLevel(p.maxPacketSize-protocol.ByteCount(sealer.Overhead())-hdr.GetLength(p.version), true)
   700  	default:
   701  		panic("unknown encryption level")
   702  	}
   703  	if payload == nil {
   704  		return nil, nil
   705  	}
   706  	size := p.packetLength(hdr, payload) + protocol.ByteCount(sealer.Overhead())
   707  	var padding protocol.ByteCount
   708  	if encLevel == protocol.EncryptionInitial {
   709  		padding = p.initialPaddingLen(payload.frames, size)
   710  	}
   711  	buffer := getPacketBuffer()
   712  	cont, err := p.appendPacket(buffer, hdr, payload, padding, encLevel, sealer, false)
   713  	if err != nil {
   714  		return nil, err
   715  	}
   716  	return &packedPacket{
   717  		buffer:         buffer,
   718  		packetContents: cont,
   719  	}, nil
   720  }
   721  
   722  func (p *packetPacker) PackMTUProbePacket(ping ackhandler.Frame, size protocol.ByteCount) (*packedPacket, error) {
   723  	payload := &payload{
   724  		frames: []ackhandler.Frame{ping},
   725  		length: ping.Length(p.version),
   726  	}
   727  	buffer := getPacketBuffer()
   728  	sealer, err := p.cryptoSetup.Get1RTTSealer()
   729  	if err != nil {
   730  		return nil, err
   731  	}
   732  	hdr := p.getShortHeader(sealer.KeyPhase())
   733  	padding := size - p.packetLength(hdr, payload) - protocol.ByteCount(sealer.Overhead())
   734  	contents, err := p.appendPacket(buffer, hdr, payload, padding, protocol.Encryption1RTT, sealer, true)
   735  	if err != nil {
   736  		return nil, err
   737  	}
   738  	contents.isMTUProbePacket = true
   739  	return &packedPacket{
   740  		buffer:         buffer,
   741  		packetContents: contents,
   742  	}, nil
   743  }
   744  
   745  func (p *packetPacker) getSealerAndHeader(encLevel protocol.EncryptionLevel) (sealer, *wire.ExtendedHeader, error) {
   746  	switch encLevel {
   747  	case protocol.EncryptionInitial:
   748  		sealer, err := p.cryptoSetup.GetInitialSealer()
   749  		if err != nil {
   750  			return nil, nil, err
   751  		}
   752  		hdr := p.getLongHeader(protocol.EncryptionInitial)
   753  		return sealer, hdr, nil
   754  	case protocol.Encryption0RTT:
   755  		sealer, err := p.cryptoSetup.Get0RTTSealer()
   756  		if err != nil {
   757  			return nil, nil, err
   758  		}
   759  		hdr := p.getLongHeader(protocol.Encryption0RTT)
   760  		return sealer, hdr, nil
   761  	case protocol.EncryptionHandshake:
   762  		sealer, err := p.cryptoSetup.GetHandshakeSealer()
   763  		if err != nil {
   764  			return nil, nil, err
   765  		}
   766  		hdr := p.getLongHeader(protocol.EncryptionHandshake)
   767  		return sealer, hdr, nil
   768  	case protocol.Encryption1RTT:
   769  		sealer, err := p.cryptoSetup.Get1RTTSealer()
   770  		if err != nil {
   771  			return nil, nil, err
   772  		}
   773  		hdr := p.getShortHeader(sealer.KeyPhase())
   774  		return sealer, hdr, nil
   775  	default:
   776  		return nil, nil, fmt.Errorf("unexpected encryption level: %s", encLevel)
   777  	}
   778  }
   779  
   780  func (p *packetPacker) getShortHeader(kp protocol.KeyPhaseBit) *wire.ExtendedHeader {
   781  	pn, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)
   782  	hdr := &wire.ExtendedHeader{}
   783  	hdr.PacketNumber = pn
   784  	hdr.PacketNumberLen = pnLen
   785  	hdr.DestConnectionID = p.getDestConnID()
   786  	hdr.KeyPhase = kp
   787  	return hdr
   788  }
   789  
   790  func (p *packetPacker) getLongHeader(encLevel protocol.EncryptionLevel) *wire.ExtendedHeader {
   791  	pn, pnLen := p.pnManager.PeekPacketNumber(encLevel)
   792  	hdr := &wire.ExtendedHeader{
   793  		PacketNumber:    pn,
   794  		PacketNumberLen: pnLen,
   795  	}
   796  	hdr.IsLongHeader = true
   797  	hdr.Version = p.version
   798  	hdr.SrcConnectionID = p.srcConnID
   799  	hdr.DestConnectionID = p.getDestConnID()
   800  
   801  	//nolint:exhaustive // 1-RTT packets are not long header packets.
   802  	switch encLevel {
   803  	case protocol.EncryptionInitial:
   804  		hdr.Type = protocol.PacketTypeInitial
   805  		hdr.Token = p.token
   806  	case protocol.EncryptionHandshake:
   807  		hdr.Type = protocol.PacketTypeHandshake
   808  	case protocol.Encryption0RTT:
   809  		hdr.Type = protocol.PacketType0RTT
   810  	}
   811  	return hdr
   812  }
   813  
   814  // writeSinglePacket packs a single packet.
   815  func (p *packetPacker) writeSinglePacket(
   816  	hdr *wire.ExtendedHeader,
   817  	payload *payload,
   818  	encLevel protocol.EncryptionLevel,
   819  	sealer sealer,
   820  ) (*packedPacket, error) {
   821  	buffer := getPacketBuffer()
   822  	var paddingLen protocol.ByteCount
   823  	if encLevel == protocol.EncryptionInitial {
   824  		paddingLen = p.initialPaddingLen(payload.frames, hdr.GetLength(p.version)+payload.length+protocol.ByteCount(sealer.Overhead()))
   825  	}
   826  	contents, err := p.appendPacket(buffer, hdr, payload, paddingLen, encLevel, sealer, false)
   827  	if err != nil {
   828  		return nil, err
   829  	}
   830  	return &packedPacket{
   831  		buffer:         buffer,
   832  		packetContents: contents,
   833  	}, nil
   834  }
   835  
   836  func (p *packetPacker) appendPacket(buffer *packetBuffer, header *wire.ExtendedHeader, payload *payload, padding protocol.ByteCount, encLevel protocol.EncryptionLevel, sealer sealer, isMTUProbePacket bool) (*packetContents, error) {
   837  	var paddingLen protocol.ByteCount
   838  	pnLen := protocol.ByteCount(header.PacketNumberLen)
   839  	if payload.length < 4-pnLen {
   840  		paddingLen = 4 - pnLen - payload.length
   841  	}
   842  	paddingLen += padding
   843  	if header.IsLongHeader {
   844  		header.Length = pnLen + protocol.ByteCount(sealer.Overhead()) + payload.length + paddingLen
   845  	}
   846  
   847  	hdrOffset := buffer.Len()
   848  	buf := bytes.NewBuffer(buffer.Data)
   849  	if err := header.Write(buf, p.version); err != nil {
   850  		return nil, err
   851  	}
   852  	payloadOffset := buf.Len()
   853  
   854  	if payload.ack != nil {
   855  		if err := payload.ack.Write(buf, p.version); err != nil {
   856  			return nil, err
   857  		}
   858  	}
   859  	if paddingLen > 0 {
   860  		buf.Write(make([]byte, paddingLen))
   861  	}
   862  	for _, frame := range payload.frames {
   863  		if err := frame.Write(buf, p.version); err != nil {
   864  			return nil, err
   865  		}
   866  	}
   867  
   868  	if payloadSize := protocol.ByteCount(buf.Len()-payloadOffset) - paddingLen; payloadSize != payload.length {
   869  		return nil, fmt.Errorf("PacketPacker BUG: payload size inconsistent (expected %d, got %d bytes)", payload.length, payloadSize)
   870  	}
   871  	if !isMTUProbePacket {
   872  		if size := protocol.ByteCount(buf.Len() + sealer.Overhead()); size > p.maxPacketSize {
   873  			return nil, fmt.Errorf("PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)", size, p.maxPacketSize)
   874  		}
   875  	}
   876  
   877  	raw := buffer.Data
   878  	// encrypt the packet
   879  	raw = raw[:buf.Len()]
   880  	_ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], header.PacketNumber, raw[hdrOffset:payloadOffset])
   881  	raw = raw[0 : buf.Len()+sealer.Overhead()]
   882  	// apply header protection
   883  	pnOffset := payloadOffset - int(header.PacketNumberLen)
   884  	sealer.EncryptHeader(raw[pnOffset+4:pnOffset+4+16], &raw[hdrOffset], raw[pnOffset:payloadOffset])
   885  	buffer.Data = raw
   886  
   887  	num := p.pnManager.PopPacketNumber(encLevel)
   888  	if num != header.PacketNumber {
   889  		return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
   890  	}
   891  	return &packetContents{
   892  		header: header,
   893  		ack:    payload.ack,
   894  		frames: payload.frames,
   895  		length: buffer.Len() - hdrOffset,
   896  	}, nil
   897  }
   898  
   899  func (p *packetPacker) SetToken(token []byte) {
   900  	p.token = token
   901  }
   902  
   903  // When a higher MTU is discovered, use it.
   904  func (p *packetPacker) SetMaxPacketSize(s protocol.ByteCount) {
   905  	p.maxPacketSize = s
   906  }
   907  
   908  // If the peer sets a max_packet_size that's smaller than the size we're currently using,
   909  // we need to reduce the size of packets we send.
   910  func (p *packetPacker) HandleTransportParameters(params *wire.TransportParameters) {
   911  	if params.MaxUDPPayloadSize != 0 {
   912  		p.maxPacketSize = utils.MinByteCount(p.maxPacketSize, params.MaxUDPPayloadSize)
   913  	}
   914  }