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