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