[nginx] SSL: object cache inheritance from the old configuration cycle.
noreply at nginx.com
noreply at nginx.com
Fri Jan 17 00:38:02 UTC 2025
details: https://github.com/nginx/nginx/commit/8311e14ae614529aabe9e72e87051d191b723fb4
branches: master
commit: 8311e14ae614529aabe9e72e87051d191b723fb4
user: Sergey Kandaurov <pluknet at nginx.com>
date: Wed, 18 Dec 2024 20:03:35 +0400
description:
SSL: object cache inheritance from the old configuration cycle.
Memory based objects are always inherited, engine based objects are
never inherited to adhere the volatile nature of engines, file based
objects are inherited subject to modification time and file index.
The previous behaviour to bypass cache from the old configuration cycle
is preserved with a new directive "ssl_object_cache_inheritable off;".
---
src/event/ngx_event_openssl_cache.c | 107 +++++++++++++++++++++++++++++++++---
1 file changed, 99 insertions(+), 8 deletions(-)
diff --git a/src/event/ngx_event_openssl_cache.c b/src/event/ngx_event_openssl_cache.c
index 8829e2879..9d1962759 100644
--- a/src/event/ngx_event_openssl_cache.c
+++ b/src/event/ngx_event_openssl_cache.c
@@ -14,6 +14,14 @@
#define NGX_SSL_CACHE_ENGINE 2
+#define ngx_ssl_cache_get_conf(cycle) \
+ (ngx_ssl_cache_t *) ngx_get_conf(cycle->conf_ctx, ngx_openssl_cache_module)
+
+#define ngx_ssl_cache_get_old_conf(cycle) \
+ cycle->old_cycle->conf_ctx ? ngx_ssl_cache_get_conf(cycle->old_cycle) \
+ : NULL
+
+
typedef struct {
unsigned type:2;
unsigned len:30;
@@ -39,12 +47,17 @@ typedef struct {
ngx_ssl_cache_key_t id;
ngx_ssl_cache_type_t *type;
void *value;
+
+ time_t mtime;
+ ngx_file_uniq_t uniq;
} ngx_ssl_cache_node_t;
typedef struct {
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
+
+ ngx_flag_t inheritable;
} ngx_ssl_cache_t;
@@ -76,22 +89,36 @@ static void *ngx_ssl_cache_ca_create(ngx_ssl_cache_key_t *id, char **err,
static BIO *ngx_ssl_cache_create_bio(ngx_ssl_cache_key_t *id, char **err);
static void *ngx_openssl_cache_create_conf(ngx_cycle_t *cycle);
+static char *ngx_openssl_cache_init_conf(ngx_cycle_t *cycle, void *conf);
static void ngx_ssl_cache_cleanup(void *data);
static void ngx_ssl_cache_node_insert(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
+static ngx_command_t ngx_openssl_cache_commands[] = {
+
+ { ngx_string("ssl_object_cache_inheritable"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ 0,
+ offsetof(ngx_ssl_cache_t, inheritable),
+ NULL },
+
+ ngx_null_command
+};
+
+
static ngx_core_module_t ngx_openssl_cache_module_ctx = {
ngx_string("openssl_cache"),
ngx_openssl_cache_create_conf,
- NULL
+ ngx_openssl_cache_init_conf
};
ngx_module_t ngx_openssl_cache_module = {
NGX_MODULE_V1,
&ngx_openssl_cache_module_ctx, /* module context */
- NULL, /* module directives */
+ ngx_openssl_cache_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
@@ -132,8 +159,13 @@ void *
ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
ngx_str_t *path, void *data)
{
+ void *value;
+ time_t mtime;
uint32_t hash;
- ngx_ssl_cache_t *cache;
+ ngx_int_t rc;
+ ngx_file_uniq_t uniq;
+ ngx_file_info_t fi;
+ ngx_ssl_cache_t *cache, *old_cache;
ngx_ssl_cache_key_t id;
ngx_ssl_cache_type_t *type;
ngx_ssl_cache_node_t *cn;
@@ -151,12 +183,60 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
hash = ngx_murmur_hash2(id.data, id.len);
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
+
if (cn != NULL) {
return type->ref(err, cn->value);
}
+ value = NULL;
+
+ if (id.type == NGX_SSL_CACHE_PATH
+ && (rc = ngx_file_info(id.data, &fi)) != NGX_FILE_ERROR)
+ {
+ mtime = ngx_file_mtime(&fi);
+ uniq = ngx_file_uniq(&fi);
+
+ } else {
+ rc = NGX_FILE_ERROR;
+ mtime = 0;
+ uniq = 0;
+ }
+
+ /* try to use a reference from the old cycle */
+
+ old_cache = ngx_ssl_cache_get_old_conf(cf->cycle);
+
+ if (old_cache && old_cache->inheritable) {
+ cn = ngx_ssl_cache_lookup(old_cache, type, &id, hash);
+
+ if (cn != NULL) {
+ switch (id.type) {
+
+ case NGX_SSL_CACHE_DATA:
+ value = type->ref(err, cn->value);
+ break;
+
+ default:
+ if (rc != NGX_FILE_ERROR
+ && uniq == cn->uniq && mtime == cn->mtime)
+ {
+ value = type->ref(err, cn->value);
+ }
+ break;
+ }
+ }
+ }
+
+ if (value == NULL) {
+ value = type->create(&id, err, data);
+ if (value == NULL) {
+ return NULL;
+ }
+ }
+
cn = ngx_palloc(cf->pool, sizeof(ngx_ssl_cache_node_t) + id.len + 1);
if (cn == NULL) {
+ type->free(value);
return NULL;
}
@@ -165,14 +245,12 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
cn->id.len = id.len;
cn->id.type = id.type;
cn->type = type;
+ cn->value = value;
+ cn->mtime = mtime;
+ cn->uniq = uniq;
ngx_cpystrn(cn->id.data, id.data, id.len + 1);
- cn->value = type->create(&id, err, data);
- if (cn->value == NULL) {
- return NULL;
- }
-
ngx_rbtree_insert(&cache->rbtree, &cn->node);
return type->ref(err, cn->value);
@@ -729,6 +807,8 @@ ngx_openssl_cache_create_conf(ngx_cycle_t *cycle)
return NULL;
}
+ cache->inheritable = NGX_CONF_UNSET;
+
cln = ngx_pool_cleanup_add(cycle->pool, 0);
if (cln == NULL) {
return NULL;
@@ -744,6 +824,17 @@ ngx_openssl_cache_create_conf(ngx_cycle_t *cycle)
}
+static char *
+ngx_openssl_cache_init_conf(ngx_cycle_t *cycle, void *conf)
+{
+ ngx_ssl_cache_t *cache = conf;
+
+ ngx_conf_init_value(cache->inheritable, 1);
+
+ return NGX_CONF_OK;
+}
+
+
static void
ngx_ssl_cache_cleanup(void *data)
{
More information about the nginx-devel
mailing list