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;
}