void AsyncSSLSocket::sslConn(
    HandshakeCB* callback,
    std::chrono::milliseconds timeout,
    const SSLContext::SSLVerifyPeerEnum& verifyPeer) {
  DestructorGuard dg(this);
  eventBase_->dcheckIsInEventBaseThread();

  // Cache local and remote socket addresses to keep them available
  // after socket file descriptor is closed.
  if (cacheAddrOnFailure_) {
    cacheAddresses();
  }

  verifyPeer_ = verifyPeer;

  // Make sure we're in the uninitialized state
  if (server_ ||
      (sslState_ != STATE_UNINIT && sslState_ != STATE_UNENCRYPTED) ||
      handshakeCallback_ != nullptr) {
    return invalidState(callback);
  }

  sslState_ = STATE_CONNECTING;
  handshakeCallback_ = callback;

  try {
    ssl_.reset(ctx_->createSSL());
  } catch (std::exception& e) {
    sslState_ = STATE_ERROR;
    static const Indestructible<AsyncSocketException> ex(
        AsyncSocketException::INTERNAL_ERROR,
        "error calling SSLContext::createSSL()");
    LOG(ERROR) << "AsyncSSLSocket::sslConn(this=" << this << ", fd=" << fd_
               << "): " << e.what();
    return failHandshake(__func__, *ex);
  }

  if (!setupSSLBio()) {
    sslState_ = STATE_ERROR;
    static const Indestructible<AsyncSocketException> ex(
        AsyncSocketException::INTERNAL_ERROR, "error creating SSL bio");
    return failHandshake(__func__, *ex);
  }

  applyVerificationOptions(ssl_);

  if (sslSession_ != nullptr) {
    sessionResumptionAttempted_ = true;
    SSL_set_session(ssl_.get(), sslSession_);
    SSL_SESSION_free(sslSession_);
    sslSession_ = nullptr;
  }
#if FOLLY_OPENSSL_HAS_SNI
  if (tlsextHostname_.size()) {
    SSL_set_tlsext_host_name(ssl_.get(), tlsextHostname_.c_str());
  }
#endif

  SSL_set_ex_data(ssl_.get(), getSSLExDataIndex(), this);

  handshakeConnectTimeout_ = timeout;
  startSSLConnect();
}
void AsyncSSLSocket::sslConn(
    HandshakeCB* callback,
    std::chrono::milliseconds timeout,
    const SSLContext::SSLVerifyPeerEnum& verifyPeer) {
  DestructorGuard dg(this);
  eventBase_->dcheckIsInEventBaseThread();

   
   
  if (cacheAddrOnFailure_) {
    cacheAddresses();
  }

  verifyPeer_ = verifyPeer;

   
  if (server_ ||
      (sslState_ != STATE_UNINIT && sslState_ != STATE_UNENCRYPTED) ||
      handshakeCallback_ != nullptr) {
    return invalidState(callback);
  }

  sslState_ = STATE_CONNECTING;
  handshakeCallback_ = callback;

  try {
    ssl_.reset(ctx_->createSSL());
  } catch (std::exception& e) {
    sslState_ = STATE_ERROR;
    static const Indestructible<AsyncSocketException> ex(
        AsyncSocketException::INTERNAL_ERROR,
        "error calling SSLContext::createSSL()");
    LOG(ERROR) << "AsyncSSLSocket::sslConn(this=" << this << ", fd=" << fd_
               << "): " << e.what();
    return failHandshake(__func__, *ex);
  }

  if (!setupSSLBio()) {
    sslState_ = STATE_ERROR;
    static const Indestructible<AsyncSocketException> ex(
        AsyncSocketException::INTERNAL_ERROR, "error creating SSL bio");
    return failHandshake(__func__, *ex);
  }

  applyVerificationOptions(ssl_);

  if (sslSession_ != nullptr) {
    sessionResumptionAttempted_ = true;
    SSL_set_session(ssl_.get(), sslSession_);
    SSL_SESSION_free(sslSession_);
    sslSession_ = nullptr;
  }
#if FOLLY_OPENSSL_HAS_SNI
  if (tlsextHostname_.size()) {
    SSL_set_tlsext_host_name(ssl_.get(), tlsextHostname_.c_str());
  }
#endif

  SSL_set_ex_data(ssl_.get(), getSSLExDataIndex(), this);

  handshakeConnectTimeout_ = timeout;
  startSSLConnect();
}