github.com/metacubex/quic-go@v0.44.1-0.20240520163451-20b689a59136/packet_packer.go (about)

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