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 }