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