dovecot: Added auth_cache_negative_ttl setting.

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 6 18:02:52 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/6c48466c23fa
changeset: 6174:6c48466c23fa
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 06 18:02:48 2007 +0300
description:
Added auth_cache_negative_ttl setting.

diffstat:

7 files changed, 33 insertions(+), 9 deletions(-)
dovecot-example.conf         |    2 ++
src/auth/auth-cache.c        |   21 +++++++++++++++++----
src/auth/auth-cache.h        |    8 +++++---
src/auth/passdb-cache.c      |    6 ++++--
src/master/auth-process.c    |    2 ++
src/master/master-settings.c |    2 ++
src/master/master-settings.h |    1 +

diffs (175 lines):

diff -r 370691a10003 -r 6c48466c23fa dovecot-example.conf
--- a/dovecot-example.conf	Mon Aug 06 17:45:25 2007 +0300
+++ b/dovecot-example.conf	Mon Aug 06 18:02:48 2007 +0300
@@ -720,6 +720,8 @@ protocol lda {
 # user's previous authentication was successful, but this one wasn't, the
 # cache isn't used. For now this works only with plaintext authentication.
 #auth_cache_ttl = 3600
+# TTL for negative hits (user not found). 0 disables caching them completely.
+#auth_cache_negative_ttl = 3600
 
 # Space separated list of realms for SASL authentication mechanisms that need
 # them. You can leave it empty if you don't want to support multiple realms.
diff -r 370691a10003 -r 6c48466c23fa src/auth/auth-cache.c
--- a/src/auth/auth-cache.c	Mon Aug 06 17:45:25 2007 +0300
+++ b/src/auth/auth-cache.c	Mon Aug 06 18:02:48 2007 +0300
@@ -16,7 +16,7 @@ struct auth_cache {
 	struct auth_cache_node *head, *tail;
 
 	size_t size_left;
-	unsigned int ttl_secs;
+	unsigned int ttl_secs, neg_ttl_secs;
 
 	unsigned int hit_count, miss_count;
 };
@@ -112,7 +112,9 @@ static void sig_auth_cache_stats(int sig
 	cache->hit_count = cache->miss_count = 0;
 }
 
-struct auth_cache *auth_cache_new(size_t max_size, unsigned int ttl_secs)
+struct auth_cache *auth_cache_new(size_t max_size, unsigned int ttl_secs,
+				  unsigned int neg_ttl_secs
+)
 {
 	struct auth_cache *cache;
 
@@ -121,6 +123,7 @@ struct auth_cache *auth_cache_new(size_t
 				  (hash_cmp_callback_t *)strcmp);
 	cache->size_left = max_size;
 	cache->ttl_secs = ttl_secs;
+	cache->neg_ttl_secs = neg_ttl_secs;
 
 	lib_signals_set_handler(SIGHUP, TRUE, sig_auth_cache_clear, cache);
 	lib_signals_set_handler(SIGUSR2, TRUE, sig_auth_cache_stats, cache);
@@ -154,6 +157,8 @@ auth_cache_lookup(struct auth_cache *cac
 {
 	string_t *str;
 	struct auth_cache_node *node;
+	const char *value;
+	unsigned int ttl_secs;
 
 	*expired_r = FALSE;
 
@@ -171,7 +176,10 @@ auth_cache_lookup(struct auth_cache *cac
 	}
 	cache->hit_count++;
 
-	if (node->created < time(NULL) - (time_t)cache->ttl_secs) {
+	value = node->data + strlen(node->data) + 1;
+	ttl_secs = *value == '\0' ? cache->neg_ttl_secs : cache->ttl_secs;
+
+	if (node->created < time(NULL) - (time_t)ttl_secs) {
 		/* TTL expired */
 		*expired_r = TRUE;
 	} else {
@@ -185,7 +193,7 @@ auth_cache_lookup(struct auth_cache *cac
 	if (node_r != NULL)
 		*node_r = node;
 
-	return node->data + strlen(node->data) + 1;
+	return value;
 }
 
 void auth_cache_insert(struct auth_cache *cache, struct auth_request *request,
@@ -195,6 +203,11 @@ void auth_cache_insert(struct auth_cache
         struct auth_cache_node *node;
 	size_t data_size, alloc_size, value_len = strlen(value);
 	char *current_username;
+
+	if (*value == '\0' && cache->neg_ttl_secs == 0) {
+		/* we're not caching negative entries */
+		return;
+	}
 
 	/* store into cache using the original username, except if we're doing
 	   a master user login */
diff -r 370691a10003 -r 6c48466c23fa src/auth/auth-cache.h
--- a/src/auth/auth-cache.h	Mon Aug 06 17:45:25 2007 +0300
+++ b/src/auth/auth-cache.h	Mon Aug 06 18:02:48 2007 +0300
@@ -22,8 +22,10 @@ char *auth_cache_parse_key(pool_t pool, 
 
 /* Create a new cache. max_size specifies the maximum amount of memory in
    bytes to use for cache (it's not fully exact). ttl_secs specifies time to
-   live for cache record, requests older than that are not used. */
-struct auth_cache *auth_cache_new(size_t max_size, unsigned int ttl_secs);
+   live for cache record, requests older than that are not used.
+   neg_ttl_secs specifies the TTL for negative entries. */
+struct auth_cache *auth_cache_new(size_t max_size, unsigned int ttl_secs,
+				  unsigned int neg_ttl_secs);
 void auth_cache_free(struct auth_cache **cache);
 
 /* Clear the cache. */
@@ -36,7 +38,7 @@ auth_cache_lookup(struct auth_cache *cac
 auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request,
 		  const char *key, struct auth_cache_node **node_r,
 		  bool *expired_r);
-/* Insert key => value into cache. */
+/* Insert key => value into cache. "" value means negative cache entry. */
 void auth_cache_insert(struct auth_cache *cache, struct auth_request *request,
 		       const char *key, const char *value, bool last_success);
 
diff -r 370691a10003 -r 6c48466c23fa src/auth/passdb-cache.c
--- a/src/auth/passdb-cache.c	Mon Aug 06 17:45:25 2007 +0300
+++ b/src/auth/passdb-cache.c	Mon Aug 06 18:02:48 2007 +0300
@@ -117,7 +117,7 @@ void passdb_cache_init(void)
 {
 	const char *env;
 	size_t max_size;
-	unsigned int cache_ttl;
+	unsigned int cache_ttl, neg_cache_ttl;
 
 	env = getenv("CACHE_SIZE");
 	if (env == NULL)
@@ -135,7 +135,9 @@ void passdb_cache_init(void)
 	if (cache_ttl == 0)
 		return;
 
-	passdb_cache = auth_cache_new(max_size, cache_ttl);
+	env = getenv("CACHE_NEGATIVE_TTL");
+	neg_cache_ttl = env == NULL ? 0 : (unsigned int)strtoul(env, NULL, 10);
+	passdb_cache = auth_cache_new(max_size, cache_ttl, neg_cache_ttl);
 }
 
 void passdb_cache_deinit(void)
diff -r 370691a10003 -r 6c48466c23fa src/master/auth-process.c
--- a/src/master/auth-process.c	Mon Aug 06 17:45:25 2007 +0300
+++ b/src/master/auth-process.c	Mon Aug 06 18:02:48 2007 +0300
@@ -436,6 +436,8 @@ static void auth_set_environment(struct 
 			    set->master_user_separator, NULL));
 	env_put(t_strdup_printf("CACHE_SIZE=%u", set->cache_size));
 	env_put(t_strdup_printf("CACHE_TTL=%u", set->cache_ttl));
+	env_put(t_strdup_printf("CACHE_NEGATIVE_TTL=%u",
+				set->cache_negative_ttl));
 
 	for (ap = set->passdbs, i = 1; ap != NULL; ap = ap->next, i++) {
 		env_put(t_strdup_printf("PASSDB_%u_DRIVER=%s", i, ap->driver));
diff -r 370691a10003 -r 6c48466c23fa src/master/master-settings.c
--- a/src/master/master-settings.c	Mon Aug 06 17:45:25 2007 +0300
+++ b/src/master/master-settings.c	Mon Aug 06 18:02:48 2007 +0300
@@ -67,6 +67,7 @@ static struct setting_def auth_setting_d
 	DEF_STR(default_realm),
 	DEF_INT(cache_size),
 	DEF_INT(cache_ttl),
+	DEF_INT(cache_negative_ttl),
 	DEF_STR(executable),
 	DEF_STR(user),
 	DEF_STR(chroot),
@@ -291,6 +292,7 @@ struct auth_settings default_auth_settin
 	MEMBER(default_realm) "",
 	MEMBER(cache_size) 0,
 	MEMBER(cache_ttl) 3600,
+	MEMBER(cache_negative_ttl) 3600,
 	MEMBER(executable) PKG_LIBEXECDIR"/dovecot-auth",
 	MEMBER(user) "root",
 	MEMBER(chroot) "",
diff -r 370691a10003 -r 6c48466c23fa src/master/master-settings.h
--- a/src/master/master-settings.h	Mon Aug 06 17:45:25 2007 +0300
+++ b/src/master/master-settings.h	Mon Aug 06 18:02:48 2007 +0300
@@ -193,6 +193,7 @@ struct auth_settings {
 	const char *default_realm;
 	unsigned int cache_size;
 	unsigned int cache_ttl;
+	unsigned int cache_negative_ttl;
 	const char *executable;
 	const char *user;
 	const char *chroot;


More information about the dovecot-cvs mailing list