|
18 | 18 | #include <cstdio> |
19 | 19 | #include <mutex> |
20 | 20 | #include <thread> |
| 21 | +#include <vector> |
21 | 22 |
|
22 | 23 | #include <folly/Memory.h> |
| 24 | +#include <folly/SharedMutex.h> |
23 | 25 | #include <folly/String.h> |
24 | 26 | #include <folly/io/async/AsyncServerSocket.h> |
25 | 27 | #include <folly/io/async/EventBase.h> |
26 | 28 | #include <folly/io/async/SSLContext.h> |
27 | 29 | #include <folly/io/async/ScopedEventBaseThread.h> |
| 30 | +#include <wangle/ssl/TLSCredProcessor.h> |
| 31 | +#include <wangle/ssl/TLSTicketKeySeeds.h> |
28 | 32 |
|
29 | 33 | #include "mcrouter/lib/network/AsyncMcServerWorker.h" |
30 | 34 | #include "mcrouter/lib/network/ThreadLocalSSLContextProvider.h" |
@@ -168,9 +172,14 @@ class McServerThread { |
168 | 172 | int fd, |
169 | 173 | const folly::SocketAddress& clientAddr) noexcept override final { |
170 | 174 | if (secure_) { |
171 | | - auto& opts = mcServerThread_->server_.opts_; |
172 | | - auto sslCtx = |
173 | | - getSSLContext(opts.pemCertPath, opts.pemKeyPath, opts.pemCaPath); |
| 175 | + const auto& server = mcServerThread_->server_; |
| 176 | + auto& opts = server.opts_; |
| 177 | + auto sslCtx = getSSLContext( |
| 178 | + opts.pemCertPath, |
| 179 | + opts.pemKeyPath, |
| 180 | + opts.pemCaPath, |
| 181 | + server.getTicketKeySeeds()); |
| 182 | + |
174 | 183 | if (sslCtx) { |
175 | 184 | sslCtx->setVerificationOption( |
176 | 185 | folly::SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT); |
@@ -346,6 +355,14 @@ AsyncMcServer::AsyncMcServer(Options opts) : opts_(std::move(opts)) { |
346 | 355 | } |
347 | 356 | } |
348 | 357 |
|
| 358 | + if (!opts_.tlsTicketKeySeedPath.empty()) { |
| 359 | + if (auto initialSeeds = wangle::TLSCredProcessor::processTLSTickets( |
| 360 | + opts_.tlsTicketKeySeedPath)) { |
| 361 | + tlsTicketKeySeeds_ = std::move(*initialSeeds); |
| 362 | + } |
| 363 | + startPollingTicketKeySeeds(); |
| 364 | + } |
| 365 | + |
349 | 366 | if (opts_.numThreads == 0) { |
350 | 367 | throw std::invalid_argument(folly::sformat( |
351 | 368 | "Unexpected option: opts_.numThreads={}", opts_.numThreads)); |
@@ -466,5 +483,27 @@ void AsyncMcServer::join() { |
466 | 483 | thread->join(); |
467 | 484 | } |
468 | 485 | } |
| 486 | + |
| 487 | +void AsyncMcServer::setTicketKeySeeds(wangle::TLSTicketKeySeeds seeds) { |
| 488 | + folly::SharedMutex::WriteHolder writeGuard(tlsTicketKeySeedsLock_); |
| 489 | + tlsTicketKeySeeds_ = std::move(seeds); |
| 490 | +} |
| 491 | + |
| 492 | +wangle::TLSTicketKeySeeds AsyncMcServer::getTicketKeySeeds() const { |
| 493 | + folly::SharedMutex::ReadHolder readGuard(tlsTicketKeySeedsLock_); |
| 494 | + return tlsTicketKeySeeds_; |
469 | 495 | } |
470 | | -} // facebook::memcache |
| 496 | + |
| 497 | +void AsyncMcServer::startPollingTicketKeySeeds() { |
| 498 | + // Caller assumed to have checked opts_.tlsTicketKeySeedPath is non-empty |
| 499 | + ticketKeySeedPoller_ = folly::make_unique<wangle::TLSCredProcessor>( |
| 500 | + opts_.tlsTicketKeySeedPath, opts_.pemCertPath); |
| 501 | + ticketKeySeedPoller_->addTicketCallback( |
| 502 | + [this](wangle::TLSTicketKeySeeds updatedSeeds) { |
| 503 | + setTicketKeySeeds(std::move(updatedSeeds)); |
| 504 | + VLOG(0) << "Updated TLSTicketKeySeeds"; |
| 505 | + }); |
| 506 | +} |
| 507 | + |
| 508 | +} // memcache |
| 509 | +} // facebook |
0 commit comments