github.com/sagernet/quic-go@v0.43.1-beta.1/ech/packet_packer.go (about)

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