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