github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/server.go (about) 1 package quic 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rand" 7 "crypto/tls" 8 "errors" 9 "fmt" 10 "net" 11 "sync" 12 "sync/atomic" 13 "time" 14 15 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/handshake" 16 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol" 17 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qerr" 18 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qtls" 19 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/utils" 20 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/wire" 21 "github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/logging" 22 ) 23 24 // packetHandler handles packets 25 type packetHandler interface { 26 handlePacket(*receivedPacket) 27 shutdown() 28 destroy(error) 29 getPerspective() protocol.Perspective 30 } 31 32 type unknownPacketHandler interface { 33 handlePacket(*receivedPacket) 34 setCloseError(error) 35 } 36 37 type packetHandlerManager interface { 38 AddWithConnID(protocol.ConnectionID, protocol.ConnectionID, func() packetHandler) bool 39 Destroy() error 40 sessionRunner 41 SetServer(unknownPacketHandler) 42 CloseServer() 43 } 44 45 type quicSession interface { 46 EarlySession 47 earlySessionReady() <-chan struct{} 48 handlePacket(*receivedPacket) 49 GetVersion() protocol.VersionNumber 50 getPerspective() protocol.Perspective 51 run() error 52 destroy(error) 53 shutdown() 54 } 55 56 // A Listener of QUIC 57 type baseServer struct { 58 mutex sync.Mutex 59 60 acceptEarlySessions bool 61 62 tlsConf *tls.Config 63 config *Config 64 65 conn connection 66 // If the server is started with ListenAddr, we create a packet conn. 67 // If it is started with Listen, we take a packet conn as a parameter. 68 createdPacketConn bool 69 70 tokenGenerator *handshake.TokenGenerator 71 72 sessionHandler packetHandlerManager 73 74 receivedPackets chan *receivedPacket 75 76 // set as a member, so they can be set in the tests 77 newSession func( 78 sendConn, 79 sessionRunner, 80 protocol.ConnectionID, /* original dest connection ID */ 81 *protocol.ConnectionID, /* retry src connection ID */ 82 protocol.ConnectionID, /* client dest connection ID */ 83 protocol.ConnectionID, /* destination connection ID */ 84 protocol.ConnectionID, /* source connection ID */ 85 protocol.StatelessResetToken, 86 *Config, 87 *tls.Config, 88 *handshake.TokenGenerator, 89 bool, /* enable 0-RTT */ 90 logging.ConnectionTracer, 91 uint64, 92 utils.Logger, 93 protocol.VersionNumber, 94 ) quicSession 95 96 serverError error 97 errorChan chan struct{} 98 closed bool 99 running chan struct{} // closed as soon as run() returns 100 101 sessionQueue chan quicSession 102 sessionQueueLen int32 // to be used as an atomic 103 104 logger utils.Logger 105 } 106 107 var ( 108 _ Listener = &baseServer{} 109 _ unknownPacketHandler = &baseServer{} 110 ) 111 112 type earlyServer struct{ *baseServer } 113 114 var _ EarlyListener = &earlyServer{} 115 116 func (s *earlyServer) Accept(ctx context.Context) (EarlySession, error) { 117 return s.baseServer.accept(ctx) 118 } 119 120 // ListenAddr creates a QUIC server listening on a given address. 121 // The tls.Config must not be nil and must contain a certificate configuration. 122 // The quic.Config may be nil, in that case the default values will be used. 123 func ListenAddr(addr string, tlsConf *tls.Config, config *Config) (Listener, error) { 124 return listenAddr(addr, tlsConf, config, false) 125 } 126 127 // ListenAddrEarly works like ListenAddr, but it returns sessions before the handshake completes. 128 func ListenAddrEarly(addr string, tlsConf *tls.Config, config *Config) (EarlyListener, error) { 129 s, err := listenAddr(addr, tlsConf, config, true) 130 if err != nil { 131 return nil, err 132 } 133 return &earlyServer{s}, nil 134 } 135 136 func listenAddr(addr string, tlsConf *tls.Config, config *Config, acceptEarly bool) (*baseServer, error) { 137 udpAddr, err := net.ResolveUDPAddr("udp", addr) 138 if err != nil { 139 return nil, err 140 } 141 conn, err := net.ListenUDP("udp", udpAddr) 142 if err != nil { 143 return nil, err 144 } 145 serv, err := listen(conn, tlsConf, config, acceptEarly) 146 if err != nil { 147 return nil, err 148 } 149 serv.createdPacketConn = true 150 return serv, nil 151 } 152 153 // Listen listens for QUIC connections on a given net.PacketConn. If the 154 // PacketConn satisfies the OOBCapablePacketConn interface (as a net.UDPConn 155 // does), ECN and packet info support will be enabled. In this case, ReadMsgUDP 156 // and WriteMsgUDP will be used instead of ReadFrom and WriteTo to read/write 157 // packets. A single net.PacketConn only be used for a single call to Listen. 158 // The PacketConn can be used for simultaneous calls to Dial. QUIC connection 159 // IDs are used for demultiplexing the different connections. The tls.Config 160 // must not be nil and must contain a certificate configuration. The 161 // tls.Config.CipherSuites allows setting of TLS 1.3 cipher suites. Furthermore, 162 // it must define an application control (using NextProtos). The quic.Config may 163 // be nil, in that case the default values will be used. 164 func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener, error) { 165 return listen(conn, tlsConf, config, false) 166 } 167 168 // ListenEarly works like Listen, but it returns sessions before the handshake completes. 169 func ListenEarly(conn net.PacketConn, tlsConf *tls.Config, config *Config) (EarlyListener, error) { 170 s, err := listen(conn, tlsConf, config, true) 171 if err != nil { 172 return nil, err 173 } 174 return &earlyServer{s}, nil 175 } 176 177 func listen(conn net.PacketConn, tlsConf *tls.Config, config *Config, acceptEarly bool) (*baseServer, error) { 178 if tlsConf == nil { 179 return nil, errors.New("quic: tls.Config not set") 180 } 181 if err := validateConfig(config); err != nil { 182 return nil, err 183 } 184 config = populateServerConfig(config) 185 for _, v := range config.Versions { 186 if !protocol.IsValidVersion(v) { 187 return nil, fmt.Errorf("%s is not a valid QUIC version", v) 188 } 189 } 190 191 sessionHandler, err := getMultiplexer().AddConn(conn, config.ConnectionIDLength, config.StatelessResetKey, config.Tracer) 192 if err != nil { 193 return nil, err 194 } 195 tokenGenerator, err := handshake.NewTokenGenerator(rand.Reader) 196 if err != nil { 197 return nil, err 198 } 199 c, err := wrapConn(conn) 200 if err != nil { 201 return nil, err 202 } 203 s := &baseServer{ 204 conn: c, 205 tlsConf: tlsConf, 206 config: config, 207 tokenGenerator: tokenGenerator, 208 sessionHandler: sessionHandler, 209 sessionQueue: make(chan quicSession), 210 errorChan: make(chan struct{}), 211 running: make(chan struct{}), 212 receivedPackets: make(chan *receivedPacket, protocol.MaxServerUnprocessedPackets), 213 newSession: newSession, 214 logger: utils.DefaultLogger.WithPrefix("server"), 215 acceptEarlySessions: acceptEarly, 216 } 217 go s.run() 218 sessionHandler.SetServer(s) 219 s.logger.Debugf("Listening for %s connections on %s", conn.LocalAddr().Network(), conn.LocalAddr().String()) 220 return s, nil 221 } 222 223 func (s *baseServer) run() { 224 defer close(s.running) 225 for { 226 select { 227 case <-s.errorChan: 228 return 229 default: 230 } 231 select { 232 case <-s.errorChan: 233 return 234 case p := <-s.receivedPackets: 235 if bufferStillInUse := s.handlePacketImpl(p); !bufferStillInUse { 236 p.buffer.Release() 237 } 238 } 239 } 240 } 241 242 var defaultAcceptToken = func(clientAddr net.Addr, token *Token) bool { 243 if token == nil { 244 return false 245 } 246 validity := protocol.TokenValidity 247 if token.IsRetryToken { 248 validity = protocol.RetryTokenValidity 249 } 250 if time.Now().After(token.SentTime.Add(validity)) { 251 return false 252 } 253 var sourceAddr string 254 if udpAddr, ok := clientAddr.(*net.UDPAddr); ok { 255 sourceAddr = udpAddr.IP.String() 256 } else { 257 sourceAddr = clientAddr.String() 258 } 259 return sourceAddr == token.RemoteAddr 260 } 261 262 // Accept returns sessions that already completed the handshake. 263 // It is only valid if acceptEarlySessions is false. 264 func (s *baseServer) Accept(ctx context.Context) (Session, error) { 265 return s.accept(ctx) 266 } 267 268 func (s *baseServer) accept(ctx context.Context) (quicSession, error) { 269 select { 270 case <-ctx.Done(): 271 return nil, ctx.Err() 272 case sess := <-s.sessionQueue: 273 atomic.AddInt32(&s.sessionQueueLen, -1) 274 return sess, nil 275 case <-s.errorChan: 276 return nil, s.serverError 277 } 278 } 279 280 // Close the server 281 func (s *baseServer) Close() error { 282 s.mutex.Lock() 283 if s.closed { 284 s.mutex.Unlock() 285 return nil 286 } 287 if s.serverError == nil { 288 s.serverError = errors.New("server closed") 289 } 290 // If the server was started with ListenAddr, we created the packet conn. 291 // We need to close it in order to make the go routine reading from that conn return. 292 createdPacketConn := s.createdPacketConn 293 s.closed = true 294 close(s.errorChan) 295 s.mutex.Unlock() 296 297 <-s.running 298 s.sessionHandler.CloseServer() 299 if createdPacketConn { 300 return s.sessionHandler.Destroy() 301 } 302 return nil 303 } 304 305 func (s *baseServer) setCloseError(e error) { 306 s.mutex.Lock() 307 defer s.mutex.Unlock() 308 if s.closed { 309 return 310 } 311 s.closed = true 312 s.serverError = e 313 close(s.errorChan) 314 } 315 316 // Addr returns the server's network address 317 func (s *baseServer) Addr() net.Addr { 318 return s.conn.LocalAddr() 319 } 320 321 func (s *baseServer) handlePacket(p *receivedPacket) { 322 select { 323 case s.receivedPackets <- p: 324 default: 325 s.logger.Debugf("Dropping packet from %s (%d bytes). Server receive queue full.", p.remoteAddr, p.Size()) 326 if s.config.Tracer != nil { 327 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) 328 } 329 } 330 } 331 332 func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* is the buffer still in use? */ { 333 if wire.IsVersionNegotiationPacket(p.data) { 334 s.logger.Debugf("Dropping Version Negotiation packet.") 335 if s.config.Tracer != nil { 336 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket) 337 } 338 return false 339 } 340 // If we're creating a new session, the packet will be passed to the session. 341 // The header will then be parsed again. 342 hdr, _, _, err := wire.ParsePacket(p.data, s.config.ConnectionIDLength) 343 if err != nil && err != wire.ErrUnsupportedVersion { 344 if s.config.Tracer != nil { 345 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) 346 } 347 s.logger.Debugf("Error parsing packet: %s", err) 348 return false 349 } 350 // Short header packets should never end up here in the first place 351 if !hdr.IsLongHeader { 352 panic(fmt.Sprintf("misrouted packet: %#v", hdr)) 353 } 354 355 // [Psiphon] 356 // To accomodate additional messages, obfuscated QUIC packets may reserve 357 // significant space in the Initial packet and send less that 1200 QUIC 358 // bytes. In this configuration, the obfuscation layer enforces the 359 // anti-amplification 1200 byte rule, but it must be disabled here. 360 isObfuscated := s.config.ServerMaxPacketSizeAdjustment != nil && s.config.ServerMaxPacketSizeAdjustment(p.remoteAddr) > 0 361 362 if !isObfuscated && 363 364 hdr.Type == protocol.PacketTypeInitial && p.Size() < protocol.MinInitialPacketSize { 365 s.logger.Debugf("Dropping a packet that is too small to be a valid Initial (%d bytes)", p.Size()) 366 if s.config.Tracer != nil { 367 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) 368 } 369 return false 370 } 371 // send a Version Negotiation Packet if the client is speaking a different protocol version 372 if !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) { 373 if p.Size() < protocol.MinUnknownVersionPacketSize { 374 s.logger.Debugf("Dropping a packet with an unknown version that is too small (%d bytes)", p.Size()) 375 if s.config.Tracer != nil { 376 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) 377 } 378 return false 379 } 380 if !s.config.DisableVersionNegotiationPackets { 381 go s.sendVersionNegotiationPacket(p, hdr) 382 } 383 return false 384 } 385 if hdr.IsLongHeader && hdr.Type != protocol.PacketTypeInitial { 386 // Drop long header packets. 387 // There's little point in sending a Stateless Reset, since the client 388 // might not have received the token yet. 389 s.logger.Debugf("Dropping long header packet of type %s (%d bytes)", hdr.Type, len(p.data)) 390 if s.config.Tracer != nil { 391 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropUnexpectedPacket) 392 } 393 return false 394 } 395 396 s.logger.Debugf("<- Received Initial packet.") 397 398 if err := s.handleInitialImpl(p, hdr); err != nil { 399 s.logger.Errorf("Error occurred handling initial packet: %s", err) 400 } 401 // Don't put the packet buffer back. 402 // handleInitialImpl deals with the buffer. 403 return true 404 } 405 406 // [Psiphon] 407 type stubCryptoSetup struct { 408 initialOpener handshake.LongHeaderOpener 409 } 410 411 var notSupported = errors.New("not supported") 412 413 func (s *stubCryptoSetup) RunHandshake() { 414 } 415 416 func (s *stubCryptoSetup) Close() error { 417 return notSupported 418 } 419 420 func (s *stubCryptoSetup) ChangeConnectionID(protocol.ConnectionID) { 421 } 422 423 func (s *stubCryptoSetup) GetSessionTicket() ([]byte, error) { 424 return nil, notSupported 425 } 426 427 func (s *stubCryptoSetup) HandleMessage([]byte, protocol.EncryptionLevel) bool { 428 return false 429 } 430 431 func (s *stubCryptoSetup) SetLargest1RTTAcked(protocol.PacketNumber) error { 432 return notSupported 433 } 434 435 func (s *stubCryptoSetup) SetHandshakeConfirmed() { 436 } 437 438 func (s *stubCryptoSetup) ConnectionState() handshake.ConnectionState { 439 return handshake.ConnectionState{} 440 } 441 442 func (s *stubCryptoSetup) GetInitialOpener() (handshake.LongHeaderOpener, error) { 443 return s.initialOpener, nil 444 } 445 446 func (s *stubCryptoSetup) GetHandshakeOpener() (handshake.LongHeaderOpener, error) { 447 return nil, notSupported 448 } 449 450 func (s *stubCryptoSetup) Get0RTTOpener() (handshake.LongHeaderOpener, error) { 451 return nil, notSupported 452 } 453 454 func (s *stubCryptoSetup) Get1RTTOpener() (handshake.ShortHeaderOpener, error) { 455 return nil, notSupported 456 } 457 458 func (s *stubCryptoSetup) GetInitialSealer() (handshake.LongHeaderSealer, error) { 459 return nil, notSupported 460 } 461 462 func (s *stubCryptoSetup) GetHandshakeSealer() (handshake.LongHeaderSealer, error) { 463 return nil, notSupported 464 } 465 466 func (s *stubCryptoSetup) Get0RTTSealer() (handshake.LongHeaderSealer, error) { 467 return nil, notSupported 468 } 469 470 func (s *stubCryptoSetup) Get1RTTSealer() (handshake.ShortHeaderSealer, error) { 471 return nil, notSupported 472 } 473 474 // [Psiphon] 475 // verifyClientHelloRandom unpacks an Initial packet, extracts the CRYPTO 476 // frame, and calls Config.VerifyClientHelloRandom. 477 func (s *baseServer) verifyClientHelloRandom(p *receivedPacket, hdr *wire.Header) error { 478 479 _, initialOpener := handshake.NewInitialAEAD( 480 hdr.DestConnectionID, protocol.PerspectiveServer, protocol.Version1) 481 482 cs := &stubCryptoSetup{ 483 initialOpener: initialOpener, 484 } 485 486 // Make a copy of the packet data since this unpacking modifies it and the 487 // original packet data must be retained for subsequent processing. 488 data := append([]byte(nil), p.data...) 489 490 unpacker := newPacketUnpacker(cs, protocol.Version1) 491 unpacked, err := unpacker.Unpack(hdr, p.rcvTime, data) 492 if err != nil { 493 return fmt.Errorf("verifyClientHelloRandom: Unpack: %w", err) 494 } 495 496 parser := wire.NewFrameParser(s.config.EnableDatagrams, protocol.Version1) 497 498 r := bytes.NewReader(unpacked.data) 499 for { 500 frame, err := parser.ParseNext(r, protocol.EncryptionInitial) 501 if err != nil { 502 return fmt.Errorf("verifyClientHelloRandom: ParseNext: %w", err) 503 } 504 if frame == nil { 505 return errors.New("verifyClientHelloRandom: missing CRYPTO frame") 506 } 507 cryptoFrame, ok := frame.(*wire.CryptoFrame) 508 if !ok { 509 continue 510 } 511 if cryptoFrame.Offset != 0 { 512 return errors.New("verifyClientHelloRandom: unexpected CRYPTO frame offset") 513 } 514 random, err := qtls.ReadClientHelloRandom(cryptoFrame.Data) 515 if err != nil { 516 return fmt.Errorf("verifyClientHelloRandom: ReadClientHelloRandom: %w", err) 517 } 518 if !s.config.VerifyClientHelloRandom(p.remoteAddr, random) { 519 return fmt.Errorf("verifyClientHelloRandom: VerifyClientHelloRandom failed") 520 } 521 break 522 } 523 524 return nil 525 } 526 527 func (s *baseServer) handleInitialImpl(p *receivedPacket, hdr *wire.Header) error { 528 if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { 529 p.buffer.Release() 530 if s.config.Tracer != nil { 531 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) 532 } 533 return errors.New("too short connection ID") 534 } 535 536 // [Psiphon] 537 // Drop any Initial packet that fails verifyClientHelloRandom. 538 if s.config.VerifyClientHelloRandom != nil { 539 err := s.verifyClientHelloRandom(p, hdr) 540 if err != nil { 541 p.buffer.Release() 542 return err 543 } 544 } 545 546 var ( 547 token *Token 548 retrySrcConnID *protocol.ConnectionID 549 ) 550 origDestConnID := hdr.DestConnectionID 551 if len(hdr.Token) > 0 { 552 c, err := s.tokenGenerator.DecodeToken(hdr.Token) 553 if err == nil { 554 token = &Token{ 555 IsRetryToken: c.IsRetryToken, 556 RemoteAddr: c.RemoteAddr, 557 SentTime: c.SentTime, 558 } 559 if token.IsRetryToken { 560 origDestConnID = c.OriginalDestConnectionID 561 retrySrcConnID = &c.RetrySrcConnectionID 562 } 563 } 564 } 565 if !s.config.AcceptToken(p.remoteAddr, token) { 566 go func() { 567 defer p.buffer.Release() 568 if token != nil && token.IsRetryToken { 569 if err := s.maybeSendInvalidToken(p, hdr); err != nil { 570 s.logger.Debugf("Error sending INVALID_TOKEN error: %s", err) 571 } 572 return 573 } 574 if err := s.sendRetry(p.remoteAddr, hdr, p.info); err != nil { 575 s.logger.Debugf("Error sending Retry: %s", err) 576 } 577 }() 578 return nil 579 } 580 581 if queueLen := atomic.LoadInt32(&s.sessionQueueLen); queueLen >= protocol.MaxAcceptQueueSize { 582 s.logger.Debugf("Rejecting new connection. Server currently busy. Accept queue length: %d (max %d)", queueLen, protocol.MaxAcceptQueueSize) 583 go func() { 584 defer p.buffer.Release() 585 if err := s.sendConnectionRefused(p.remoteAddr, hdr, p.info); err != nil { 586 s.logger.Debugf("Error rejecting connection: %s", err) 587 } 588 }() 589 return nil 590 } 591 592 connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) 593 if err != nil { 594 return err 595 } 596 s.logger.Debugf("Changing connection ID to %s.", connID) 597 var sess quicSession 598 tracingID := nextSessionTracingID() 599 if added := s.sessionHandler.AddWithConnID(hdr.DestConnectionID, connID, func() packetHandler { 600 var tracer logging.ConnectionTracer 601 if s.config.Tracer != nil { 602 // Use the same connection ID that is passed to the client's GetLogWriter callback. 603 connID := hdr.DestConnectionID 604 if origDestConnID.Len() > 0 { 605 connID = origDestConnID 606 } 607 tracer = s.config.Tracer.TracerForConnection( 608 context.WithValue(context.Background(), SessionTracingKey, tracingID), 609 protocol.PerspectiveServer, 610 connID, 611 ) 612 } 613 sess = s.newSession( 614 newSendConn(s.conn, p.remoteAddr, p.info), 615 s.sessionHandler, 616 origDestConnID, 617 retrySrcConnID, 618 hdr.DestConnectionID, 619 hdr.SrcConnectionID, 620 connID, 621 s.sessionHandler.GetStatelessResetToken(connID), 622 s.config, 623 s.tlsConf, 624 s.tokenGenerator, 625 s.acceptEarlySessions, 626 tracer, 627 tracingID, 628 s.logger, 629 hdr.Version, 630 ) 631 sess.handlePacket(p) 632 return sess 633 }); !added { 634 return nil 635 } 636 go sess.run() 637 go s.handleNewSession(sess) 638 if sess == nil { 639 p.buffer.Release() 640 return nil 641 } 642 return nil 643 } 644 645 func (s *baseServer) handleNewSession(sess quicSession) { 646 sessCtx := sess.Context() 647 if s.acceptEarlySessions { 648 // wait until the early session is ready (or the handshake fails) 649 select { 650 case <-sess.earlySessionReady(): 651 case <-sessCtx.Done(): 652 return 653 } 654 } else { 655 // wait until the handshake is complete (or fails) 656 select { 657 case <-sess.HandshakeComplete().Done(): 658 case <-sessCtx.Done(): 659 return 660 } 661 } 662 663 atomic.AddInt32(&s.sessionQueueLen, 1) 664 select { 665 case s.sessionQueue <- sess: 666 // blocks until the session is accepted 667 case <-sessCtx.Done(): 668 atomic.AddInt32(&s.sessionQueueLen, -1) 669 // don't pass sessions that were already closed to Accept() 670 } 671 } 672 673 func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info *packetInfo) error { 674 // Log the Initial packet now. 675 // If no Retry is sent, the packet will be logged by the session. 676 (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) 677 srcConnID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) 678 if err != nil { 679 return err 680 } 681 token, err := s.tokenGenerator.NewRetryToken(remoteAddr, hdr.DestConnectionID, srcConnID) 682 if err != nil { 683 return err 684 } 685 replyHdr := &wire.ExtendedHeader{} 686 replyHdr.IsLongHeader = true 687 replyHdr.Type = protocol.PacketTypeRetry 688 replyHdr.Version = hdr.Version 689 replyHdr.SrcConnectionID = srcConnID 690 replyHdr.DestConnectionID = hdr.SrcConnectionID 691 replyHdr.Token = token 692 if s.logger.Debug() { 693 s.logger.Debugf("Changing connection ID to %s.", srcConnID) 694 s.logger.Debugf("-> Sending Retry") 695 replyHdr.Log(s.logger) 696 } 697 698 packetBuffer := getPacketBuffer() 699 defer packetBuffer.Release() 700 buf := bytes.NewBuffer(packetBuffer.Data) 701 if err := replyHdr.Write(buf, hdr.Version); err != nil { 702 return err 703 } 704 // append the Retry integrity tag 705 tag := handshake.GetRetryIntegrityTag(buf.Bytes(), hdr.DestConnectionID, hdr.Version) 706 buf.Write(tag[:]) 707 if s.config.Tracer != nil { 708 s.config.Tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(buf.Len()), nil) 709 } 710 _, err = s.conn.WritePacket(buf.Bytes(), remoteAddr, info.OOB()) 711 return err 712 } 713 714 func (s *baseServer) maybeSendInvalidToken(p *receivedPacket, hdr *wire.Header) error { 715 // Only send INVALID_TOKEN if we can unprotect the packet. 716 // This makes sure that we won't send it for packets that were corrupted. 717 sealer, opener := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer, hdr.Version) 718 data := p.data[:hdr.ParsedLen()+hdr.Length] 719 extHdr, err := unpackHeader(opener, hdr, data, hdr.Version) 720 if err != nil { 721 if s.config.Tracer != nil { 722 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropHeaderParseError) 723 } 724 // don't return the error here. Just drop the packet. 725 return nil 726 } 727 hdrLen := extHdr.ParsedLen() 728 if _, err := opener.Open(data[hdrLen:hdrLen], data[hdrLen:], extHdr.PacketNumber, data[:hdrLen]); err != nil { 729 // don't return the error here. Just drop the packet. 730 if s.config.Tracer != nil { 731 s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropPayloadDecryptError) 732 } 733 return nil 734 } 735 if s.logger.Debug() { 736 s.logger.Debugf("Client sent an invalid retry token. Sending INVALID_TOKEN to %s.", p.remoteAddr) 737 } 738 return s.sendError(p.remoteAddr, hdr, sealer, qerr.InvalidToken, p.info) 739 } 740 741 func (s *baseServer) sendConnectionRefused(remoteAddr net.Addr, hdr *wire.Header, info *packetInfo) error { 742 sealer, _ := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer, hdr.Version) 743 return s.sendError(remoteAddr, hdr, sealer, qerr.ConnectionRefused, info) 744 } 745 746 // sendError sends the error as a response to the packet received with header hdr 747 func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer handshake.LongHeaderSealer, errorCode qerr.TransportErrorCode, info *packetInfo) error { 748 packetBuffer := getPacketBuffer() 749 defer packetBuffer.Release() 750 buf := bytes.NewBuffer(packetBuffer.Data) 751 752 ccf := &wire.ConnectionCloseFrame{ErrorCode: uint64(errorCode)} 753 754 replyHdr := &wire.ExtendedHeader{} 755 replyHdr.IsLongHeader = true 756 replyHdr.Type = protocol.PacketTypeInitial 757 replyHdr.Version = hdr.Version 758 replyHdr.SrcConnectionID = hdr.DestConnectionID 759 replyHdr.DestConnectionID = hdr.SrcConnectionID 760 replyHdr.PacketNumberLen = protocol.PacketNumberLen4 761 replyHdr.Length = 4 /* packet number len */ + ccf.Length(hdr.Version) + protocol.ByteCount(sealer.Overhead()) 762 if err := replyHdr.Write(buf, hdr.Version); err != nil { 763 return err 764 } 765 payloadOffset := buf.Len() 766 767 if err := ccf.Write(buf, hdr.Version); err != nil { 768 return err 769 } 770 771 raw := buf.Bytes() 772 _ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], replyHdr.PacketNumber, raw[:payloadOffset]) 773 raw = raw[0 : buf.Len()+sealer.Overhead()] 774 775 pnOffset := payloadOffset - int(replyHdr.PacketNumberLen) 776 sealer.EncryptHeader( 777 raw[pnOffset+4:pnOffset+4+16], 778 &raw[0], 779 raw[pnOffset:payloadOffset], 780 ) 781 782 replyHdr.Log(s.logger) 783 wire.LogFrame(s.logger, ccf, true) 784 if s.config.Tracer != nil { 785 s.config.Tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(raw)), []logging.Frame{ccf}) 786 } 787 _, err := s.conn.WritePacket(raw, remoteAddr, info.OOB()) 788 return err 789 } 790 791 func (s *baseServer) sendVersionNegotiationPacket(p *receivedPacket, hdr *wire.Header) { 792 s.logger.Debugf("Client offered version %s, sending Version Negotiation", hdr.Version) 793 data, err := wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.config.Versions) 794 if err != nil { 795 s.logger.Debugf("Error composing Version Negotiation: %s", err) 796 return 797 } 798 if s.config.Tracer != nil { 799 s.config.Tracer.SentPacket( 800 p.remoteAddr, 801 &wire.Header{ 802 IsLongHeader: true, 803 DestConnectionID: hdr.SrcConnectionID, 804 SrcConnectionID: hdr.DestConnectionID, 805 }, 806 protocol.ByteCount(len(data)), 807 nil, 808 ) 809 } 810 if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil { 811 s.logger.Debugf("Error sending Version Negotiation: %s", err) 812 } 813 }