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