int fizzServerBenchmarkCommand()

in fizz/tool/FizzServerBenchmarkCommand.cpp [152:270]


int fizzServerBenchmarkCommand(const std::vector<std::string>& args) {
  // configurable parameters and their default values
  uint16_t port = 8443;
  std::string certPath;
  std::string keyPath;
  std::string keyPass;
  int threadNum = 1;
  size_t backlog = 100;
  std::vector<std::vector<CipherSuite>> ciphers{
      {CipherSuite::TLS_AES_128_GCM_SHA256}};
  std::vector<ProtocolVersion> versions{
      ProtocolVersion::tls_1_3, ProtocolVersion::tls_1_3_28};
  bool enableBatch = false;
  size_t batchNumMsgThreshold = 0;
  std::shared_ptr<SynchronizedBatcher<Sha256>> batcher;

  // Argument Handler Map
  // clang-format off
  FizzArgHandlerMap handlers = {
    {"-accept", {true, [&port](const std::string& arg) {
        port = portFromString(arg, true);
    }}},
    {"-cert", {true, [&certPath](const std::string& arg) {
      certPath = arg;
    }}},
    {"-key", {true, [&keyPath](const std::string& arg) {
      keyPath = arg;
    }}},
    {"-pass", {true, [&keyPass](const std::string& arg) {
      keyPass = arg;
    }}},
    {"-threads", {true, [&threadNum](const std::string& arg) {
      threadNum = std::stoi(arg);
    }}},
    {"-backlog", {true, [&backlog](const std::string& arg) {
      backlog = std::stoi(arg);
    }}},
    {"-batch", {true, [&enableBatch, &batchNumMsgThreshold](const std::string& arg) {
      enableBatch = true;
      batchNumMsgThreshold = std::stoi(arg);
    }}}
  };
  // clang-format on

  // parse arguments
  try {
    if (parseArguments(args, handlers, printUsage)) {
      // Parsing failed, return
      return 1;
    }
  } catch (const std::exception& e) {
    LOG(ERROR) << "Error: " << e.what();
    return 1;
  }
  if (certPath.empty() || keyPath.empty()) {
    LOG(ERROR)
        << "-cert and -key are both required for the server benchmark tool";
    return 1;
  }

  // set up the IO Thread Pool and get the EventBase
  EventBase evb; // main thread event base, used for accepting new connections
  auto threadExe = std::make_shared<IOThreadPoolExecutor>(
      threadNum,
      std::make_shared<NamedThreadFactory>("ServerBenchmarkPool"),
      folly::EventBaseManager::get(),
      IOThreadPoolExecutor::Options().setWaitForAll(true));

  // prepare FizzServerContext
  auto serverContext = std::make_shared<FizzServerContext>();
  serverContext->setSupportedCiphers(std::move(ciphers));
  auto ticketCipher = std::make_shared<
      Aead128GCMTicketCipher<TicketCodec<CertificateStorage::X509>>>(
      std::make_shared<OpenSSLFactory>(), std::make_shared<CertManager>());
  auto ticketSeed = RandomGenerator<32>().generateRandom();
  ticketCipher->setTicketSecrets({{range(ticketSeed)}});
  serverContext->setTicketCipher(ticketCipher);
  serverContext->setSupportedVersions(std::move(versions));

  // load Server's certificate and private key
  std::unique_ptr<CertManager> certManager =
      std::make_unique<fizz::extensions::DelegatedCredentialCertManager>();
  std::vector<std::shared_ptr<CertificateCompressor>> compressors;
  {
    std::string certData;
    std::string keyData;
    if (!readFile(certPath.c_str(), certData)) {
      LOG(ERROR) << "Failed to read certificate";
      return 1;
    } else if (!readFile(keyPath.c_str(), keyData)) {
      LOG(ERROR) << "Failed to read private key";
      return 1;
    }
    std::unique_ptr<SelfCert> cert;
    if (!keyPass.empty()) {
      cert = CertUtils::makeSelfCert(certData, keyData, keyPass, compressors);
    } else {
      cert = CertUtils::makeSelfCert(certData, keyData, compressors);
    }
    std::shared_ptr<SelfCert> sharedCert = std::move(cert);
    if (enableBatch) {
      batcher = std::make_shared<SynchronizedBatcher<Sha256>>(
          batchNumMsgThreshold, sharedCert, CertificateVerifyContext::Server);
      auto batchCert =
          std::make_shared<BatchSignatureAsyncSelfCert<Sha256>>(batcher);
      serverContext->setSupportedSigSchemes(batchCert->getSigSchemes());
      certManager->addCert(batchCert, true);
    } else {
      serverContext->setSupportedSigSchemes(sharedCert->getSigSchemes());
      certManager->addCert(sharedCert, true);
    }
  }
  serverContext->setCertManager(std::move(certManager));

  // start to listen to new connections
  FizzServerAcceptor acceptor(port, backlog, &evb, serverContext, threadExe);
  evb.loop();
  return 0;
}