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