github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/session.go (about) 1 package quic 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/tls" 7 "errors" 8 "fmt" 9 "io" 10 "net" 11 "reflect" 12 "sync" 13 "sync/atomic" 14 "time" 15 16 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/ackhandler" 17 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/flowcontrol" 18 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/handshake" 19 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/logutils" 20 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol" 21 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qerr" 22 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/utils" 23 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/wire" 24 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/logging" 25 ) 26 27 type unpacker interface { 28 Unpack(hdr *wire.Header, rcvTime time.Time, data []byte) (*unpackedPacket, error) 29 } 30 31 type streamGetter interface { 32 GetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error) 33 GetOrOpenSendStream(protocol.StreamID) (sendStreamI, error) 34 } 35 36 type streamManager interface { 37 GetOrOpenSendStream(protocol.StreamID) (sendStreamI, error) 38 GetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error) 39 OpenStream() (Stream, error) 40 OpenUniStream() (SendStream, error) 41 OpenStreamSync(context.Context) (Stream, error) 42 OpenUniStreamSync(context.Context) (SendStream, error) 43 AcceptStream(context.Context) (Stream, error) 44 AcceptUniStream(context.Context) (ReceiveStream, error) 45 DeleteStream(protocol.StreamID) error 46 UpdateLimits(*wire.TransportParameters) 47 HandleMaxStreamsFrame(*wire.MaxStreamsFrame) 48 CloseWithError(error) 49 ResetFor0RTT() 50 UseResetMaps() 51 } 52 53 type cryptoStreamHandler interface { 54 RunHandshake() 55 ChangeConnectionID(protocol.ConnectionID) 56 SetLargest1RTTAcked(protocol.PacketNumber) error 57 SetHandshakeConfirmed() 58 GetSessionTicket() ([]byte, error) 59 io.Closer 60 ConnectionState() handshake.ConnectionState 61 } 62 63 type packetInfo struct { 64 addr net.IP 65 ifIndex uint32 66 } 67 68 type receivedPacket struct { 69 buffer *packetBuffer 70 71 remoteAddr net.Addr 72 rcvTime time.Time 73 data []byte 74 75 ecn protocol.ECN 76 77 info *packetInfo 78 } 79 80 func (p *receivedPacket) Size() protocol.ByteCount { return protocol.ByteCount(len(p.data)) } 81 82 func (p *receivedPacket) Clone() *receivedPacket { 83 return &receivedPacket{ 84 remoteAddr: p.remoteAddr, 85 rcvTime: p.rcvTime, 86 data: p.data, 87 buffer: p.buffer, 88 ecn: p.ecn, 89 info: p.info, 90 } 91 } 92 93 type sessionRunner interface { 94 Add(protocol.ConnectionID, packetHandler) bool 95 GetStatelessResetToken(protocol.ConnectionID) protocol.StatelessResetToken 96 Retire(protocol.ConnectionID) 97 Remove(protocol.ConnectionID) 98 ReplaceWithClosed(protocol.ConnectionID, packetHandler) 99 AddResetToken(protocol.StatelessResetToken, packetHandler) 100 RemoveResetToken(protocol.StatelessResetToken) 101 } 102 103 type handshakeRunner struct { 104 onReceivedParams func(*wire.TransportParameters) 105 onError func(error) 106 dropKeys func(protocol.EncryptionLevel) 107 onHandshakeComplete func() 108 } 109 110 func (r *handshakeRunner) OnReceivedParams(tp *wire.TransportParameters) { r.onReceivedParams(tp) } 111 func (r *handshakeRunner) OnError(e error) { r.onError(e) } 112 func (r *handshakeRunner) DropKeys(el protocol.EncryptionLevel) { r.dropKeys(el) } 113 func (r *handshakeRunner) OnHandshakeComplete() { r.onHandshakeComplete() } 114 115 type closeError struct { 116 err error 117 remote bool 118 immediate bool 119 } 120 121 type errCloseForRecreating struct { 122 nextPacketNumber protocol.PacketNumber 123 nextVersion protocol.VersionNumber 124 } 125 126 func (e *errCloseForRecreating) Error() string { 127 return "closing session in order to recreate it" 128 } 129 130 var sessionTracingID uint64 // to be accessed atomically 131 func nextSessionTracingID() uint64 { return atomic.AddUint64(&sessionTracingID, 1) } 132 133 // A Session is a QUIC session 134 type session struct { 135 // Destination connection ID used during the handshake. 136 // Used to check source connection ID on incoming packets. 137 handshakeDestConnID protocol.ConnectionID 138 // Set for the client. Destination connection ID used on the first Initial sent. 139 origDestConnID protocol.ConnectionID 140 retrySrcConnID *protocol.ConnectionID // only set for the client (and if a Retry was performed) 141 142 srcConnIDLen int 143 144 perspective protocol.Perspective 145 version protocol.VersionNumber 146 config *Config 147 148 conn sendConn 149 sendQueue sender 150 151 streamsMap streamManager 152 connIDManager *connIDManager 153 connIDGenerator *connIDGenerator 154 155 rttStats *utils.RTTStats 156 157 cryptoStreamManager *cryptoStreamManager 158 sentPacketHandler ackhandler.SentPacketHandler 159 receivedPacketHandler ackhandler.ReceivedPacketHandler 160 retransmissionQueue *retransmissionQueue 161 framer framer 162 windowUpdateQueue *windowUpdateQueue 163 connFlowController flowcontrol.ConnectionFlowController 164 tokenStoreKey string // only set for the client 165 tokenGenerator *handshake.TokenGenerator // only set for the server 166 167 unpacker unpacker 168 frameParser wire.FrameParser 169 packer packer 170 mtuDiscoverer mtuDiscoverer // initialized when the handshake completes 171 172 oneRTTStream cryptoStream // only set for the server 173 cryptoStreamHandler cryptoStreamHandler 174 175 receivedPackets chan *receivedPacket 176 sendingScheduled chan struct{} 177 178 closeOnce sync.Once 179 // closeChan is used to notify the run loop that it should terminate 180 closeChan chan closeError 181 182 ctx context.Context 183 ctxCancel context.CancelFunc 184 handshakeCtx context.Context 185 handshakeCtxCancel context.CancelFunc 186 187 undecryptablePackets []*receivedPacket // undecryptable packets, waiting for a change in encryption level 188 undecryptablePacketsToProcess []*receivedPacket 189 190 clientHelloWritten <-chan *wire.TransportParameters 191 earlySessionReadyChan chan struct{} 192 handshakeCompleteChan chan struct{} // is closed when the handshake completes 193 handshakeComplete bool 194 handshakeConfirmed bool 195 196 receivedRetry bool 197 versionNegotiated bool 198 receivedFirstPacket bool 199 200 idleTimeout time.Duration 201 sessionCreationTime time.Time 202 // The idle timeout is set based on the max of the time we received the last packet... 203 lastPacketReceivedTime time.Time 204 // ... and the time we sent a new ack-eliciting packet after receiving a packet. 205 firstAckElicitingPacketAfterIdleSentTime time.Time 206 // pacingDeadline is the time when the next packet should be sent 207 pacingDeadline time.Time 208 209 peerParams *wire.TransportParameters 210 211 timer *utils.Timer 212 // keepAlivePingSent stores whether a keep alive PING is in flight. 213 // It is reset as soon as we receive a packet from the peer. 214 keepAlivePingSent bool 215 keepAliveInterval time.Duration 216 217 datagramQueue *datagramQueue 218 219 logID string 220 tracer logging.ConnectionTracer 221 logger utils.Logger 222 } 223 224 var ( 225 _ Session = &session{} 226 _ EarlySession = &session{} 227 _ streamSender = &session{} 228 deadlineSendImmediately = time.Time{}.Add(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine 229 ) 230 231 var newSession = func( 232 conn sendConn, 233 runner sessionRunner, 234 origDestConnID protocol.ConnectionID, 235 retrySrcConnID *protocol.ConnectionID, 236 clientDestConnID protocol.ConnectionID, 237 destConnID protocol.ConnectionID, 238 srcConnID protocol.ConnectionID, 239 statelessResetToken protocol.StatelessResetToken, 240 conf *Config, 241 tlsConf *tls.Config, 242 tokenGenerator *handshake.TokenGenerator, 243 enable0RTT bool, 244 tracer logging.ConnectionTracer, 245 tracingID uint64, 246 logger utils.Logger, 247 v protocol.VersionNumber, 248 ) quicSession { 249 s := &session{ 250 conn: conn, 251 config: conf, 252 handshakeDestConnID: destConnID, 253 srcConnIDLen: srcConnID.Len(), 254 tokenGenerator: tokenGenerator, 255 oneRTTStream: newCryptoStream(), 256 perspective: protocol.PerspectiveServer, 257 handshakeCompleteChan: make(chan struct{}), 258 tracer: tracer, 259 logger: logger, 260 version: v, 261 } 262 if origDestConnID != nil { 263 s.logID = origDestConnID.String() 264 } else { 265 s.logID = destConnID.String() 266 } 267 s.connIDManager = newConnIDManager( 268 destConnID, 269 func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) }, 270 runner.RemoveResetToken, 271 s.queueControlFrame, 272 ) 273 s.connIDGenerator = newConnIDGenerator( 274 srcConnID, 275 clientDestConnID, 276 func(connID protocol.ConnectionID) { runner.Add(connID, s) }, 277 runner.GetStatelessResetToken, 278 runner.Remove, 279 runner.Retire, 280 runner.ReplaceWithClosed, 281 s.queueControlFrame, 282 s.version, 283 ) 284 s.preSetup() 285 s.ctx, s.ctxCancel = context.WithCancel(context.WithValue(context.Background(), SessionTracingKey, tracingID)) 286 287 // [Psiphon] 288 maxPacketSizeAdjustment := 0 289 if conf.ServerMaxPacketSizeAdjustment != nil { 290 maxPacketSizeAdjustment = conf.ServerMaxPacketSizeAdjustment(s.RemoteAddr()) 291 } 292 293 s.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler( 294 0, 295 getMaxPacketSize(s.conn.RemoteAddr(), maxPacketSizeAdjustment), 296 s.rttStats, 297 s.perspective, 298 s.tracer, 299 s.logger, 300 s.version, 301 ) 302 initialStream := newCryptoStream() 303 handshakeStream := newCryptoStream() 304 params := &wire.TransportParameters{ 305 InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow), 306 InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow), 307 InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamReceiveWindow), 308 InitialMaxData: protocol.ByteCount(s.config.InitialConnectionReceiveWindow), 309 MaxIdleTimeout: s.config.MaxIdleTimeout, 310 MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams), 311 MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams), 312 MaxAckDelay: protocol.MaxAckDelayInclGranularity, 313 AckDelayExponent: protocol.AckDelayExponent, 314 DisableActiveMigration: true, 315 StatelessResetToken: &statelessResetToken, 316 OriginalDestinationConnectionID: origDestConnID, 317 ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs, 318 InitialSourceConnectionID: srcConnID, 319 RetrySourceConnectionID: retrySrcConnID, 320 } 321 if s.config.EnableDatagrams { 322 params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize 323 } 324 if s.tracer != nil { 325 s.tracer.SentTransportParameters(params) 326 } 327 cs := handshake.NewCryptoSetupServer( 328 initialStream, 329 handshakeStream, 330 clientDestConnID, 331 conn.LocalAddr(), 332 conn.RemoteAddr(), 333 params, 334 &handshakeRunner{ 335 onReceivedParams: s.handleTransportParameters, 336 onError: s.closeLocal, 337 dropKeys: s.dropEncryptionLevel, 338 onHandshakeComplete: func() { 339 runner.Retire(clientDestConnID) 340 close(s.handshakeCompleteChan) 341 }, 342 }, 343 tlsConf, 344 enable0RTT, 345 s.rttStats, 346 tracer, 347 logger, 348 s.version, 349 ) 350 s.cryptoStreamHandler = cs 351 s.packer = newPacketPacker( 352 srcConnID, 353 s.connIDManager.Get, 354 initialStream, 355 handshakeStream, 356 s.sentPacketHandler, 357 s.retransmissionQueue, 358 s.RemoteAddr(), 359 360 // [Psiphon] 361 maxPacketSizeAdjustment, 362 363 cs, 364 s.framer, 365 s.receivedPacketHandler, 366 s.datagramQueue, 367 s.perspective, 368 s.version, 369 ) 370 s.unpacker = newPacketUnpacker(cs, s.version) 371 s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream, s.oneRTTStream) 372 return s 373 } 374 375 // declare this as a variable, such that we can it mock it in the tests 376 var newClientSession = func( 377 conn sendConn, 378 runner sessionRunner, 379 destConnID protocol.ConnectionID, 380 srcConnID protocol.ConnectionID, 381 conf *Config, 382 tlsConf *tls.Config, 383 initialPacketNumber protocol.PacketNumber, 384 enable0RTT bool, 385 hasNegotiatedVersion bool, 386 tracer logging.ConnectionTracer, 387 tracingID uint64, 388 logger utils.Logger, 389 v protocol.VersionNumber, 390 ) quicSession { 391 s := &session{ 392 conn: conn, 393 config: conf, 394 origDestConnID: destConnID, 395 handshakeDestConnID: destConnID, 396 srcConnIDLen: srcConnID.Len(), 397 perspective: protocol.PerspectiveClient, 398 handshakeCompleteChan: make(chan struct{}), 399 logID: destConnID.String(), 400 logger: logger, 401 tracer: tracer, 402 versionNegotiated: hasNegotiatedVersion, 403 version: v, 404 } 405 s.connIDManager = newConnIDManager( 406 destConnID, 407 func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) }, 408 runner.RemoveResetToken, 409 s.queueControlFrame, 410 ) 411 s.connIDGenerator = newConnIDGenerator( 412 srcConnID, 413 nil, 414 func(connID protocol.ConnectionID) { runner.Add(connID, s) }, 415 runner.GetStatelessResetToken, 416 runner.Remove, 417 runner.Retire, 418 runner.ReplaceWithClosed, 419 s.queueControlFrame, 420 s.version, 421 ) 422 s.preSetup() 423 s.ctx, s.ctxCancel = context.WithCancel(context.WithValue(context.Background(), SessionTracingKey, tracingID)) 424 s.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler( 425 initialPacketNumber, 426 427 // [Psiphon] 428 getMaxPacketSize(s.conn.RemoteAddr(), conf.ClientMaxPacketSizeAdjustment), 429 430 s.rttStats, 431 s.perspective, 432 s.tracer, 433 s.logger, 434 s.version, 435 ) 436 initialStream := newCryptoStream() 437 handshakeStream := newCryptoStream() 438 params := &wire.TransportParameters{ 439 InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow), 440 InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow), 441 InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamReceiveWindow), 442 InitialMaxData: protocol.ByteCount(s.config.InitialConnectionReceiveWindow), 443 MaxIdleTimeout: s.config.MaxIdleTimeout, 444 MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams), 445 MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams), 446 MaxAckDelay: protocol.MaxAckDelayInclGranularity, 447 AckDelayExponent: protocol.AckDelayExponent, 448 DisableActiveMigration: true, 449 ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs, 450 InitialSourceConnectionID: srcConnID, 451 } 452 if s.config.EnableDatagrams { 453 params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize 454 } 455 if s.tracer != nil { 456 s.tracer.SentTransportParameters(params) 457 } 458 cs, clientHelloWritten := handshake.NewCryptoSetupClient( 459 initialStream, 460 handshakeStream, 461 destConnID, 462 conn.LocalAddr(), 463 conn.RemoteAddr(), 464 params, 465 &handshakeRunner{ 466 onReceivedParams: s.handleTransportParameters, 467 onError: s.closeLocal, 468 dropKeys: s.dropEncryptionLevel, 469 onHandshakeComplete: func() { close(s.handshakeCompleteChan) }, 470 }, 471 tlsConf, 472 473 // [Psiphon] 474 conf.ClientHelloSeed, 475 conf.GetClientHelloRandom, 476 477 enable0RTT, 478 s.rttStats, 479 tracer, 480 logger, 481 s.version, 482 ) 483 s.clientHelloWritten = clientHelloWritten 484 s.cryptoStreamHandler = cs 485 s.cryptoStreamManager = newCryptoStreamManager(cs, initialStream, handshakeStream, newCryptoStream()) 486 s.unpacker = newPacketUnpacker(cs, s.version) 487 s.packer = newPacketPacker( 488 srcConnID, 489 s.connIDManager.Get, 490 initialStream, 491 handshakeStream, 492 s.sentPacketHandler, 493 s.retransmissionQueue, 494 s.RemoteAddr(), 495 496 // [Psiphon] 497 conf.ClientMaxPacketSizeAdjustment, 498 499 cs, 500 s.framer, 501 s.receivedPacketHandler, 502 s.datagramQueue, 503 s.perspective, 504 s.version, 505 ) 506 if len(tlsConf.ServerName) > 0 { 507 s.tokenStoreKey = tlsConf.ServerName 508 } else { 509 s.tokenStoreKey = conn.RemoteAddr().String() 510 } 511 if s.config.TokenStore != nil { 512 if token := s.config.TokenStore.Pop(s.tokenStoreKey); token != nil { 513 s.packer.SetToken(token.data) 514 } 515 } 516 return s 517 } 518 519 func (s *session) preSetup() { 520 s.sendQueue = newSendQueue(s.conn) 521 s.retransmissionQueue = newRetransmissionQueue(s.version) 522 s.frameParser = wire.NewFrameParser(s.config.EnableDatagrams, s.version) 523 s.rttStats = &utils.RTTStats{} 524 s.connFlowController = flowcontrol.NewConnectionFlowController( 525 protocol.ByteCount(s.config.InitialConnectionReceiveWindow), 526 protocol.ByteCount(s.config.MaxConnectionReceiveWindow), 527 s.onHasConnectionWindowUpdate, 528 func(size protocol.ByteCount) bool { 529 if s.config.AllowConnectionWindowIncrease == nil { 530 return true 531 } 532 return s.config.AllowConnectionWindowIncrease(s, uint64(size)) 533 }, 534 s.rttStats, 535 s.logger, 536 ) 537 s.earlySessionReadyChan = make(chan struct{}) 538 s.streamsMap = newStreamsMap( 539 s, 540 s.newFlowController, 541 uint64(s.config.MaxIncomingStreams), 542 uint64(s.config.MaxIncomingUniStreams), 543 s.perspective, 544 s.version, 545 ) 546 s.framer = newFramer(s.streamsMap, s.version) 547 s.receivedPackets = make(chan *receivedPacket, protocol.MaxSessionUnprocessedPackets) 548 s.closeChan = make(chan closeError, 1) 549 s.sendingScheduled = make(chan struct{}, 1) 550 s.handshakeCtx, s.handshakeCtxCancel = context.WithCancel(context.Background()) 551 552 now := time.Now() 553 s.lastPacketReceivedTime = now 554 s.sessionCreationTime = now 555 556 s.windowUpdateQueue = newWindowUpdateQueue(s.streamsMap, s.connFlowController, s.framer.QueueControlFrame) 557 if s.config.EnableDatagrams { 558 s.datagramQueue = newDatagramQueue(s.scheduleSending, s.logger) 559 } 560 } 561 562 // run the session main loop 563 func (s *session) run() error { 564 defer s.ctxCancel() 565 566 s.timer = utils.NewTimer() 567 568 go s.cryptoStreamHandler.RunHandshake() 569 go func() { 570 if err := s.sendQueue.Run(); err != nil { 571 s.destroyImpl(err) 572 } 573 }() 574 575 if s.perspective == protocol.PerspectiveClient { 576 select { 577 case zeroRTTParams := <-s.clientHelloWritten: 578 s.scheduleSending() 579 if zeroRTTParams != nil { 580 s.restoreTransportParameters(zeroRTTParams) 581 close(s.earlySessionReadyChan) 582 } 583 case closeErr := <-s.closeChan: 584 // put the close error back into the channel, so that the run loop can receive it 585 s.closeChan <- closeErr 586 } 587 } 588 589 var ( 590 closeErr closeError 591 sendQueueAvailable <-chan struct{} 592 ) 593 594 runLoop: 595 for { 596 // Close immediately if requested 597 select { 598 case closeErr = <-s.closeChan: 599 break runLoop 600 case <-s.handshakeCompleteChan: 601 s.handleHandshakeComplete() 602 default: 603 } 604 605 s.maybeResetTimer() 606 607 var processedUndecryptablePacket bool 608 if len(s.undecryptablePacketsToProcess) > 0 { 609 queue := s.undecryptablePacketsToProcess 610 s.undecryptablePacketsToProcess = nil 611 for _, p := range queue { 612 if processed := s.handlePacketImpl(p); processed { 613 processedUndecryptablePacket = true 614 } 615 // Don't set timers and send packets if the packet made us close the session. 616 select { 617 case closeErr = <-s.closeChan: 618 break runLoop 619 default: 620 } 621 } 622 } 623 // If we processed any undecryptable packets, jump to the resetting of the timers directly. 624 if !processedUndecryptablePacket { 625 select { 626 case closeErr = <-s.closeChan: 627 break runLoop 628 case <-s.timer.Chan(): 629 s.timer.SetRead() 630 // We do all the interesting stuff after the switch statement, so 631 // nothing to see here. 632 case <-s.sendingScheduled: 633 // We do all the interesting stuff after the switch statement, so 634 // nothing to see here. 635 case <-sendQueueAvailable: 636 case firstPacket := <-s.receivedPackets: 637 wasProcessed := s.handlePacketImpl(firstPacket) 638 // Don't set timers and send packets if the packet made us close the session. 639 select { 640 case closeErr = <-s.closeChan: 641 break runLoop 642 default: 643 } 644 if s.handshakeComplete { 645 // Now process all packets in the receivedPackets channel. 646 // Limit the number of packets to the length of the receivedPackets channel, 647 // so we eventually get a chance to send out an ACK when receiving a lot of packets. 648 numPackets := len(s.receivedPackets) 649 receiveLoop: 650 for i := 0; i < numPackets; i++ { 651 select { 652 case p := <-s.receivedPackets: 653 if processed := s.handlePacketImpl(p); processed { 654 wasProcessed = true 655 } 656 select { 657 case closeErr = <-s.closeChan: 658 break runLoop 659 default: 660 } 661 default: 662 break receiveLoop 663 } 664 } 665 } 666 // Only reset the timers if this packet was actually processed. 667 // This avoids modifying any state when handling undecryptable packets, 668 // which could be injected by an attacker. 669 if !wasProcessed { 670 continue 671 } 672 case <-s.handshakeCompleteChan: 673 s.handleHandshakeComplete() 674 } 675 } 676 677 now := time.Now() 678 if timeout := s.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && timeout.Before(now) { 679 // This could cause packets to be retransmitted. 680 // Check it before trying to send packets. 681 if err := s.sentPacketHandler.OnLossDetectionTimeout(); err != nil { 682 s.closeLocal(err) 683 } 684 } 685 686 if keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() && !now.Before(keepAliveTime) { 687 // send a PING frame since there is no activity in the session 688 s.logger.Debugf("Sending a keep-alive PING to keep the connection alive.") 689 s.framer.QueueControlFrame(&wire.PingFrame{}) 690 s.keepAlivePingSent = true 691 } else if !s.handshakeComplete && now.Sub(s.sessionCreationTime) >= s.config.handshakeTimeout() { 692 s.destroyImpl(qerr.ErrHandshakeTimeout) 693 continue 694 } else { 695 idleTimeoutStartTime := s.idleTimeoutStartTime() 696 if (!s.handshakeComplete && now.Sub(idleTimeoutStartTime) >= s.config.HandshakeIdleTimeout) || 697 (s.handshakeComplete && now.Sub(idleTimeoutStartTime) >= s.idleTimeout) { 698 s.destroyImpl(qerr.ErrIdleTimeout) 699 continue 700 } 701 } 702 703 if s.sendQueue.WouldBlock() { 704 // The send queue is still busy sending out packets. 705 // Wait until there's space to enqueue new packets. 706 sendQueueAvailable = s.sendQueue.Available() 707 continue 708 } 709 if err := s.sendPackets(); err != nil { 710 s.closeLocal(err) 711 } 712 if s.sendQueue.WouldBlock() { 713 sendQueueAvailable = s.sendQueue.Available() 714 } else { 715 sendQueueAvailable = nil 716 } 717 } 718 719 s.handleCloseError(&closeErr) 720 if e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) && s.tracer != nil { 721 s.tracer.Close() 722 } 723 s.logger.Infof("Connection %s closed.", s.logID) 724 s.cryptoStreamHandler.Close() 725 s.sendQueue.Close() 726 s.timer.Stop() 727 return closeErr.err 728 } 729 730 // blocks until the early session can be used 731 func (s *session) earlySessionReady() <-chan struct{} { 732 return s.earlySessionReadyChan 733 } 734 735 func (s *session) HandshakeComplete() context.Context { 736 return s.handshakeCtx 737 } 738 739 func (s *session) Context() context.Context { 740 return s.ctx 741 } 742 743 func (s *session) supportsDatagrams() bool { 744 return s.peerParams.MaxDatagramFrameSize != protocol.InvalidByteCount 745 } 746 747 func (s *session) ConnectionState() ConnectionState { 748 return ConnectionState{ 749 TLS: s.cryptoStreamHandler.ConnectionState(), 750 SupportsDatagrams: s.supportsDatagrams(), 751 } 752 } 753 754 // Time when the next keep-alive packet should be sent. 755 // It returns a zero time if no keep-alive should be sent. 756 func (s *session) nextKeepAliveTime() time.Time { 757 if !s.config.KeepAlive || s.keepAlivePingSent || !s.firstAckElicitingPacketAfterIdleSentTime.IsZero() { 758 return time.Time{} 759 } 760 return s.lastPacketReceivedTime.Add(s.keepAliveInterval) 761 } 762 763 func (s *session) maybeResetTimer() { 764 var deadline time.Time 765 if !s.handshakeComplete { 766 deadline = utils.MinTime( 767 s.sessionCreationTime.Add(s.config.handshakeTimeout()), 768 s.idleTimeoutStartTime().Add(s.config.HandshakeIdleTimeout), 769 ) 770 } else { 771 if keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() { 772 deadline = keepAliveTime 773 } else { 774 deadline = s.idleTimeoutStartTime().Add(s.idleTimeout) 775 } 776 } 777 if s.handshakeConfirmed && !s.config.DisablePathMTUDiscovery { 778 if probeTime := s.mtuDiscoverer.NextProbeTime(); !probeTime.IsZero() { 779 deadline = utils.MinTime(deadline, probeTime) 780 } 781 } 782 783 if ackAlarm := s.receivedPacketHandler.GetAlarmTimeout(); !ackAlarm.IsZero() { 784 deadline = utils.MinTime(deadline, ackAlarm) 785 } 786 if lossTime := s.sentPacketHandler.GetLossDetectionTimeout(); !lossTime.IsZero() { 787 deadline = utils.MinTime(deadline, lossTime) 788 } 789 if !s.pacingDeadline.IsZero() { 790 deadline = utils.MinTime(deadline, s.pacingDeadline) 791 } 792 793 s.timer.Reset(deadline) 794 } 795 796 func (s *session) idleTimeoutStartTime() time.Time { 797 return utils.MaxTime(s.lastPacketReceivedTime, s.firstAckElicitingPacketAfterIdleSentTime) 798 } 799 800 func (s *session) handleHandshakeComplete() { 801 s.handshakeComplete = true 802 s.handshakeCompleteChan = nil // prevent this case from ever being selected again 803 defer s.handshakeCtxCancel() 804 // Once the handshake completes, we have derived 1-RTT keys. 805 // There's no point in queueing undecryptable packets for later decryption any more. 806 s.undecryptablePackets = nil 807 808 s.connIDManager.SetHandshakeComplete() 809 s.connIDGenerator.SetHandshakeComplete() 810 811 if s.perspective == protocol.PerspectiveClient { 812 s.applyTransportParameters() 813 return 814 } 815 816 s.handleHandshakeConfirmed() 817 818 ticket, err := s.cryptoStreamHandler.GetSessionTicket() 819 if err != nil { 820 s.closeLocal(err) 821 } 822 if ticket != nil { 823 s.oneRTTStream.Write(ticket) 824 for s.oneRTTStream.HasData() { 825 s.queueControlFrame(s.oneRTTStream.PopCryptoFrame(protocol.MaxPostHandshakeCryptoFrameSize)) 826 } 827 } 828 token, err := s.tokenGenerator.NewToken(s.conn.RemoteAddr()) 829 if err != nil { 830 s.closeLocal(err) 831 } 832 s.queueControlFrame(&wire.NewTokenFrame{Token: token}) 833 s.queueControlFrame(&wire.HandshakeDoneFrame{}) 834 } 835 836 func (s *session) handleHandshakeConfirmed() { 837 838 // [Psiphon] 839 // Adjust the max packet size to allow for obfuscation overhead. 840 maxPacketSizeAdjustment := 0 841 if s.config.ServerMaxPacketSizeAdjustment != nil { 842 maxPacketSizeAdjustment = s.config.ServerMaxPacketSizeAdjustment(s.conn.RemoteAddr()) 843 } else { 844 maxPacketSizeAdjustment = s.config.ClientMaxPacketSizeAdjustment 845 } 846 847 s.handshakeConfirmed = true 848 s.sentPacketHandler.SetHandshakeConfirmed() 849 s.cryptoStreamHandler.SetHandshakeConfirmed() 850 851 if !s.config.DisablePathMTUDiscovery { 852 maxPacketSize := s.peerParams.MaxUDPPayloadSize 853 if maxPacketSize == 0 { 854 maxPacketSize = protocol.MaxByteCount 855 } 856 maxPacketSize = utils.MinByteCount(maxPacketSize, protocol.MaxPacketBufferSize) 857 858 // [Psiphon] 859 if maxPacketSize > protocol.ByteCount(maxPacketSizeAdjustment) { 860 maxPacketSize -= protocol.ByteCount(maxPacketSizeAdjustment) 861 } 862 863 s.mtuDiscoverer = newMTUDiscoverer( 864 s.rttStats, 865 866 // [Psiphon] 867 getMaxPacketSize(s.conn.RemoteAddr(), maxPacketSizeAdjustment), 868 869 maxPacketSize, 870 func(size protocol.ByteCount) { 871 s.sentPacketHandler.SetMaxDatagramSize(size) 872 s.packer.SetMaxPacketSize(size) 873 }, 874 ) 875 } 876 } 877 878 func (s *session) handlePacketImpl(rp *receivedPacket) bool { 879 s.sentPacketHandler.ReceivedBytes(rp.Size()) 880 881 if wire.IsVersionNegotiationPacket(rp.data) { 882 s.handleVersionNegotiationPacket(rp) 883 return false 884 } 885 886 var counter uint8 887 var lastConnID protocol.ConnectionID 888 var processed bool 889 data := rp.data 890 p := rp 891 for len(data) > 0 { 892 if counter > 0 { 893 p = p.Clone() 894 p.data = data 895 } 896 897 hdr, packetData, rest, err := wire.ParsePacket(p.data, s.srcConnIDLen) 898 if err != nil { 899 if s.tracer != nil { 900 dropReason := logging.PacketDropHeaderParseError 901 if err == wire.ErrUnsupportedVersion { 902 dropReason = logging.PacketDropUnsupportedVersion 903 } 904 s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), dropReason) 905 } 906 s.logger.Debugf("error parsing packet: %s", err) 907 break 908 } 909 910 if hdr.IsLongHeader && hdr.Version != s.version { 911 if s.tracer != nil { 912 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion) 913 } 914 s.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, s.version) 915 break 916 } 917 918 if counter > 0 && !hdr.DestConnectionID.Equal(lastConnID) { 919 if s.tracer != nil { 920 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID) 921 } 922 s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", hdr.DestConnectionID, lastConnID) 923 break 924 } 925 lastConnID = hdr.DestConnectionID 926 927 if counter > 0 { 928 p.buffer.Split() 929 } 930 counter++ 931 932 // only log if this actually a coalesced packet 933 if s.logger.Debug() && (counter > 1 || len(rest) > 0) { 934 s.logger.Debugf("Parsed a coalesced packet. Part %d: %d bytes. Remaining: %d bytes.", counter, len(packetData), len(rest)) 935 } 936 p.data = packetData 937 if wasProcessed := s.handleSinglePacket(p, hdr); wasProcessed { 938 processed = true 939 } 940 data = rest 941 } 942 p.buffer.MaybeRelease() 943 return processed 944 } 945 946 func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool /* was the packet successfully processed */ { 947 var wasQueued bool 948 949 defer func() { 950 // Put back the packet buffer if the packet wasn't queued for later decryption. 951 if !wasQueued { 952 p.buffer.Decrement() 953 } 954 }() 955 956 if hdr.Type == protocol.PacketTypeRetry { 957 return s.handleRetryPacket(hdr, p.data) 958 } 959 960 // The server can change the source connection ID with the first Handshake packet. 961 // After this, all packets with a different source connection have to be ignored. 962 if s.receivedFirstPacket && hdr.IsLongHeader && hdr.Type == protocol.PacketTypeInitial && !hdr.SrcConnectionID.Equal(s.handshakeDestConnID) { 963 if s.tracer != nil { 964 s.tracer.DroppedPacket(logging.PacketTypeInitial, p.Size(), logging.PacketDropUnknownConnectionID) 965 } 966 s.logger.Debugf("Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)", p.Size(), hdr.SrcConnectionID, s.handshakeDestConnID) 967 return false 968 } 969 // drop 0-RTT packets, if we are a client 970 if s.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT { 971 if s.tracer != nil { 972 s.tracer.DroppedPacket(logging.PacketType0RTT, p.Size(), logging.PacketDropKeyUnavailable) 973 } 974 return false 975 } 976 977 packet, err := s.unpacker.Unpack(hdr, p.rcvTime, p.data) 978 if err != nil { 979 switch err { 980 case handshake.ErrKeysDropped: 981 if s.tracer != nil { 982 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropKeyUnavailable) 983 } 984 s.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", hdr.PacketType(), p.Size()) 985 case handshake.ErrKeysNotYetAvailable: 986 // Sealer for this encryption level not yet available. 987 // Try again later. 988 wasQueued = true 989 s.tryQueueingUndecryptablePacket(p, hdr) 990 case wire.ErrInvalidReservedBits: 991 s.closeLocal(&qerr.TransportError{ 992 ErrorCode: qerr.ProtocolViolation, 993 ErrorMessage: err.Error(), 994 }) 995 case handshake.ErrDecryptionFailed: 996 // This might be a packet injected by an attacker. Drop it. 997 if s.tracer != nil { 998 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropPayloadDecryptError) 999 } 1000 s.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", hdr.PacketType(), p.Size(), err) 1001 default: 1002 var headerErr *headerParseError 1003 if errors.As(err, &headerErr) { 1004 // This might be a packet injected by an attacker. Drop it. 1005 if s.tracer != nil { 1006 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropHeaderParseError) 1007 } 1008 s.logger.Debugf("Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s", hdr.PacketType(), p.Size(), err) 1009 } else { 1010 // This is an error returned by the AEAD (other than ErrDecryptionFailed). 1011 // For example, a PROTOCOL_VIOLATION due to key updates. 1012 s.closeLocal(err) 1013 } 1014 } 1015 return false 1016 } 1017 1018 if s.logger.Debug() { 1019 s.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, %s", packet.packetNumber, p.Size(), hdr.DestConnectionID, packet.encryptionLevel) 1020 packet.hdr.Log(s.logger) 1021 } 1022 1023 if s.receivedPacketHandler.IsPotentiallyDuplicate(packet.packetNumber, packet.encryptionLevel) { 1024 s.logger.Debugf("Dropping (potentially) duplicate packet.") 1025 if s.tracer != nil { 1026 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropDuplicate) 1027 } 1028 return false 1029 } 1030 1031 if err := s.handleUnpackedPacket(packet, p.ecn, p.rcvTime, p.Size()); err != nil { 1032 s.closeLocal(err) 1033 return false 1034 } 1035 return true 1036 } 1037 1038 func (s *session) handleRetryPacket(hdr *wire.Header, data []byte) bool /* was this a valid Retry */ { 1039 if s.perspective == protocol.PerspectiveServer { 1040 if s.tracer != nil { 1041 s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) 1042 } 1043 s.logger.Debugf("Ignoring Retry.") 1044 return false 1045 } 1046 if s.receivedFirstPacket { 1047 if s.tracer != nil { 1048 s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) 1049 } 1050 s.logger.Debugf("Ignoring Retry, since we already received a packet.") 1051 return false 1052 } 1053 destConnID := s.connIDManager.Get() 1054 if hdr.SrcConnectionID.Equal(destConnID) { 1055 if s.tracer != nil { 1056 s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) 1057 } 1058 s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.") 1059 return false 1060 } 1061 // If a token is already set, this means that we already received a Retry from the server. 1062 // Ignore this Retry packet. 1063 if s.receivedRetry { 1064 s.logger.Debugf("Ignoring Retry, since a Retry was already received.") 1065 return false 1066 } 1067 1068 tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version) 1069 if !bytes.Equal(data[len(data)-16:], tag[:]) { 1070 if s.tracer != nil { 1071 s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError) 1072 } 1073 s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.") 1074 return false 1075 } 1076 1077 if s.logger.Debug() { 1078 s.logger.Debugf("<- Received Retry:") 1079 (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) 1080 s.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID) 1081 } 1082 if s.tracer != nil { 1083 s.tracer.ReceivedRetry(hdr) 1084 } 1085 newDestConnID := hdr.SrcConnectionID 1086 s.receivedRetry = true 1087 if err := s.sentPacketHandler.ResetForRetry(); err != nil { 1088 s.closeLocal(err) 1089 return false 1090 } 1091 s.handshakeDestConnID = newDestConnID 1092 s.retrySrcConnID = &newDestConnID 1093 s.cryptoStreamHandler.ChangeConnectionID(newDestConnID) 1094 s.packer.SetToken(hdr.Token) 1095 s.connIDManager.ChangeInitialConnID(newDestConnID) 1096 s.scheduleSending() 1097 return true 1098 } 1099 1100 func (s *session) handleVersionNegotiationPacket(p *receivedPacket) { 1101 if s.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets 1102 s.receivedFirstPacket || s.versionNegotiated { // ignore delayed / duplicated version negotiation packets 1103 if s.tracer != nil { 1104 s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket) 1105 } 1106 return 1107 } 1108 1109 hdr, supportedVersions, err := wire.ParseVersionNegotiationPacket(bytes.NewReader(p.data)) 1110 if err != nil { 1111 if s.tracer != nil { 1112 s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropHeaderParseError) 1113 } 1114 s.logger.Debugf("Error parsing Version Negotiation packet: %s", err) 1115 return 1116 } 1117 1118 for _, v := range supportedVersions { 1119 if v == s.version { 1120 if s.tracer != nil { 1121 s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedVersion) 1122 } 1123 // The Version Negotiation packet contains the version that we offered. 1124 // This might be a packet sent by an attacker, or it was corrupted. 1125 return 1126 } 1127 } 1128 1129 s.logger.Infof("Received a Version Negotiation packet. Supported Versions: %s", supportedVersions) 1130 if s.tracer != nil { 1131 s.tracer.ReceivedVersionNegotiationPacket(hdr, supportedVersions) 1132 } 1133 newVersion, ok := protocol.ChooseSupportedVersion(s.config.Versions, supportedVersions) 1134 if !ok { 1135 s.destroyImpl(&VersionNegotiationError{ 1136 Ours: s.config.Versions, 1137 Theirs: supportedVersions, 1138 }) 1139 s.logger.Infof("No compatible QUIC version found.") 1140 return 1141 } 1142 if s.tracer != nil { 1143 s.tracer.NegotiatedVersion(newVersion, s.config.Versions, supportedVersions) 1144 } 1145 1146 s.logger.Infof("Switching to QUIC version %s.", newVersion) 1147 nextPN, _ := s.sentPacketHandler.PeekPacketNumber(protocol.EncryptionInitial) 1148 s.destroyImpl(&errCloseForRecreating{ 1149 nextPacketNumber: nextPN, 1150 nextVersion: newVersion, 1151 }) 1152 } 1153 1154 func (s *session) handleUnpackedPacket( 1155 packet *unpackedPacket, 1156 ecn protocol.ECN, 1157 rcvTime time.Time, 1158 packetSize protocol.ByteCount, // only for logging 1159 ) error { 1160 if len(packet.data) == 0 { 1161 return &qerr.TransportError{ 1162 ErrorCode: qerr.ProtocolViolation, 1163 ErrorMessage: "empty packet", 1164 } 1165 } 1166 1167 if !s.receivedFirstPacket { 1168 s.receivedFirstPacket = true 1169 if !s.versionNegotiated && s.tracer != nil { 1170 var clientVersions, serverVersions []protocol.VersionNumber 1171 switch s.perspective { 1172 case protocol.PerspectiveClient: 1173 clientVersions = s.config.Versions 1174 case protocol.PerspectiveServer: 1175 serverVersions = s.config.Versions 1176 } 1177 s.tracer.NegotiatedVersion(s.version, clientVersions, serverVersions) 1178 } 1179 // The server can change the source connection ID with the first Handshake packet. 1180 if s.perspective == protocol.PerspectiveClient && packet.hdr.IsLongHeader && !packet.hdr.SrcConnectionID.Equal(s.handshakeDestConnID) { 1181 cid := packet.hdr.SrcConnectionID 1182 s.logger.Debugf("Received first packet. Switching destination connection ID to: %s", cid) 1183 s.handshakeDestConnID = cid 1184 s.connIDManager.ChangeInitialConnID(cid) 1185 } 1186 // We create the session as soon as we receive the first packet from the client. 1187 // We do that before authenticating the packet. 1188 // That means that if the source connection ID was corrupted, 1189 // we might have create a session with an incorrect source connection ID. 1190 // Once we authenticate the first packet, we need to update it. 1191 if s.perspective == protocol.PerspectiveServer { 1192 if !packet.hdr.SrcConnectionID.Equal(s.handshakeDestConnID) { 1193 s.handshakeDestConnID = packet.hdr.SrcConnectionID 1194 s.connIDManager.ChangeInitialConnID(packet.hdr.SrcConnectionID) 1195 } 1196 if s.tracer != nil { 1197 s.tracer.StartedConnection( 1198 s.conn.LocalAddr(), 1199 s.conn.RemoteAddr(), 1200 packet.hdr.SrcConnectionID, 1201 packet.hdr.DestConnectionID, 1202 ) 1203 } 1204 } 1205 } 1206 1207 s.lastPacketReceivedTime = rcvTime 1208 s.firstAckElicitingPacketAfterIdleSentTime = time.Time{} 1209 s.keepAlivePingSent = false 1210 1211 // Only used for tracing. 1212 // If we're not tracing, this slice will always remain empty. 1213 var frames []wire.Frame 1214 r := bytes.NewReader(packet.data) 1215 var isAckEliciting bool 1216 for { 1217 frame, err := s.frameParser.ParseNext(r, packet.encryptionLevel) 1218 if err != nil { 1219 return err 1220 } 1221 if frame == nil { 1222 break 1223 } 1224 if ackhandler.IsFrameAckEliciting(frame) { 1225 isAckEliciting = true 1226 } 1227 // Only process frames now if we're not logging. 1228 // If we're logging, we need to make sure that the packet_received event is logged first. 1229 if s.tracer == nil { 1230 if err := s.handleFrame(frame, packet.encryptionLevel, packet.hdr.DestConnectionID); err != nil { 1231 return err 1232 } 1233 } else { 1234 frames = append(frames, frame) 1235 } 1236 } 1237 1238 if s.tracer != nil { 1239 fs := make([]logging.Frame, len(frames)) 1240 for i, frame := range frames { 1241 fs[i] = logutils.ConvertFrame(frame) 1242 } 1243 s.tracer.ReceivedPacket(packet.hdr, packetSize, fs) 1244 for _, frame := range frames { 1245 if err := s.handleFrame(frame, packet.encryptionLevel, packet.hdr.DestConnectionID); err != nil { 1246 return err 1247 } 1248 } 1249 } 1250 1251 return s.receivedPacketHandler.ReceivedPacket(packet.packetNumber, ecn, packet.encryptionLevel, rcvTime, isAckEliciting) 1252 } 1253 1254 func (s *session) handleFrame(f wire.Frame, encLevel protocol.EncryptionLevel, destConnID protocol.ConnectionID) error { 1255 var err error 1256 wire.LogFrame(s.logger, f, false) 1257 switch frame := f.(type) { 1258 case *wire.CryptoFrame: 1259 err = s.handleCryptoFrame(frame, encLevel) 1260 case *wire.StreamFrame: 1261 err = s.handleStreamFrame(frame) 1262 case *wire.AckFrame: 1263 err = s.handleAckFrame(frame, encLevel) 1264 case *wire.ConnectionCloseFrame: 1265 s.handleConnectionCloseFrame(frame) 1266 case *wire.ResetStreamFrame: 1267 err = s.handleResetStreamFrame(frame) 1268 case *wire.MaxDataFrame: 1269 s.handleMaxDataFrame(frame) 1270 case *wire.MaxStreamDataFrame: 1271 err = s.handleMaxStreamDataFrame(frame) 1272 case *wire.MaxStreamsFrame: 1273 s.handleMaxStreamsFrame(frame) 1274 case *wire.DataBlockedFrame: 1275 case *wire.StreamDataBlockedFrame: 1276 case *wire.StreamsBlockedFrame: 1277 case *wire.StopSendingFrame: 1278 err = s.handleStopSendingFrame(frame) 1279 case *wire.PingFrame: 1280 case *wire.PathChallengeFrame: 1281 s.handlePathChallengeFrame(frame) 1282 case *wire.PathResponseFrame: 1283 // since we don't send PATH_CHALLENGEs, we don't expect PATH_RESPONSEs 1284 err = errors.New("unexpected PATH_RESPONSE frame") 1285 case *wire.NewTokenFrame: 1286 err = s.handleNewTokenFrame(frame) 1287 case *wire.NewConnectionIDFrame: 1288 err = s.handleNewConnectionIDFrame(frame) 1289 case *wire.RetireConnectionIDFrame: 1290 err = s.handleRetireConnectionIDFrame(frame, destConnID) 1291 case *wire.HandshakeDoneFrame: 1292 err = s.handleHandshakeDoneFrame() 1293 case *wire.DatagramFrame: 1294 err = s.handleDatagramFrame(frame) 1295 default: 1296 err = fmt.Errorf("unexpected frame type: %s", reflect.ValueOf(&frame).Elem().Type().Name()) 1297 } 1298 return err 1299 } 1300 1301 // handlePacket is called by the server with a new packet 1302 func (s *session) handlePacket(p *receivedPacket) { 1303 // Discard packets once the amount of queued packets is larger than 1304 // the channel size, protocol.MaxSessionUnprocessedPackets 1305 select { 1306 case s.receivedPackets <- p: 1307 default: 1308 if s.tracer != nil { 1309 s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) 1310 } 1311 } 1312 } 1313 1314 func (s *session) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame) { 1315 if frame.IsApplicationError { 1316 s.closeRemote(&qerr.ApplicationError{ 1317 Remote: true, 1318 ErrorCode: qerr.ApplicationErrorCode(frame.ErrorCode), 1319 ErrorMessage: frame.ReasonPhrase, 1320 }) 1321 return 1322 } 1323 s.closeRemote(&qerr.TransportError{ 1324 Remote: true, 1325 ErrorCode: qerr.TransportErrorCode(frame.ErrorCode), 1326 FrameType: frame.FrameType, 1327 ErrorMessage: frame.ReasonPhrase, 1328 }) 1329 } 1330 1331 func (s *session) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel) error { 1332 encLevelChanged, err := s.cryptoStreamManager.HandleCryptoFrame(frame, encLevel) 1333 if err != nil { 1334 return err 1335 } 1336 if encLevelChanged { 1337 // Queue all packets for decryption that have been undecryptable so far. 1338 s.undecryptablePacketsToProcess = s.undecryptablePackets 1339 s.undecryptablePackets = nil 1340 } 1341 return nil 1342 } 1343 1344 func (s *session) handleStreamFrame(frame *wire.StreamFrame) error { 1345 str, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) 1346 if err != nil { 1347 return err 1348 } 1349 if str == nil { 1350 // Stream is closed and already garbage collected 1351 // ignore this StreamFrame 1352 return nil 1353 } 1354 return str.handleStreamFrame(frame) 1355 } 1356 1357 func (s *session) handleMaxDataFrame(frame *wire.MaxDataFrame) { 1358 s.connFlowController.UpdateSendWindow(frame.MaximumData) 1359 } 1360 1361 func (s *session) handleMaxStreamDataFrame(frame *wire.MaxStreamDataFrame) error { 1362 str, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID) 1363 if err != nil { 1364 return err 1365 } 1366 if str == nil { 1367 // stream is closed and already garbage collected 1368 return nil 1369 } 1370 str.updateSendWindow(frame.MaximumStreamData) 1371 return nil 1372 } 1373 1374 func (s *session) handleMaxStreamsFrame(frame *wire.MaxStreamsFrame) { 1375 s.streamsMap.HandleMaxStreamsFrame(frame) 1376 } 1377 1378 func (s *session) handleResetStreamFrame(frame *wire.ResetStreamFrame) error { 1379 str, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) 1380 if err != nil { 1381 return err 1382 } 1383 if str == nil { 1384 // stream is closed and already garbage collected 1385 return nil 1386 } 1387 return str.handleResetStreamFrame(frame) 1388 } 1389 1390 func (s *session) handleStopSendingFrame(frame *wire.StopSendingFrame) error { 1391 str, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID) 1392 if err != nil { 1393 return err 1394 } 1395 if str == nil { 1396 // stream is closed and already garbage collected 1397 return nil 1398 } 1399 str.handleStopSendingFrame(frame) 1400 return nil 1401 } 1402 1403 func (s *session) handlePathChallengeFrame(frame *wire.PathChallengeFrame) { 1404 s.queueControlFrame(&wire.PathResponseFrame{Data: frame.Data}) 1405 } 1406 1407 func (s *session) handleNewTokenFrame(frame *wire.NewTokenFrame) error { 1408 if s.perspective == protocol.PerspectiveServer { 1409 return &qerr.TransportError{ 1410 ErrorCode: qerr.ProtocolViolation, 1411 ErrorMessage: "received NEW_TOKEN frame from the client", 1412 } 1413 } 1414 if s.config.TokenStore != nil { 1415 s.config.TokenStore.Put(s.tokenStoreKey, &ClientToken{data: frame.Token}) 1416 } 1417 return nil 1418 } 1419 1420 func (s *session) handleNewConnectionIDFrame(f *wire.NewConnectionIDFrame) error { 1421 return s.connIDManager.Add(f) 1422 } 1423 1424 func (s *session) handleRetireConnectionIDFrame(f *wire.RetireConnectionIDFrame, destConnID protocol.ConnectionID) error { 1425 return s.connIDGenerator.Retire(f.SequenceNumber, destConnID) 1426 } 1427 1428 func (s *session) handleHandshakeDoneFrame() error { 1429 if s.perspective == protocol.PerspectiveServer { 1430 return &qerr.TransportError{ 1431 ErrorCode: qerr.ProtocolViolation, 1432 ErrorMessage: "received a HANDSHAKE_DONE frame", 1433 } 1434 } 1435 if !s.handshakeConfirmed { 1436 s.handleHandshakeConfirmed() 1437 } 1438 return nil 1439 } 1440 1441 func (s *session) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel) error { 1442 acked1RTTPacket, err := s.sentPacketHandler.ReceivedAck(frame, encLevel, s.lastPacketReceivedTime) 1443 if err != nil { 1444 return err 1445 } 1446 if !acked1RTTPacket { 1447 return nil 1448 } 1449 if s.perspective == protocol.PerspectiveClient && !s.handshakeConfirmed { 1450 s.handleHandshakeConfirmed() 1451 } 1452 return s.cryptoStreamHandler.SetLargest1RTTAcked(frame.LargestAcked()) 1453 } 1454 1455 func (s *session) handleDatagramFrame(f *wire.DatagramFrame) error { 1456 if f.Length(s.version) > protocol.MaxDatagramFrameSize { 1457 return &qerr.TransportError{ 1458 ErrorCode: qerr.ProtocolViolation, 1459 ErrorMessage: "DATAGRAM frame too large", 1460 } 1461 } 1462 s.datagramQueue.HandleDatagramFrame(f) 1463 return nil 1464 } 1465 1466 // closeLocal closes the session and send a CONNECTION_CLOSE containing the error 1467 func (s *session) closeLocal(e error) { 1468 s.closeOnce.Do(func() { 1469 if e == nil { 1470 s.logger.Infof("Closing session.") 1471 } else { 1472 s.logger.Errorf("Closing session with error: %s", e) 1473 } 1474 s.closeChan <- closeError{err: e, immediate: false, remote: false} 1475 }) 1476 } 1477 1478 // destroy closes the session without sending the error on the wire 1479 func (s *session) destroy(e error) { 1480 s.destroyImpl(e) 1481 <-s.ctx.Done() 1482 } 1483 1484 func (s *session) destroyImpl(e error) { 1485 s.closeOnce.Do(func() { 1486 if nerr, ok := e.(net.Error); ok && nerr.Timeout() { 1487 s.logger.Errorf("Destroying session: %s", e) 1488 } else { 1489 s.logger.Errorf("Destroying session with error: %s", e) 1490 } 1491 s.closeChan <- closeError{err: e, immediate: true, remote: false} 1492 }) 1493 } 1494 1495 func (s *session) closeRemote(e error) { 1496 s.closeOnce.Do(func() { 1497 s.logger.Errorf("Peer closed session with error: %s", e) 1498 s.closeChan <- closeError{err: e, immediate: true, remote: true} 1499 }) 1500 } 1501 1502 // Close the connection. It sends a NO_ERROR application error. 1503 // It waits until the run loop has stopped before returning 1504 func (s *session) shutdown() { 1505 s.closeLocal(nil) 1506 <-s.ctx.Done() 1507 } 1508 1509 func (s *session) CloseWithError(code ApplicationErrorCode, desc string) error { 1510 s.closeLocal(&qerr.ApplicationError{ 1511 ErrorCode: code, 1512 ErrorMessage: desc, 1513 }) 1514 <-s.ctx.Done() 1515 return nil 1516 } 1517 1518 func (s *session) handleCloseError(closeErr *closeError) { 1519 e := closeErr.err 1520 if e == nil { 1521 e = &qerr.ApplicationError{} 1522 } else { 1523 defer func() { 1524 closeErr.err = e 1525 }() 1526 } 1527 1528 var ( 1529 statelessResetErr *StatelessResetError 1530 versionNegotiationErr *VersionNegotiationError 1531 recreateErr *errCloseForRecreating 1532 applicationErr *ApplicationError 1533 transportErr *TransportError 1534 ) 1535 switch { 1536 case errors.Is(e, qerr.ErrIdleTimeout), 1537 errors.Is(e, qerr.ErrHandshakeTimeout), 1538 errors.As(e, &statelessResetErr), 1539 errors.As(e, &versionNegotiationErr), 1540 errors.As(e, &recreateErr), 1541 errors.As(e, &applicationErr), 1542 errors.As(e, &transportErr): 1543 default: 1544 e = &qerr.TransportError{ 1545 ErrorCode: qerr.InternalError, 1546 ErrorMessage: e.Error(), 1547 } 1548 } 1549 1550 s.streamsMap.CloseWithError(e) 1551 s.connIDManager.Close() 1552 if s.datagramQueue != nil { 1553 s.datagramQueue.CloseWithError(e) 1554 } 1555 1556 if s.tracer != nil && !errors.As(e, &recreateErr) { 1557 s.tracer.ClosedConnection(e) 1558 } 1559 1560 // If this is a remote close we're done here 1561 if closeErr.remote { 1562 s.connIDGenerator.ReplaceWithClosed(newClosedRemoteSession(s.perspective)) 1563 return 1564 } 1565 if closeErr.immediate { 1566 s.connIDGenerator.RemoveAll() 1567 return 1568 } 1569 connClosePacket, err := s.sendConnectionClose(e) 1570 if err != nil { 1571 s.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err) 1572 } 1573 cs := newClosedLocalSession(s.conn, connClosePacket, s.perspective, s.logger) 1574 s.connIDGenerator.ReplaceWithClosed(cs) 1575 } 1576 1577 func (s *session) dropEncryptionLevel(encLevel protocol.EncryptionLevel) { 1578 s.sentPacketHandler.DropPackets(encLevel) 1579 s.receivedPacketHandler.DropPackets(encLevel) 1580 if s.tracer != nil { 1581 s.tracer.DroppedEncryptionLevel(encLevel) 1582 } 1583 if encLevel == protocol.Encryption0RTT { 1584 s.streamsMap.ResetFor0RTT() 1585 if err := s.connFlowController.Reset(); err != nil { 1586 s.closeLocal(err) 1587 } 1588 if err := s.framer.Handle0RTTRejection(); err != nil { 1589 s.closeLocal(err) 1590 } 1591 } 1592 } 1593 1594 // is called for the client, when restoring transport parameters saved for 0-RTT 1595 func (s *session) restoreTransportParameters(params *wire.TransportParameters) { 1596 if s.logger.Debug() { 1597 s.logger.Debugf("Restoring Transport Parameters: %s", params) 1598 } 1599 1600 s.peerParams = params 1601 s.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit) 1602 s.connFlowController.UpdateSendWindow(params.InitialMaxData) 1603 s.streamsMap.UpdateLimits(params) 1604 } 1605 1606 func (s *session) handleTransportParameters(params *wire.TransportParameters) { 1607 if err := s.checkTransportParameters(params); err != nil { 1608 s.closeLocal(&qerr.TransportError{ 1609 ErrorCode: qerr.TransportParameterError, 1610 ErrorMessage: err.Error(), 1611 }) 1612 } 1613 s.peerParams = params 1614 // On the client side we have to wait for handshake completion. 1615 // During a 0-RTT connection, we are only allowed to use the new transport parameters for 1-RTT packets. 1616 if s.perspective == protocol.PerspectiveServer { 1617 s.applyTransportParameters() 1618 // On the server side, the early session is ready as soon as we processed 1619 // the client's transport parameters. 1620 close(s.earlySessionReadyChan) 1621 } 1622 } 1623 1624 func (s *session) checkTransportParameters(params *wire.TransportParameters) error { 1625 if s.logger.Debug() { 1626 s.logger.Debugf("Processed Transport Parameters: %s", params) 1627 } 1628 if s.tracer != nil { 1629 s.tracer.ReceivedTransportParameters(params) 1630 } 1631 1632 // check the initial_source_connection_id 1633 if !params.InitialSourceConnectionID.Equal(s.handshakeDestConnID) { 1634 return fmt.Errorf("expected initial_source_connection_id to equal %s, is %s", s.handshakeDestConnID, params.InitialSourceConnectionID) 1635 } 1636 1637 if s.perspective == protocol.PerspectiveServer { 1638 return nil 1639 } 1640 // check the original_destination_connection_id 1641 if !params.OriginalDestinationConnectionID.Equal(s.origDestConnID) { 1642 return fmt.Errorf("expected original_destination_connection_id to equal %s, is %s", s.origDestConnID, params.OriginalDestinationConnectionID) 1643 } 1644 if s.retrySrcConnID != nil { // a Retry was performed 1645 if params.RetrySourceConnectionID == nil { 1646 return errors.New("missing retry_source_connection_id") 1647 } 1648 if !(*params.RetrySourceConnectionID).Equal(*s.retrySrcConnID) { 1649 return fmt.Errorf("expected retry_source_connection_id to equal %s, is %s", s.retrySrcConnID, *params.RetrySourceConnectionID) 1650 } 1651 } else if params.RetrySourceConnectionID != nil { 1652 return errors.New("received retry_source_connection_id, although no Retry was performed") 1653 } 1654 return nil 1655 } 1656 1657 func (s *session) applyTransportParameters() { 1658 params := s.peerParams 1659 // Our local idle timeout will always be > 0. 1660 s.idleTimeout = utils.MinNonZeroDuration(s.config.MaxIdleTimeout, params.MaxIdleTimeout) 1661 s.keepAliveInterval = utils.MinDuration(s.idleTimeout/2, protocol.MaxKeepAliveInterval) 1662 s.streamsMap.UpdateLimits(params) 1663 s.packer.HandleTransportParameters(params) 1664 s.frameParser.SetAckDelayExponent(params.AckDelayExponent) 1665 s.connFlowController.UpdateSendWindow(params.InitialMaxData) 1666 s.rttStats.SetMaxAckDelay(params.MaxAckDelay) 1667 s.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit) 1668 if params.StatelessResetToken != nil { 1669 s.connIDManager.SetStatelessResetToken(*params.StatelessResetToken) 1670 } 1671 // We don't support connection migration yet, so we don't have any use for the preferred_address. 1672 if params.PreferredAddress != nil { 1673 // Retire the connection ID. 1674 s.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, params.PreferredAddress.StatelessResetToken) 1675 } 1676 } 1677 1678 func (s *session) sendPackets() error { 1679 s.pacingDeadline = time.Time{} 1680 1681 var sentPacket bool // only used in for packets sent in send mode SendAny 1682 for { 1683 sendMode := s.sentPacketHandler.SendMode() 1684 if sendMode == ackhandler.SendAny && s.handshakeComplete && !s.sentPacketHandler.HasPacingBudget() { 1685 deadline := s.sentPacketHandler.TimeUntilSend() 1686 if deadline.IsZero() { 1687 deadline = deadlineSendImmediately 1688 } 1689 s.pacingDeadline = deadline 1690 // Allow sending of an ACK if we're pacing limit (if we haven't sent out a packet yet). 1691 // This makes sure that a peer that is mostly receiving data (and thus has an inaccurate cwnd estimate) 1692 // sends enough ACKs to allow its peer to utilize the bandwidth. 1693 if sentPacket { 1694 return nil 1695 } 1696 sendMode = ackhandler.SendAck 1697 } 1698 switch sendMode { 1699 case ackhandler.SendNone: 1700 return nil 1701 case ackhandler.SendAck: 1702 // If we already sent packets, and the send mode switches to SendAck, 1703 // as we've just become congestion limited. 1704 // There's no need to try to send an ACK at this moment. 1705 if sentPacket { 1706 return nil 1707 } 1708 // We can at most send a single ACK only packet. 1709 // There will only be a new ACK after receiving new packets. 1710 // SendAck is only returned when we're congestion limited, so we don't need to set the pacingt timer. 1711 return s.maybeSendAckOnlyPacket() 1712 case ackhandler.SendPTOInitial: 1713 if err := s.sendProbePacket(protocol.EncryptionInitial); err != nil { 1714 return err 1715 } 1716 case ackhandler.SendPTOHandshake: 1717 if err := s.sendProbePacket(protocol.EncryptionHandshake); err != nil { 1718 return err 1719 } 1720 case ackhandler.SendPTOAppData: 1721 if err := s.sendProbePacket(protocol.Encryption1RTT); err != nil { 1722 return err 1723 } 1724 case ackhandler.SendAny: 1725 sent, err := s.sendPacket() 1726 if err != nil || !sent { 1727 return err 1728 } 1729 sentPacket = true 1730 default: 1731 return fmt.Errorf("BUG: invalid send mode %d", sendMode) 1732 } 1733 // Prioritize receiving of packets over sending out more packets. 1734 if len(s.receivedPackets) > 0 { 1735 s.pacingDeadline = deadlineSendImmediately 1736 return nil 1737 } 1738 if s.sendQueue.WouldBlock() { 1739 return nil 1740 } 1741 } 1742 } 1743 1744 func (s *session) maybeSendAckOnlyPacket() error { 1745 packet, err := s.packer.MaybePackAckPacket(s.handshakeConfirmed) 1746 if err != nil { 1747 return err 1748 } 1749 if packet == nil { 1750 return nil 1751 } 1752 s.sendPackedPacket(packet, time.Now()) 1753 return nil 1754 } 1755 1756 func (s *session) sendProbePacket(encLevel protocol.EncryptionLevel) error { 1757 // Queue probe packets until we actually send out a packet, 1758 // or until there are no more packets to queue. 1759 var packet *packedPacket 1760 for { 1761 if wasQueued := s.sentPacketHandler.QueueProbePacket(encLevel); !wasQueued { 1762 break 1763 } 1764 var err error 1765 packet, err = s.packer.MaybePackProbePacket(encLevel) 1766 if err != nil { 1767 return err 1768 } 1769 if packet != nil { 1770 break 1771 } 1772 } 1773 if packet == nil { 1774 //nolint:exhaustive // Cannot send probe packets for 0-RTT. 1775 switch encLevel { 1776 case protocol.EncryptionInitial: 1777 s.retransmissionQueue.AddInitial(&wire.PingFrame{}) 1778 case protocol.EncryptionHandshake: 1779 s.retransmissionQueue.AddHandshake(&wire.PingFrame{}) 1780 case protocol.Encryption1RTT: 1781 s.retransmissionQueue.AddAppData(&wire.PingFrame{}) 1782 default: 1783 panic("unexpected encryption level") 1784 } 1785 var err error 1786 packet, err = s.packer.MaybePackProbePacket(encLevel) 1787 if err != nil { 1788 return err 1789 } 1790 } 1791 if packet == nil || packet.packetContents == nil { 1792 return fmt.Errorf("session BUG: couldn't pack %s probe packet", encLevel) 1793 } 1794 s.sendPackedPacket(packet, time.Now()) 1795 return nil 1796 } 1797 1798 func (s *session) sendPacket() (bool, error) { 1799 if isBlocked, offset := s.connFlowController.IsNewlyBlocked(); isBlocked { 1800 s.framer.QueueControlFrame(&wire.DataBlockedFrame{MaximumData: offset}) 1801 } 1802 s.windowUpdateQueue.QueueAll() 1803 1804 now := time.Now() 1805 if !s.handshakeConfirmed { 1806 packet, err := s.packer.PackCoalescedPacket() 1807 if err != nil || packet == nil { 1808 return false, err 1809 } 1810 s.logCoalescedPacket(packet) 1811 for _, p := range packet.packets { 1812 if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() { 1813 s.firstAckElicitingPacketAfterIdleSentTime = now 1814 } 1815 s.sentPacketHandler.SentPacket(p.ToAckHandlerPacket(now, s.retransmissionQueue)) 1816 } 1817 s.connIDManager.SentPacket() 1818 s.sendQueue.Send(packet.buffer) 1819 return true, nil 1820 } 1821 if !s.config.DisablePathMTUDiscovery && s.mtuDiscoverer.ShouldSendProbe(now) { 1822 packet, err := s.packer.PackMTUProbePacket(s.mtuDiscoverer.GetPing()) 1823 if err != nil { 1824 return false, err 1825 } 1826 s.sendPackedPacket(packet, now) 1827 return true, nil 1828 } 1829 packet, err := s.packer.PackPacket() 1830 if err != nil || packet == nil { 1831 return false, err 1832 } 1833 s.sendPackedPacket(packet, now) 1834 return true, nil 1835 } 1836 1837 func (s *session) sendPackedPacket(packet *packedPacket, now time.Time) { 1838 if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && packet.IsAckEliciting() { 1839 s.firstAckElicitingPacketAfterIdleSentTime = now 1840 } 1841 s.logPacket(packet) 1842 s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket(now, s.retransmissionQueue)) 1843 s.connIDManager.SentPacket() 1844 s.sendQueue.Send(packet.buffer) 1845 } 1846 1847 func (s *session) sendConnectionClose(e error) ([]byte, error) { 1848 var packet *coalescedPacket 1849 var err error 1850 var transportErr *qerr.TransportError 1851 var applicationErr *qerr.ApplicationError 1852 if errors.As(e, &transportErr) { 1853 packet, err = s.packer.PackConnectionClose(transportErr) 1854 } else if errors.As(e, &applicationErr) { 1855 packet, err = s.packer.PackApplicationClose(applicationErr) 1856 } else { 1857 packet, err = s.packer.PackConnectionClose(&qerr.TransportError{ 1858 ErrorCode: qerr.InternalError, 1859 ErrorMessage: fmt.Sprintf("session BUG: unspecified error type (msg: %s)", e.Error()), 1860 }) 1861 } 1862 if err != nil { 1863 return nil, err 1864 } 1865 s.logCoalescedPacket(packet) 1866 return packet.buffer.Data, s.conn.Write(packet.buffer.Data) 1867 } 1868 1869 func (s *session) logPacketContents(p *packetContents) { 1870 // tracing 1871 if s.tracer != nil { 1872 frames := make([]logging.Frame, 0, len(p.frames)) 1873 for _, f := range p.frames { 1874 frames = append(frames, logutils.ConvertFrame(f.Frame)) 1875 } 1876 s.tracer.SentPacket(p.header, p.length, p.ack, frames) 1877 } 1878 1879 // quic-go logging 1880 if !s.logger.Debug() { 1881 return 1882 } 1883 p.header.Log(s.logger) 1884 if p.ack != nil { 1885 wire.LogFrame(s.logger, p.ack, true) 1886 } 1887 for _, frame := range p.frames { 1888 wire.LogFrame(s.logger, frame.Frame, true) 1889 } 1890 } 1891 1892 func (s *session) logCoalescedPacket(packet *coalescedPacket) { 1893 if s.logger.Debug() { 1894 if len(packet.packets) > 1 { 1895 s.logger.Debugf("-> Sending coalesced packet (%d parts, %d bytes) for connection %s", len(packet.packets), packet.buffer.Len(), s.logID) 1896 } else { 1897 s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, %s", packet.packets[0].header.PacketNumber, packet.buffer.Len(), s.logID, packet.packets[0].EncryptionLevel()) 1898 } 1899 } 1900 for _, p := range packet.packets { 1901 s.logPacketContents(p) 1902 } 1903 } 1904 1905 func (s *session) logPacket(packet *packedPacket) { 1906 if s.logger.Debug() { 1907 s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, %s", packet.header.PacketNumber, packet.buffer.Len(), s.logID, packet.EncryptionLevel()) 1908 } 1909 s.logPacketContents(packet.packetContents) 1910 } 1911 1912 // AcceptStream returns the next stream openend by the peer 1913 func (s *session) AcceptStream(ctx context.Context) (Stream, error) { 1914 return s.streamsMap.AcceptStream(ctx) 1915 } 1916 1917 func (s *session) AcceptUniStream(ctx context.Context) (ReceiveStream, error) { 1918 return s.streamsMap.AcceptUniStream(ctx) 1919 } 1920 1921 // OpenStream opens a stream 1922 func (s *session) OpenStream() (Stream, error) { 1923 return s.streamsMap.OpenStream() 1924 } 1925 1926 func (s *session) OpenStreamSync(ctx context.Context) (Stream, error) { 1927 return s.streamsMap.OpenStreamSync(ctx) 1928 } 1929 1930 func (s *session) OpenUniStream() (SendStream, error) { 1931 return s.streamsMap.OpenUniStream() 1932 } 1933 1934 func (s *session) OpenUniStreamSync(ctx context.Context) (SendStream, error) { 1935 return s.streamsMap.OpenUniStreamSync(ctx) 1936 } 1937 1938 func (s *session) newFlowController(id protocol.StreamID) flowcontrol.StreamFlowController { 1939 initialSendWindow := s.peerParams.InitialMaxStreamDataUni 1940 if id.Type() == protocol.StreamTypeBidi { 1941 if id.InitiatedBy() == s.perspective { 1942 initialSendWindow = s.peerParams.InitialMaxStreamDataBidiRemote 1943 } else { 1944 initialSendWindow = s.peerParams.InitialMaxStreamDataBidiLocal 1945 } 1946 } 1947 return flowcontrol.NewStreamFlowController( 1948 id, 1949 s.connFlowController, 1950 protocol.ByteCount(s.config.InitialStreamReceiveWindow), 1951 protocol.ByteCount(s.config.MaxStreamReceiveWindow), 1952 initialSendWindow, 1953 s.onHasStreamWindowUpdate, 1954 s.rttStats, 1955 s.logger, 1956 ) 1957 } 1958 1959 // scheduleSending signals that we have data for sending 1960 func (s *session) scheduleSending() { 1961 select { 1962 case s.sendingScheduled <- struct{}{}: 1963 default: 1964 } 1965 } 1966 1967 func (s *session) tryQueueingUndecryptablePacket(p *receivedPacket, hdr *wire.Header) { 1968 if s.handshakeComplete { 1969 panic("shouldn't queue undecryptable packets after handshake completion") 1970 } 1971 if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets { 1972 if s.tracer != nil { 1973 s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropDOSPrevention) 1974 } 1975 s.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size()) 1976 return 1977 } 1978 s.logger.Infof("Queueing packet (%d bytes) for later decryption", p.Size()) 1979 if s.tracer != nil { 1980 s.tracer.BufferedPacket(logging.PacketTypeFromHeader(hdr)) 1981 } 1982 s.undecryptablePackets = append(s.undecryptablePackets, p) 1983 } 1984 1985 func (s *session) queueControlFrame(f wire.Frame) { 1986 s.framer.QueueControlFrame(f) 1987 s.scheduleSending() 1988 } 1989 1990 func (s *session) onHasStreamWindowUpdate(id protocol.StreamID) { 1991 s.windowUpdateQueue.AddStream(id) 1992 s.scheduleSending() 1993 } 1994 1995 func (s *session) onHasConnectionWindowUpdate() { 1996 s.windowUpdateQueue.AddConnection() 1997 s.scheduleSending() 1998 } 1999 2000 func (s *session) onHasStreamData(id protocol.StreamID) { 2001 s.framer.AddActiveStream(id) 2002 s.scheduleSending() 2003 } 2004 2005 func (s *session) onStreamCompleted(id protocol.StreamID) { 2006 if err := s.streamsMap.DeleteStream(id); err != nil { 2007 s.closeLocal(err) 2008 } 2009 } 2010 2011 func (s *session) SendMessage(p []byte) error { 2012 f := &wire.DatagramFrame{DataLenPresent: true} 2013 if protocol.ByteCount(len(p)) > f.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version) { 2014 return errors.New("message too large") 2015 } 2016 f.Data = make([]byte, len(p)) 2017 copy(f.Data, p) 2018 return s.datagramQueue.AddAndWait(f) 2019 } 2020 2021 func (s *session) ReceiveMessage() ([]byte, error) { 2022 return s.datagramQueue.Receive() 2023 } 2024 2025 func (s *session) LocalAddr() net.Addr { 2026 return s.conn.LocalAddr() 2027 } 2028 2029 func (s *session) RemoteAddr() net.Addr { 2030 return s.conn.RemoteAddr() 2031 } 2032 2033 func (s *session) getPerspective() protocol.Perspective { 2034 return s.perspective 2035 } 2036 2037 func (s *session) GetVersion() protocol.VersionNumber { 2038 return s.version 2039 } 2040 2041 func (s *session) NextSession() Session { 2042 <-s.HandshakeComplete().Done() 2043 s.streamsMap.UseResetMaps() 2044 return s 2045 }