nghttpx: Fix crash when reusing cached SSL session

This commit is contained in:
Tatsuhiro Tsujikawa 2016-02-07 17:27:05 +09:00
parent b3e5d49a3e
commit 5c10534b88
2 changed files with 10 additions and 13 deletions

View File

@ -73,6 +73,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
dconn_pool_(get_config()->conn.downstream.addr_groups.size()), dconn_pool_(get_config()->conn.downstream.addr_groups.size()),
worker_stat_(get_config()->conn.downstream.addr_groups.size()), worker_stat_(get_config()->conn.downstream.addr_groups.size()),
dgrps_(get_config()->conn.downstream.addr_groups.size()), dgrps_(get_config()->conn.downstream.addr_groups.size()),
cl_tls_session_cache_size_(0),
loop_(loop), loop_(loop),
sv_ssl_ctx_(sv_ssl_ctx), sv_ssl_ctx_(sv_ssl_ctx),
cl_ssl_ctx_(cl_ssl_ctx), cl_ssl_ctx_(cl_ssl_ctx),
@ -315,10 +316,11 @@ void Worker::cache_cl_tls_session(const DownstreamAddr *addr,
return; return;
} }
if (cl_tls_session_order_.size() >= max) { if (cl_tls_session_cache_size_ >= max) {
auto addrkey = cl_tls_session_order_.front(); // It is implementation dependent which item is returned from
cl_tls_session_order_.pop_front(); // std::begin(). Probably, this depends on hash algorithm. If it
auto it = cl_tls_session_cache_.find(addrkey); // is random fashion, then we are mostly OK.
auto it = std::begin(cl_tls_session_cache_);
assert(it != std::end(cl_tls_session_cache_)); assert(it != std::end(cl_tls_session_cache_));
auto &v = (*it).second; auto &v = (*it).second;
assert(!v.empty()); assert(!v.empty());
@ -330,13 +332,13 @@ void Worker::cache_cl_tls_session(const DownstreamAddr *addr,
} }
} }
cl_tls_session_order_.push_back(addr);
auto it = cl_tls_session_cache_.find(addr); auto it = cl_tls_session_cache_.find(addr);
if (it == std::end(cl_tls_session_cache_)) { if (it == std::end(cl_tls_session_cache_)) {
std::tie(it, std::ignore) = std::tie(it, std::ignore) =
cl_tls_session_cache_.emplace(addr, std::deque<SSL_SESSION *>()); cl_tls_session_cache_.emplace(addr, std::deque<SSL_SESSION *>());
} }
(*it).second.push_back(session); (*it).second.push_back(session);
++cl_tls_session_cache_size_;
} }
SSL_SESSION *Worker::reuse_cl_tls_session(const DownstreamAddr *addr) { SSL_SESSION *Worker::reuse_cl_tls_session(const DownstreamAddr *addr) {
@ -345,16 +347,15 @@ SSL_SESSION *Worker::reuse_cl_tls_session(const DownstreamAddr *addr) {
return nullptr; return nullptr;
} }
assert((*it).first == cl_tls_session_order_.back());
auto &v = (*it).second; auto &v = (*it).second;
assert(!v.empty()); assert(!v.empty());
auto session = v.back(); auto session = v.back();
v.pop_back(); v.pop_back();
--cl_tls_session_cache_size_;
if (v.empty()) { if (v.empty()) {
cl_tls_session_cache_.erase(it); cl_tls_session_cache_.erase(it);
} }
cl_tls_session_order_.pop_back();
return session; return session;
} }

View File

@ -176,11 +176,7 @@ private:
// which sits at the front of deque is removed. // which sits at the front of deque is removed.
std::unordered_map<const DownstreamAddr *, std::deque<SSL_SESSION *>> std::unordered_map<const DownstreamAddr *, std::deque<SSL_SESSION *>>
cl_tls_session_cache_; cl_tls_session_cache_;
// This is the order of address added to cl_tls_session_cache_ in size_t cl_tls_session_cache_size_;
// order to evict oldest entry first. The invariant is the sum of
// SSL_SESSION in cl_tls_session_cache_ ==
// cl_tls_session_order_.size().
std::deque<const DownstreamAddr *> cl_tls_session_order_;
std::unique_ptr<MemcachedDispatcher> session_cache_memcached_dispatcher_; std::unique_ptr<MemcachedDispatcher> session_cache_memcached_dispatcher_;
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY