From 3b3b36ba1da40b36ecfce8e127471a7c0765e1b3 Mon Sep 17 00:00:00 2001 From: Aleksey Baulin Date: Tue, 21 Jun 2016 00:28:20 +0300 Subject: [PATCH] Implement cache entry invalidation by making it stale. (#501) --- tempesta_fw/cache.c | 22 +++++++--- tempesta_fw/vhost.c | 102 ++++++++++++++++++++++---------------------- tempesta_fw/vhost.h | 1 - 3 files changed, 66 insertions(+), 59 deletions(-) diff --git a/tempesta_fw/cache.c b/tempesta_fw/cache.c index 1c8b26161..22881735c 100644 --- a/tempesta_fw/cache.c +++ b/tempesta_fw/cache.c @@ -43,7 +43,6 @@ /* Flags stored in a Cache Entry. */ #define TFW_CE_MUST_REVAL 0x0001 /* MUST revalidate if stale. */ -#define TFW_CE_INVALID 0x0100 /* * @trec - Database record descriptor; @@ -382,6 +381,9 @@ tfw_cache_entry_is_live(TfwHttpReq *req, TfwCacheEntry *ce) time_t ce_age = tfw_cache_entry_age(ce); time_t ce_lifetime, lt_fresh = UINT_MAX; + if (ce->lifetime <= 0) + return 0; + #define CC_LIFETIME_FRESH (TFW_HTTP_CC_MAX_AGE | TFW_HTTP_CC_MIN_FRESH) if (req->cache_ctl.flags & CC_LIFETIME_FRESH) { time_t lt_max_age = UINT_MAX, lt_min_fresh = UINT_MAX; @@ -1135,9 +1137,10 @@ cache_req_process_node(TfwHttpReq *req, unsigned long key, /* * Invalidate a cache entry. + * In fact, this is implemented by making the cache entry stale. */ static int -tfw_cache_purge_set_expired(TfwHttpReq *req, unsigned long key) +tfw_cache_purge_invalidate(TfwHttpReq *req, unsigned long key) { TdbIter iter; TDB *db = node_db(); @@ -1145,9 +1148,7 @@ tfw_cache_purge_set_expired(TfwHttpReq *req, unsigned long key) if (!(ce = tfw_cache_dbce_get(db, &iter, req, key))) return -ENOENT; - - /* ce->lifetime = 0; */ - + ce->lifetime = 0; tfw_cache_dbce_put(ce); return 0; } @@ -1170,7 +1171,16 @@ tfw_cache_purge_method(TfwHttpReq *req, unsigned long key) if (!tfw_capuacl_match(vhost, &saddr)) return tfw_http_send_403((TfwHttpMsg *)req); - if (tfw_cache_purge_set_expired(req, key)) + /* Only "invalidate" option is implemented at this time. */ + switch (vhost->cache_purge_mode) { + case TFW_D_CACHE_PURGE_INVALIDATE: + ret = tfw_cache_purge_invalidate(req, key); + break; + default: + return tfw_http_send_403((TfwHttpMsg *)req); + } + + if (ret) return tfw_http_send_404((TfwHttpMsg *)req); else return tfw_http_send_200((TfwHttpMsg *)req); diff --git a/tempesta_fw/vhost.c b/tempesta_fw/vhost.c index 9c0cbf8ec..6ed24d267 100644 --- a/tempesta_fw/vhost.c +++ b/tempesta_fw/vhost.c @@ -559,41 +559,6 @@ tfw_cleanup_locache(TfwCfgSpec *cs) __tfw_cleanup_locache(); } -/* - * Process hdr_via directive. - * Default value is preset statically. - */ -static int -tfw_handle_out_hdr_via(TfwCfgSpec *cs, TfwCfgEntry *ce) -{ - int len; - TfwVhost *vhost = &tfw_vhost_dflt; - - if (ce->attr_n) { - TFW_ERR("%s: Arguments may not have the \'=\' sign\n", - cs->name); - return -EINVAL; - } - if (ce->val_n != 1) { - TFW_ERR("%s: Invalid number of arguments: %d\n", - cs->name, (int)ce->val_n); - return -EINVAL; - } - - /* - * If a value is specified in the configuration file, then - * the default value is not used, even if the processing of - * the specified value results in an error. - */ - len = strlen(ce->vals[0]); - if ((vhost->hdr_via = kmalloc(len + 1, GFP_KERNEL)) == NULL) - return -ENOMEM; - memcpy((void *)vhost->hdr_via, (void *)ce->vals[0], len + 1); - vhost->hdr_via_len = len; - - return 0; -} - /* * Match the ip address against the ACL list. */ @@ -653,20 +618,6 @@ tfw_handle_cache_purge_acl(TfwCfgSpec *cs, TfwCfgEntry *ce) return 0; } -static void -__tfw_cleanup_hdrvia(void) -{ - TfwVhost *vhost = &tfw_vhost_dflt; - if (vhost->hdr_via && (vhost->hdr_via != s_hdr_via_dflt)) - kfree(vhost->hdr_via); -} - -static void -tfw_cleanup_hdrvia(TfwCfgSpec *cs) -{ - __tfw_cleanup_hdrvia(); -} - /* * Process the cache_purge directive. */ @@ -690,8 +641,6 @@ tfw_handle_cache_purge(TfwCfgSpec *cs, TfwCfgEntry *ce) TFW_CFG_ENTRY_FOR_EACH_VAL(ce, i, val) { if (!strcasecmp(val, "invalidate")) { vhost->cache_purge_mode = TFW_D_CACHE_PURGE_INVALIDATE; - } else if (!strcasecmp(val, "delete")) { - vhost->cache_purge_mode = TFW_D_CACHE_PURGE_DELETE; } else { TFW_ERR("%s: unsupported argument: '%s'\n", cs->name, val); @@ -704,6 +653,55 @@ tfw_handle_cache_purge(TfwCfgSpec *cs, TfwCfgEntry *ce) return 0; } +/* + * Process hdr_via directive. + * Default value is preset statically. + */ +static int +tfw_handle_hdr_via(TfwCfgSpec *cs, TfwCfgEntry *ce) +{ + int len; + TfwVhost *vhost = &tfw_vhost_dflt; + + if (ce->attr_n) { + TFW_ERR("%s: Arguments may not have the \'=\' sign\n", + cs->name); + return -EINVAL; + } + if (ce->val_n != 1) { + TFW_ERR("%s: Invalid number of arguments: %d\n", + cs->name, (int)ce->val_n); + return -EINVAL; + } + + /* + * If a value is specified in the configuration file, then + * the default value is not used, even if the processing of + * the specified value results in an error. + */ + len = strlen(ce->vals[0]); + if ((vhost->hdr_via = kmalloc(len + 1, GFP_KERNEL)) == NULL) + return -ENOMEM; + memcpy((void *)vhost->hdr_via, (void *)ce->vals[0], len + 1); + vhost->hdr_via_len = len; + + return 0; +} + +static void +__tfw_cleanup_hdrvia(void) +{ + TfwVhost *vhost = &tfw_vhost_dflt; + if (vhost->hdr_via && (vhost->hdr_via != s_hdr_via_dflt)) + kfree(vhost->hdr_via); +} + +static void +tfw_cleanup_hdrvia(TfwCfgSpec *cs) +{ + __tfw_cleanup_hdrvia(); +} + static int tfw_vhost_cfg_start(void) { @@ -742,7 +740,7 @@ static TfwCfgSpec tfw_location_specs[] = { static TfwCfgSpec tfw_vhost_cfg_specs[] = { { "hdr_via", NULL, - tfw_handle_out_hdr_via, + tfw_handle_hdr_via, .allow_none = true, .allow_repeat = false, .cleanup = tfw_cleanup_hdrvia diff --git a/tempesta_fw/vhost.h b/tempesta_fw/vhost.h index b6f7a4788..da4314881 100644 --- a/tempesta_fw/vhost.h +++ b/tempesta_fw/vhost.h @@ -64,7 +64,6 @@ typedef struct { /* Cache purge configuration modes. */ enum { TFW_D_CACHE_PURGE_INVALIDATE, - TFW_D_CACHE_PURGE_DELETE, }; /*