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