Skip to content
Snippets Groups Projects
Commit dd3141f0 authored by Andrea Ceccanti's avatar Andrea Ceccanti
Browse files

Merge branch 'issue-15' into 'master'

cache and clean the VOMS AC only once per connection

Closes #15

See merge request storm2/ngx_http_voms_module!10
parents 46abca85 a885773c
No related branches found
No related tags found
1 merge request!10cache and clean the VOMS AC only once per connection
Pipeline #13972 passed
...@@ -22,6 +22,7 @@ extern "C" { ...@@ -22,6 +22,7 @@ extern "C" {
#include <cassert> #include <cassert>
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <map>
#include <memory> #include <memory>
#include <numeric> #include <numeric>
#include <string> #include <string>
...@@ -63,8 +64,6 @@ ngx_module_t ngx_http_voms_module = { ...@@ -63,8 +64,6 @@ ngx_module_t ngx_http_voms_module = {
NGX_MODULE_V1_PADDING // NGX_MODULE_V1_PADDING //
}; };
static std::unique_ptr<vomsdata> vomsdata_ptr;
static ngx_int_t generic_getter( // static ngx_int_t generic_getter( //
ngx_http_request_t* r, ngx_http_request_t* r,
ngx_http_variable_value_t* v, ngx_http_variable_value_t* v,
...@@ -344,52 +343,62 @@ static MaybeVomsAc retrieve_voms_ac_from_proxy(ngx_http_request_t* r) ...@@ -344,52 +343,62 @@ static MaybeVomsAc retrieve_voms_ac_from_proxy(ngx_http_request_t* r)
return boost::none; return boost::none;
} }
if (!vomsdata_ptr) { vomsdata vd;
vomsdata_ptr.reset(new vomsdata);
} auto ok = vd.Retrieve(client_cert.get(), client_chain, RECURSE_CHAIN);
auto ok =
vomsdata_ptr->Retrieve(client_cert.get(), client_chain, RECURSE_CHAIN);
if (!ok) { if (!ok) {
auto msg = vomsdata_ptr->ErrorMessage().c_str(); auto msg = vd.ErrorMessage().c_str();
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", msg); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", msg);
return boost::none; return boost::none;
} }
if (vomsdata_ptr->data.empty()) { if (vd.data.empty()) {
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "no ACs in proxy"); ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "no ACs in proxy");
return boost::none; return boost::none;
} }
return vomsdata_ptr->data.front(); return vd.data.front();
} }
// note that an entry in the cache is always created if within a connection a
// request is made to one of the voms_* variables. If the presented
// credential is a normal certificate or a proxy without attribute certificates,
// the unique_ptr points to a MaybeVomsAc that is empty (in the sense of an
// std::optional)
static std::map<ngx_connection_t*, std::unique_ptr<MaybeVomsAc>> ac_cache;
static void clean_voms_ac(void* data) static void clean_voms_ac(void* data)
{ {
auto r = static_cast<ngx_http_request_t*>(data); auto c = static_cast<ngx_connection_t*>(data);
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__); ngx_log_error(NGX_LOG_DEBUG, c->log, 0, "%s", __func__);
auto n = ac_cache.erase(c);
auto p = static_cast<MaybeVomsAc*>( // we erase from the cache exactly once per connection
ngx_http_get_module_ctx(r, ngx_http_voms_module)); assert(n == 1);
delete p;
} }
static void cache_voms_ac(ngx_http_request_t* r, MaybeVomsAc* ac) static void cache_voms_ac(ngx_http_request_t* r,
std::unique_ptr<MaybeVomsAc> acp)
{ {
ngx_http_set_ctx(r, ac, ngx_http_voms_module); ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
auto cln = ngx_http_cleanup_add(r, 0); auto c = r->connection;
auto cln = ngx_pool_cleanup_add(c->pool, 0);
if (cln) { if (cln) {
auto r = ac_cache.insert({c, std::move(acp)});
// we insert into the cache exactly once per connection
assert(r.second);
cln->handler = clean_voms_ac; cln->handler = clean_voms_ac;
cln->data = r; cln->data = c;
} else { } else {
ngx_log_error( ngx_log_error(
NGX_LOG_ERR, r->connection->log, 0, "ngx_http_cleanup_add() failed"); NGX_LOG_ERR, r->connection->log, 0, "ngx_pool_cleanup_add() failed");
} }
} }
static MaybeVomsAc* get_voms_ac_from_cache(ngx_http_request_t* r) static MaybeVomsAc* get_voms_ac_from_cache(ngx_http_request_t* r)
{ {
return static_cast<MaybeVomsAc*>( ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
ngx_http_get_module_ctx(r, ngx_http_voms_module)); auto it = ac_cache.find(r->connection);
return it != ac_cache.end() ? it->second.get() : nullptr;
} }
static MaybeVomsAc const& get_voms_ac(ngx_http_request_t* r) static MaybeVomsAc const& get_voms_ac(ngx_http_request_t* r)
...@@ -399,8 +408,9 @@ static MaybeVomsAc const& get_voms_ac(ngx_http_request_t* r) ...@@ -399,8 +408,9 @@ static MaybeVomsAc const& get_voms_ac(ngx_http_request_t* r)
MaybeVomsAc* acp = get_voms_ac_from_cache(r); MaybeVomsAc* acp = get_voms_ac_from_cache(r);
if (!acp) { if (!acp) {
acp = new MaybeVomsAc(retrieve_voms_ac_from_proxy(r)); auto p = std::make_unique<MaybeVomsAc>(retrieve_voms_ac_from_proxy(r));
cache_voms_ac(r, acp); acp = p.get();
cache_voms_ac(r, std::move(p));
} }
return *acp; return *acp;
......
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:CRYPTO_malloc
fun:SSL_SESSION_new
fun:ssl_get_new_session
fun:ssl23_connect
fun:ngx_ssl_handshake
fun:ngx_http_upstream_ssl_init_connection
fun:ngx_http_upstream_send_request_handler
fun:ngx_http_upstream_handler
fun:ngx_epoll_process_events
fun:ngx_process_events_and_timers
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:ngx_alloc
fun:ngx_set_environment
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Free
fun:free
fun:__libc_freeres
fun:_vgnU_freeres
fun:__run_exit_handlers
fun:exit
fun:ngx_master_process_exit
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Param
epoll_ctl(event)
fun:epoll_ctl
fun:ngx_epoll_test_rdhup
fun:ngx_epoll_init
fun:ngx_event_process_init
fun:ngx_single_process_cycle
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Param
epoll_ctl(event)
fun:epoll_ctl
fun:ngx_epoll_test_rdhup
fun:ngx_epoll_init
fun:ngx_event_process_init
fun:ngx_single_process_cycle
fun:main
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment