github.com/MerlinKodo/quic-go@v0.39.2/server.go (about) 1 package quic 2 3 import ( 4 "context" 5 "crypto/tls" 6 "errors" 7 "fmt" 8 "net" 9 "sync" 10 "sync/atomic" 11 "time" 12 13 "github.com/MerlinKodo/quic-go/internal/handshake" 14 "github.com/MerlinKodo/quic-go/internal/protocol" 15 "github.com/MerlinKodo/quic-go/internal/qerr" 16 "github.com/MerlinKodo/quic-go/internal/utils" 17 "github.com/MerlinKodo/quic-go/internal/wire" 18 "github.com/MerlinKodo/quic-go/logging" 19 ) 20 21 // ErrServerClosed is returned by the Listener or EarlyListener's Accept method after a call to Close. 22 var ErrServerClosed = errors.New("quic: server closed") 23 24 // packetHandler handles packets 25 type packetHandler interface { 26 handlePacket(receivedPacket) 27 shutdown() 28 destroy(error) 29 getPerspective() protocol.Perspective 30 } 31 32 type packetHandlerManager interface { 33 Get(protocol.ConnectionID) (packetHandler, bool) 34 GetByResetToken(protocol.StatelessResetToken) (packetHandler, bool) 35 AddWithConnID(protocol.ConnectionID, protocol.ConnectionID, func() (packetHandler, bool)) bool 36 Close(error) 37 CloseServer() 38 connRunner 39 } 40 41 type quicConn interface { 42 EarlyConnection 43 earlyConnReady() <-chan struct{} 44 handlePacket(receivedPacket) 45 GetVersion() protocol.VersionNumber 46 getPerspective() protocol.Perspective 47 run() error 48 destroy(error) 49 shutdown() 50 } 51 52 type zeroRTTQueue struct { 53 packets []receivedPacket 54 expiration time.Time 55 } 56 57 type rejectedPacket struct { 58 receivedPacket 59 hdr *wire.Header 60 } 61 62 // A Listener of QUIC 63 type baseServer struct { 64 mutex sync.Mutex 65 66 disableVersionNegotiation bool 67 acceptEarlyConns bool 68 69 tlsConf *tls.Config 70 config *Config 71 72 conn rawConn 73 74 tokenGenerator *handshake.TokenGenerator 75 maxTokenAge time.Duration 76 77 connIDGenerator ConnectionIDGenerator 78 connHandler packetHandlerManager 79 onClose func() 80 81 receivedPackets chan receivedPacket 82 83 nextZeroRTTCleanup time.Time 84 zeroRTTQueues map[protocol.ConnectionID]*zeroRTTQueue // only initialized if acceptEarlyConns == true 85 86 // set as a member, so they can be set in the tests 87 newConn func( 88 sendConn, 89 connRunner, 90 protocol.ConnectionID, /* original dest connection ID */ 91 *protocol.ConnectionID, /* retry src connection ID */ 92 protocol.ConnectionID, /* client dest connection ID */ 93 protocol.ConnectionID, /* destination connection ID */ 94 protocol.ConnectionID, /* source connection ID */ 95 ConnectionIDGenerator, 96 protocol.StatelessResetToken, 97 *Config, 98 *tls.Config, 99 *handshake.TokenGenerator, 100 bool, /* client address validated by an address validation token */ 101 *logging.ConnectionTracer, 102 uint64, 103 utils.Logger, 104 protocol.VersionNumber, 105 ) quicConn 106 107 serverError error 108 errorChan chan struct{} 109 closed bool 110 running chan struct{} // closed as soon as run() returns 111 versionNegotiationQueue chan receivedPacket 112 invalidTokenQueue chan rejectedPacket 113 connectionRefusedQueue chan rejectedPacket 114 retryQueue chan rejectedPacket 115 116 connQueue chan quicConn 117 connQueueLen int32 // to be used as an atomic 118 119 tracer *logging.Tracer 120 121 logger utils.Logger 122 } 123 124 // A Listener listens for incoming QUIC connections. 125 // It returns connections once the handshake has completed. 126 type Listener struct { 127 baseServer *baseServer 128 } 129 130 // Accept returns new connections. It should be called in a loop. 131 func (l *Listener) Accept(ctx context.Context) (Connection, error) { 132 return l.baseServer.Accept(ctx) 133 } 134 135 // Close the server. All active connections will be closed. 136 func (l *Listener) Close() error { 137 return l.baseServer.Close() 138 } 139 140 // Addr returns the local network address that the server is listening on. 141 func (l *Listener) Addr() net.Addr { 142 return l.baseServer.Addr() 143 } 144 145 // An EarlyListener listens for incoming QUIC connections, and returns them before the handshake completes. 146 // For connections that don't use 0-RTT, this allows the server to send 0.5-RTT data. 147 // This data is encrypted with forward-secure keys, however, the client's identity has not yet been verified. 148 // For connection using 0-RTT, this allows the server to accept and respond to streams that the client opened in the 149 // 0-RTT data it sent. Note that at this point during the handshake, the live-ness of the 150 // client has not yet been confirmed, and the 0-RTT data could have been replayed by an attacker. 151 type EarlyListener struct { 152 baseServer *baseServer 153 } 154 155 // Accept returns a new connections. It should be called in a loop. 156 func (l *EarlyListener) Accept(ctx context.Context) (EarlyConnection, error) { 157 return l.baseServer.accept(ctx) 158 } 159 160 // Close the server. All active connections will be closed. 161 func (l *EarlyListener) Close() error { 162 return l.baseServer.Close() 163 } 164 165 // Addr returns the local network addr that the server is listening on. 166 func (l *EarlyListener) Addr() net.Addr { 167 return l.baseServer.Addr() 168 } 169 170 // ListenAddr creates a QUIC server listening on a given address. 171 // See Listen for more details. 172 func ListenAddr(addr string, tlsConf *tls.Config, config *Config) (*Listener, error) { 173 conn, err := listenUDP(addr) 174 if err != nil { 175 return nil, err 176 } 177 return (&Transport{ 178 Conn: conn, 179 createdConn: true, 180 isSingleUse: true, 181 }).Listen(tlsConf, config) 182 } 183 184 // ListenAddrEarly works like ListenAddr, but it returns connections before the handshake completes. 185 func ListenAddrEarly(addr string, tlsConf *tls.Config, config *Config) (*EarlyListener, error) { 186 conn, err := listenUDP(addr) 187 if err != nil { 188 return nil, err 189 } 190 return (&Transport{ 191 Conn: conn, 192 createdConn: true, 193 isSingleUse: true, 194 }).ListenEarly(tlsConf, config) 195 } 196 197 func listenUDP(addr string) (*net.UDPConn, error) { 198 udpAddr, err := net.ResolveUDPAddr("udp", addr) 199 if err != nil { 200 return nil, err 201 } 202 return net.ListenUDP("udp", udpAddr) 203 } 204 205 // Listen listens for QUIC connections on a given net.PacketConn. 206 // If the PacketConn satisfies the OOBCapablePacketConn interface (as a net.UDPConn does), 207 // ECN and packet info support will be enabled. In this case, ReadMsgUDP and WriteMsgUDP 208 // will be used instead of ReadFrom and WriteTo to read/write packets. 209 // A single net.PacketConn can only be used for a single call to Listen. 210 // 211 // The tls.Config must not be nil and must contain a certificate configuration. 212 // Furthermore, it must define an application control (using NextProtos). 213 // The quic.Config may be nil, in that case the default values will be used. 214 // 215 // This is a convenience function. More advanced use cases should instantiate a Transport, 216 // which offers configuration options for a more fine-grained control of the connection establishment, 217 // including reusing the underlying UDP socket for outgoing QUIC connections. 218 func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*Listener, error) { 219 tr := &Transport{Conn: conn, isSingleUse: true} 220 return tr.Listen(tlsConf, config) 221 } 222 223 // ListenEarly works like Listen, but it returns connections before the handshake completes. 224 func ListenEarly(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*EarlyListener, error) { 225 tr := &Transport{Conn: conn, isSingleUse: true} 226 return tr.ListenEarly(tlsConf, config) 227 } 228 229 func newServer( 230 conn rawConn, 231 connHandler packetHandlerManager, 232 connIDGenerator ConnectionIDGenerator, 233 tlsConf *tls.Config, 234 config *Config, 235 tracer *logging.Tracer, 236 onClose func(), 237 tokenGeneratorKey TokenGeneratorKey, 238 maxTokenAge time.Duration, 239 disableVersionNegotiation bool, 240 acceptEarly bool, 241 ) *baseServer { 242 s := &baseServer{ 243 conn: conn, 244 tlsConf: tlsConf, 245 config: config, 246 tokenGenerator: handshake.NewTokenGenerator(tokenGeneratorKey), 247 maxTokenAge: maxTokenAge, 248 connIDGenerator: connIDGenerator, 249 connHandler: connHandler, 250 connQueue: make(chan quicConn), 251 errorChan: make(chan struct{}), 252 running: make(chan struct{}), 253 receivedPackets: make(chan receivedPacket, protocol.MaxServerUnprocessedPackets), 254 versionNegotiationQueue: make(chan receivedPacket, 4), 255 invalidTokenQueue: make(chan rejectedPacket, 4), 256 connectionRefusedQueue: make(chan rejectedPacket, 4), 257 retryQueue: make(chan rejectedPacket, 8), 258 newConn: newConnection, 259 tracer: tracer, 260 logger: utils.DefaultLogger.WithPrefix("server"), 261 acceptEarlyConns: acceptEarly, 262 disableVersionNegotiation: disableVersionNegotiation, 263 onClose: onClose, 264 } 265 if acceptEarly { 266 s.zeroRTTQueues = map[protocol.ConnectionID]*zeroRTTQueue{} 267 } 268 go s.run() 269 go s.runSendQueue() 270 s.logger.Debugf("Listening for %s connections on %s", conn.LocalAddr().Network(), conn.LocalAddr().String()) 271 return s 272 } 273 274 func (s *baseServer) run() { 275 defer close(s.running) 276 for { 277 select { 278 case <-s.errorChan: 279 return 280 default: 281 } 282 select { 283 case <-s.errorChan: 284 return 285 case p := <-s.receivedPackets: 286 if bufferStillInUse := s.handlePacketImpl(p); !bufferStillInUse { 287 p.buffer.Release() 288 } 289 } 290 } 291 } 292 293 func (s *baseServer) runSendQueue() { 294 for { 295 select { 296 case <-s.running: 297 return 298 case p := <-s.versionNegotiationQueue: 299 s.maybeSendVersionNegotiationPacket(p) 300 case p := <-s.invalidTokenQueue: 301 s.maybeSendInvalidToken(p) 302 case p := <-s.connectionRefusedQueue: 303 s.sendConnectionRefused(p) 304 case p := <-s.retryQueue: 305 s.sendRetry(p) 306 } 307 } 308 } 309 310 // Accept returns connections that already completed the handshake. 311 // It is only valid if acceptEarlyConns is false. 312 func (s *baseServer) Accept(ctx context.Context) (Connection, error) { 313 return s.accept(ctx) 314 } 315 316 func (s *baseServer) accept(ctx context.Context) (quicConn, error) { 317 select { 318 case <-ctx.Done(): 319 return nil, ctx.Err() 320 case conn := <-s.connQueue: 321 atomic.AddInt32(&s.connQueueLen, -1) 322 return conn, nil 323 case <-s.errorChan: 324 return nil, s.serverError 325 } 326 } 327 328 // Close the server 329 func (s *baseServer) Close() error { 330 s.mutex.Lock() 331 if s.closed { 332 s.mutex.Unlock() 333 return nil 334 } 335 if s.serverError == nil { 336 s.serverError = ErrServerClosed 337 } 338 s.closed = true 339 close(s.errorChan) 340 s.mutex.Unlock() 341 342 <-s.running 343 s.onClose() 344 return nil 345 } 346 347 func (s *baseServer) setCloseError(e error) { 348 s.mutex.Lock() 349 defer s.mutex.Unlock() 350 if s.closed { 351 return 352 } 353 s.closed = true 354 s.serverError = e 355 close(s.errorChan) 356 } 357 358 // Addr returns the server's network address 359 func (s *baseServer) Addr() net.Addr { 360 return s.conn.LocalAddr() 361 } 362 363 func (s *baseServer) handlePacket(p receivedPacket) { 364 select { 365 case s.receivedPackets <- p: 366 default: 367 s.logger.Debugf("Dropping packet from %s (%d bytes). Server receive queue full.", p.remoteAddr, p.Size()) 368 if s.tracer != nil && s.tracer.DroppedPacket != nil { 369 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) 370 } 371 } 372 } 373 374 func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer still in use? */ { 375 if !s.nextZeroRTTCleanup.IsZero() && p.rcvTime.After(s.nextZeroRTTCleanup) { 376 defer s.cleanupZeroRTTQueues(p.rcvTime) 377 } 378 379 if wire.IsVersionNegotiationPacket(p.data) { 380 s.logger.Debugf("Dropping Version Negotiation packet.") 381 if s.tracer != nil && s.tracer.DroppedPacket != nil { 382 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket) 383 } 384 return false 385 } 386 // Short header packets should never end up here in the first place 387 if !wire.IsLongHeaderPacket(p.data[0]) { 388 panic(fmt.Sprintf("misrouted packet: %#v", p.data)) 389 } 390 v, err := wire.ParseVersion(p.data) 391 // drop the packet if we failed to parse the protocol version 392 if err != nil { 393 s.logger.Debugf("Dropping a packet with an unknown version") 394 if s.tracer != nil && s.tracer.DroppedPacket != nil { 395 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) 396 } 397 return false 398 } 399 // send a Version Negotiation Packet if the client is speaking a different protocol version 400 if !protocol.IsSupportedVersion(s.config.Versions, v) { 401 if s.disableVersionNegotiation { 402 return false 403 } 404 405 if p.Size() < protocol.MinUnknownVersionPacketSize { 406 s.logger.Debugf("Dropping a packet with an unsupported version number %d that is too small (%d bytes)", v, p.Size()) 407 if s.tracer != nil && s.tracer.DroppedPacket != nil { 408 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) 409 } 410 return false 411 } 412 return s.enqueueVersionNegotiationPacket(p) 413 } 414 415 if wire.Is0RTTPacket(p.data) { 416 if !s.acceptEarlyConns { 417 if s.tracer != nil && s.tracer.DroppedPacket != nil { 418 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropUnexpectedPacket) 419 } 420 return false 421 } 422 return s.handle0RTTPacket(p) 423 } 424 425 // If we're creating a new connection, the packet will be passed to the connection. 426 // The header will then be parsed again. 427 hdr, _, _, err := wire.ParsePacket(p.data) 428 if err != nil { 429 if s.tracer != nil && s.tracer.DroppedPacket != nil { 430 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) 431 } 432 s.logger.Debugf("Error parsing packet: %s", err) 433 return false 434 } 435 if hdr.Type == protocol.PacketTypeInitial && p.Size() < protocol.MinInitialPacketSize { 436 s.logger.Debugf("Dropping a packet that is too small to be a valid Initial (%d bytes)", p.Size()) 437 if s.tracer != nil && s.tracer.DroppedPacket != nil { 438 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) 439 } 440 return false 441 } 442 443 if hdr.Type != protocol.PacketTypeInitial { 444 // Drop long header packets. 445 // There's little point in sending a Stateless Reset, since the client 446 // might not have received the token yet. 447 s.logger.Debugf("Dropping long header packet of type %s (%d bytes)", hdr.Type, len(p.data)) 448 if s.tracer != nil && s.tracer.DroppedPacket != nil { 449 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropUnexpectedPacket) 450 } 451 return false 452 } 453 454 s.logger.Debugf("<- Received Initial packet.") 455 456 if err := s.handleInitialImpl(p, hdr); err != nil { 457 s.logger.Errorf("Error occurred handling initial packet: %s", err) 458 } 459 // Don't put the packet buffer back. 460 // handleInitialImpl deals with the buffer. 461 return true 462 } 463 464 func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { 465 connID, err := wire.ParseConnectionID(p.data, 0) 466 if err != nil { 467 if s.tracer != nil && s.tracer.DroppedPacket != nil { 468 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropHeaderParseError) 469 } 470 return false 471 } 472 473 // check again if we might have a connection now 474 if handler, ok := s.connHandler.Get(connID); ok { 475 handler.handlePacket(p) 476 return true 477 } 478 479 if q, ok := s.zeroRTTQueues[connID]; ok { 480 if len(q.packets) >= protocol.Max0RTTQueueLen { 481 if s.tracer != nil && s.tracer.DroppedPacket != nil { 482 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) 483 } 484 return false 485 } 486 q.packets = append(q.packets, p) 487 return true 488 } 489 490 if len(s.zeroRTTQueues) >= protocol.Max0RTTQueues { 491 if s.tracer != nil && s.tracer.DroppedPacket != nil { 492 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) 493 } 494 return false 495 } 496 queue := &zeroRTTQueue{packets: make([]receivedPacket, 1, 8)} 497 queue.packets[0] = p 498 expiration := p.rcvTime.Add(protocol.Max0RTTQueueingDuration) 499 queue.expiration = expiration 500 if s.nextZeroRTTCleanup.IsZero() || s.nextZeroRTTCleanup.After(expiration) { 501 s.nextZeroRTTCleanup = expiration 502 } 503 s.zeroRTTQueues[connID] = queue 504 return true 505 } 506 507 func (s *baseServer) cleanupZeroRTTQueues(now time.Time) { 508 // Iterate over all queues to find those that are expired. 509 // This is ok since we're placing a pretty low limit on the number of queues. 510 var nextCleanup time.Time 511 for connID, q := range s.zeroRTTQueues { 512 if q.expiration.After(now) { 513 if nextCleanup.IsZero() || nextCleanup.After(q.expiration) { 514 nextCleanup = q.expiration 515 } 516 continue 517 } 518 for _, p := range q.packets { 519 if s.tracer != nil && s.tracer.DroppedPacket != nil { 520 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) 521 } 522 p.buffer.Release() 523 } 524 delete(s.zeroRTTQueues, connID) 525 if s.logger.Debug() { 526 s.logger.Debugf("Removing 0-RTT queue for %s.", connID) 527 } 528 } 529 s.nextZeroRTTCleanup = nextCleanup 530 } 531 532 // validateToken returns false if: 533 // - address is invalid 534 // - token is expired 535 // - token is null 536 func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { 537 if token == nil { 538 return false 539 } 540 if !token.ValidateRemoteAddr(addr) { 541 return false 542 } 543 if !token.IsRetryToken && time.Since(token.SentTime) > s.maxTokenAge { 544 return false 545 } 546 if token.IsRetryToken && time.Since(token.SentTime) > s.config.maxRetryTokenAge() { 547 return false 548 } 549 return true 550 } 551 552 func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error { 553 if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { 554 p.buffer.Release() 555 if s.tracer != nil && s.tracer.DroppedPacket != nil { 556 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) 557 } 558 return errors.New("too short connection ID") 559 } 560 561 // The server queues packets for a while, and we might already have established a connection by now. 562 // This results in a second check in the connection map. 563 // That's ok since it's not the hot path (it's only taken by some Initial and 0-RTT packets). 564 if handler, ok := s.connHandler.Get(hdr.DestConnectionID); ok { 565 handler.handlePacket(p) 566 return nil 567 } 568 569 var ( 570 token *handshake.Token 571 retrySrcConnID *protocol.ConnectionID 572 ) 573 origDestConnID := hdr.DestConnectionID 574 if len(hdr.Token) > 0 { 575 tok, err := s.tokenGenerator.DecodeToken(hdr.Token) 576 if err == nil { 577 if tok.IsRetryToken { 578 origDestConnID = tok.OriginalDestConnectionID 579 retrySrcConnID = &tok.RetrySrcConnectionID 580 } 581 token = tok 582 } 583 } 584 585 clientAddrIsValid := s.validateToken(token, p.remoteAddr) 586 if token != nil && !clientAddrIsValid { 587 // For invalid and expired non-retry tokens, we don't send an INVALID_TOKEN error. 588 // We just ignore them, and act as if there was no token on this packet at all. 589 // This also means we might send a Retry later. 590 if !token.IsRetryToken { 591 token = nil 592 } else { 593 // For Retry tokens, we send an INVALID_ERROR if 594 // * the token is too old, or 595 // * the token is invalid, in case of a retry token. 596 select { 597 case s.invalidTokenQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: 598 default: 599 // drop packet if we can't send out the INVALID_TOKEN packets fast enough 600 p.buffer.Release() 601 } 602 return nil 603 } 604 } 605 if token == nil && s.config.RequireAddressValidation(p.remoteAddr) { 606 // Retry invalidates all 0-RTT packets sent. 607 delete(s.zeroRTTQueues, hdr.DestConnectionID) 608 select { 609 case s.retryQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: 610 default: 611 // drop packet if we can't send out Retry packets fast enough 612 p.buffer.Release() 613 } 614 return nil 615 } 616 617 if queueLen := atomic.LoadInt32(&s.connQueueLen); queueLen >= protocol.MaxAcceptQueueSize { 618 s.logger.Debugf("Rejecting new connection. Server currently busy. Accept queue length: %d (max %d)", queueLen, protocol.MaxAcceptQueueSize) 619 select { 620 case s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: 621 default: 622 // drop packet if we can't send out the CONNECTION_REFUSED fast enough 623 p.buffer.Release() 624 } 625 return nil 626 } 627 628 connID, err := s.connIDGenerator.GenerateConnectionID() 629 if err != nil { 630 return err 631 } 632 s.logger.Debugf("Changing connection ID to %s.", connID) 633 var conn quicConn 634 tracingID := nextConnTracingID() 635 if added := s.connHandler.AddWithConnID(hdr.DestConnectionID, connID, func() (packetHandler, bool) { 636 config := s.config 637 if s.config.GetConfigForClient != nil { 638 conf, err := s.config.GetConfigForClient(&ClientHelloInfo{RemoteAddr: p.remoteAddr}) 639 if err != nil { 640 s.logger.Debugf("Rejecting new connection due to GetConfigForClient callback") 641 return nil, false 642 } 643 config = populateConfig(conf) 644 } 645 var tracer *logging.ConnectionTracer 646 if config.Tracer != nil { 647 // Use the same connection ID that is passed to the client's GetLogWriter callback. 648 connID := hdr.DestConnectionID 649 if origDestConnID.Len() > 0 { 650 connID = origDestConnID 651 } 652 tracer = config.Tracer(context.WithValue(context.Background(), ConnectionTracingKey, tracingID), protocol.PerspectiveServer, connID) 653 } 654 conn = s.newConn( 655 newSendConn(s.conn, p.remoteAddr, p.info, s.logger), 656 s.connHandler, 657 origDestConnID, 658 retrySrcConnID, 659 hdr.DestConnectionID, 660 hdr.SrcConnectionID, 661 connID, 662 s.connIDGenerator, 663 s.connHandler.GetStatelessResetToken(connID), 664 config, 665 s.tlsConf, 666 s.tokenGenerator, 667 clientAddrIsValid, 668 tracer, 669 tracingID, 670 s.logger, 671 hdr.Version, 672 ) 673 conn.handlePacket(p) 674 675 if q, ok := s.zeroRTTQueues[hdr.DestConnectionID]; ok { 676 for _, p := range q.packets { 677 conn.handlePacket(p) 678 } 679 delete(s.zeroRTTQueues, hdr.DestConnectionID) 680 } 681 682 return conn, true 683 }); !added { 684 select { 685 case s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: 686 default: 687 // drop packet if we can't send out the CONNECTION_REFUSED fast enough 688 p.buffer.Release() 689 } 690 return nil 691 } 692 go conn.run() 693 go s.handleNewConn(conn) 694 if conn == nil { 695 p.buffer.Release() 696 return nil 697 } 698 return nil 699 } 700 701 func (s *baseServer) handleNewConn(conn quicConn) { 702 connCtx := conn.Context() 703 if s.acceptEarlyConns { 704 // wait until the early connection is ready (or the handshake fails) 705 select { 706 case <-conn.earlyConnReady(): 707 case <-connCtx.Done(): 708 return 709 } 710 } else { 711 // wait until the handshake is complete (or fails) 712 select { 713 case <-conn.HandshakeComplete(): 714 case <-connCtx.Done(): 715 return 716 } 717 } 718 719 atomic.AddInt32(&s.connQueueLen, 1) 720 select { 721 case s.connQueue <- conn: 722 // blocks until the connection is accepted 723 case <-connCtx.Done(): 724 atomic.AddInt32(&s.connQueueLen, -1) 725 // don't pass connections that were already closed to Accept() 726 } 727 } 728 729 func (s *baseServer) sendRetry(p rejectedPacket) { 730 if err := s.sendRetryPacket(p); err != nil { 731 s.logger.Debugf("Error sending Retry packet: %s", err) 732 } 733 } 734 735 func (s *baseServer) sendRetryPacket(p rejectedPacket) error { 736 hdr := p.hdr 737 // Log the Initial packet now. 738 // If no Retry is sent, the packet will be logged by the connection. 739 (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) 740 srcConnID, err := s.connIDGenerator.GenerateConnectionID() 741 if err != nil { 742 return err 743 } 744 token, err := s.tokenGenerator.NewRetryToken(p.remoteAddr, hdr.DestConnectionID, srcConnID) 745 if err != nil { 746 return err 747 } 748 replyHdr := &wire.ExtendedHeader{} 749 replyHdr.Type = protocol.PacketTypeRetry 750 replyHdr.Version = hdr.Version 751 replyHdr.SrcConnectionID = srcConnID 752 replyHdr.DestConnectionID = hdr.SrcConnectionID 753 replyHdr.Token = token 754 if s.logger.Debug() { 755 s.logger.Debugf("Changing connection ID to %s.", srcConnID) 756 s.logger.Debugf("-> Sending Retry") 757 replyHdr.Log(s.logger) 758 } 759 760 buf := getPacketBuffer() 761 defer buf.Release() 762 buf.Data, err = replyHdr.Append(buf.Data, hdr.Version) 763 if err != nil { 764 return err 765 } 766 // append the Retry integrity tag 767 tag := handshake.GetRetryIntegrityTag(buf.Data, hdr.DestConnectionID, hdr.Version) 768 buf.Data = append(buf.Data, tag[:]...) 769 if s.tracer != nil && s.tracer.SentPacket != nil { 770 s.tracer.SentPacket(p.remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) 771 } 772 _, err = s.conn.WritePacket(buf.Data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported) 773 return err 774 } 775 776 func (s *baseServer) maybeSendInvalidToken(p rejectedPacket) { 777 defer p.buffer.Release() 778 779 // Only send INVALID_TOKEN if we can unprotect the packet. 780 // This makes sure that we won't send it for packets that were corrupted. 781 hdr := p.hdr 782 sealer, opener := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer, hdr.Version) 783 data := p.data[:hdr.ParsedLen()+hdr.Length] 784 extHdr, err := unpackLongHeader(opener, hdr, data, hdr.Version) 785 // Only send INVALID_TOKEN if we can unprotect the packet. 786 // This makes sure that we won't send it for packets that were corrupted. 787 if err != nil { 788 if s.tracer != nil && s.tracer.DroppedPacket != nil { 789 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropHeaderParseError) 790 } 791 return 792 } 793 hdrLen := extHdr.ParsedLen() 794 if _, err := opener.Open(data[hdrLen:hdrLen], data[hdrLen:], extHdr.PacketNumber, data[:hdrLen]); err != nil { 795 if s.tracer != nil && s.tracer.DroppedPacket != nil { 796 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropPayloadDecryptError) 797 } 798 return 799 } 800 if s.logger.Debug() { 801 s.logger.Debugf("Client sent an invalid retry token. Sending INVALID_TOKEN to %s.", p.remoteAddr) 802 } 803 if err := s.sendError(p.remoteAddr, hdr, sealer, qerr.InvalidToken, p.info); err != nil { 804 s.logger.Debugf("Error sending INVALID_TOKEN error: %s", err) 805 } 806 } 807 808 func (s *baseServer) sendConnectionRefused(p rejectedPacket) { 809 defer p.buffer.Release() 810 sealer, _ := handshake.NewInitialAEAD(p.hdr.DestConnectionID, protocol.PerspectiveServer, p.hdr.Version) 811 if err := s.sendError(p.remoteAddr, p.hdr, sealer, qerr.ConnectionRefused, p.info); err != nil { 812 s.logger.Debugf("Error sending CONNECTION_REFUSED error: %s", err) 813 } 814 } 815 816 // sendError sends the error as a response to the packet received with header hdr 817 func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer handshake.LongHeaderSealer, errorCode qerr.TransportErrorCode, info packetInfo) error { 818 b := getPacketBuffer() 819 defer b.Release() 820 821 ccf := &wire.ConnectionCloseFrame{ErrorCode: uint64(errorCode)} 822 823 replyHdr := &wire.ExtendedHeader{} 824 replyHdr.Type = protocol.PacketTypeInitial 825 replyHdr.Version = hdr.Version 826 replyHdr.SrcConnectionID = hdr.DestConnectionID 827 replyHdr.DestConnectionID = hdr.SrcConnectionID 828 replyHdr.PacketNumberLen = protocol.PacketNumberLen4 829 replyHdr.Length = 4 /* packet number len */ + ccf.Length(hdr.Version) + protocol.ByteCount(sealer.Overhead()) 830 var err error 831 b.Data, err = replyHdr.Append(b.Data, hdr.Version) 832 if err != nil { 833 return err 834 } 835 payloadOffset := len(b.Data) 836 837 b.Data, err = ccf.Append(b.Data, hdr.Version) 838 if err != nil { 839 return err 840 } 841 842 _ = sealer.Seal(b.Data[payloadOffset:payloadOffset], b.Data[payloadOffset:], replyHdr.PacketNumber, b.Data[:payloadOffset]) 843 b.Data = b.Data[0 : len(b.Data)+sealer.Overhead()] 844 845 pnOffset := payloadOffset - int(replyHdr.PacketNumberLen) 846 sealer.EncryptHeader( 847 b.Data[pnOffset+4:pnOffset+4+16], 848 &b.Data[0], 849 b.Data[pnOffset:payloadOffset], 850 ) 851 852 replyHdr.Log(s.logger) 853 wire.LogFrame(s.logger, ccf, true) 854 if s.tracer != nil && s.tracer.SentPacket != nil { 855 s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) 856 } 857 _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) 858 return err 859 } 860 861 func (s *baseServer) enqueueVersionNegotiationPacket(p receivedPacket) (bufferInUse bool) { 862 select { 863 case s.versionNegotiationQueue <- p: 864 return true 865 default: 866 // it's fine to not send version negotiation packets when we are busy 867 } 868 return false 869 } 870 871 func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { 872 defer p.buffer.Release() 873 874 v, err := wire.ParseVersion(p.data) 875 if err != nil { 876 s.logger.Debugf("failed to parse version for sending version negotiation packet: %s", err) 877 return 878 } 879 880 _, src, dest, err := wire.ParseArbitraryLenConnectionIDs(p.data) 881 if err != nil { // should never happen 882 s.logger.Debugf("Dropping a packet with an unknown version for which we failed to parse connection IDs") 883 if s.tracer != nil && s.tracer.DroppedPacket != nil { 884 s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) 885 } 886 return 887 } 888 889 s.logger.Debugf("Client offered version %s, sending Version Negotiation", v) 890 891 data := wire.ComposeVersionNegotiation(dest, src, s.config.Versions) 892 if s.tracer != nil && s.tracer.SentVersionNegotiationPacket != nil { 893 s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) 894 } 895 if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil { 896 s.logger.Debugf("Error sending Version Negotiation: %s", err) 897 } 898 }