void ConnectOperation::specializedRunImpl()

in squangle/mysql_client/Operation.cpp [600:682]


void ConnectOperation::specializedRunImpl() {
  if (attempts_made_ == 0) {
    conn()->initialize();
  } else {
    conn()->initMysqlOnly();
  }
  removeClientReference();
  MYSQL* mysql = conn()->mysql();
  if (!mysql) {
    setAsyncClientError("connection initialization failed");
    attemptFailed(OperationResult::Failed);
    return;
  }

  mysql_options(conn()->mysql(), MYSQL_OPT_CONNECT_ATTR_RESET, 0);
  for (const auto& [key, value] : attributes_) {
    mysql_options4(
        conn()->mysql(),
        MYSQL_OPT_CONNECT_ATTR_ADD,
        key.c_str(),
        value.c_str());
  }

  const auto& compression_lib = getCompression();
  if (compression_lib) {
    mysql_options(mysql, MYSQL_OPT_COMPRESS, nullptr);
    setCompressionOption(mysql, *compression_lib);
  }

  auto provider = conn_options_.getSSLOptionsProviderPtr();
  if (provider && provider->setMysqlSSLOptions(mysql)) {
    if (connection_context_) {
      connection_context_->isSslConnection = true;
    }
  }

  // Set sni field for ssl connection
  if (conn_options_.getSniServerName()) {
    mysql_options(
        mysql,
        MYSQL_OPT_TLS_SNI_SERVERNAME,
        (*conn_options_.getSniServerName()).c_str());
  }

  if (conn_options_.getDscp().has_value()) {
    // DS field (QOS/TOS level) is 8 bits with DSCP packed into the most
    // significant 6 bits.
    uint dsf = *conn_options_.getDscp() << 2;
    int ret = mysql_options(mysql, MYSQL_OPT_TOS, &dsf);
    if (ret != 0) {
      LOG(WARNING) << fmt::format(
          "Failed to set DSCP {} for MySQL Client socket",
          *conn_options_.getDscp());
    }
  }

  if (conn_options_.getCertValidationCallback()) {
    MysqlCertValidatorCallback callback = mysqlCertValidator;
    const void* self = this;
    mysql_options(mysql, MYSQL_OPT_TLS_CERT_CALLBACK, &callback);
    mysql_options(mysql, MYSQL_OPT_TLS_CERT_CALLBACK_CONTEXT, &self);
  }

  conn()->socketHandler()->setOperation(this);

  // If the tcp timeout value is not set in conn options, use the default value
  uint timeoutInMs = chrono::duration_cast<chrono::milliseconds>(
                         conn_options_.getConnectTcpTimeout().value_or(Duration(
                             FLAGS_async_mysql_connect_tcp_timeout_micros)))
                         .count();
  // Set the connect timeout in mysql options and also on tcp_timeout_handler if
  // event base is set. Sync implmenation of MysqlClientBase may not have it
  // set. If the timeout is set to 0, skip setting any timeout
  if (timeoutInMs != 0) {
    mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT_MS, &timeoutInMs);
    if (isEventBaseSet()) {
      tcp_timeout_handler_.scheduleTimeout(timeoutInMs);
    }
  }

  // connect is immediately "ready" to do one loop
  socketActionable();
}