github.com/tumi8/quic-go@v0.37.4-tum/packet_packer.go (about)

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