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