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