Skip to content
Snippets Groups Projects
Commit c0a30ae2 authored by Francesco Giacomini's avatar Francesco Giacomini
Browse files

tentative fix issue #15

parent d20fa5f2
No related branches found
No related tags found
1 merge request!10cache and clean the VOMS AC only once per connection
This commit is part of merge request !10. Comments created here will be created in the context of that merge request.
......@@ -22,6 +22,7 @@ extern "C" {
#include <cassert>
#include <chrono>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <string>
......@@ -63,8 +64,6 @@ ngx_module_t ngx_http_voms_module = {
NGX_MODULE_V1_PADDING //
};
static std::unique_ptr<vomsdata> vomsdata_ptr;
static ngx_int_t generic_getter( //
ngx_http_request_t* r,
ngx_http_variable_value_t* v,
......@@ -344,52 +343,62 @@ static MaybeVomsAc retrieve_voms_ac_from_proxy(ngx_http_request_t* r)
return boost::none;
}
if (!vomsdata_ptr) {
vomsdata_ptr.reset(new vomsdata);
}
auto ok =
vomsdata_ptr->Retrieve(client_cert.get(), client_chain, RECURSE_CHAIN);
vomsdata vd;
auto ok = vd.Retrieve(client_cert.get(), client_chain, RECURSE_CHAIN);
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);
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");
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)
{
auto r = static_cast<ngx_http_request_t*>(data);
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
auto p = static_cast<MaybeVomsAc*>(
ngx_http_get_module_ctx(r, ngx_http_voms_module));
delete p;
auto c = static_cast<ngx_connection_t*>(data);
ngx_log_error(NGX_LOG_DEBUG, c->log, 0, "%s", __func__);
auto n = ac_cache.erase(c);
// we erase from the cache exactly once per connection
assert(n == 1);
}
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);
auto cln = ngx_http_cleanup_add(r, 0);
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
auto c = r->connection;
auto cln = ngx_pool_cleanup_add(c->pool, 0);
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->data = r;
cln->data = c;
} else {
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)
{
return static_cast<MaybeVomsAc*>(
ngx_http_get_module_ctx(r, ngx_http_voms_module));
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
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)
......@@ -399,8 +408,9 @@ static MaybeVomsAc const& get_voms_ac(ngx_http_request_t* r)
MaybeVomsAc* acp = get_voms_ac_from_cache(r);
if (!acp) {
acp = new MaybeVomsAc(retrieve_voms_ac_from_proxy(r));
cache_voms_ac(r, acp);
auto p = std::make_unique<MaybeVomsAc>(retrieve_voms_ac_from_proxy(r));
acp = p.get();
cache_voms_ac(r, std::move(p));
}
return *acp;
......@@ -417,14 +427,14 @@ static ngx_int_t generic_getter(ngx_http_request_t* r,
auto& ac = get_voms_ac(r);
if (!ac) {
if (ac.has_value()) {
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "get_voms_ac() failed");
return NGX_OK;
}
using getter_p = std::string (*)(VomsAc const& voms);
auto getter = reinterpret_cast<getter_p>(data);
std::string const value = getter(*ac);
std::string const value = getter(ac.value());
auto buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, value.size()));
if (!buffer) {
......
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