user-directory.c revision 069d9f1da8dffdce72a80650217eb92450dee643
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* n% of timeout_secs */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* but max. of this many secs */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* const char *username => struct user* */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* sorted by time */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ARRAY_DEFINE(iters, struct user_directory_iter *);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* If user's expire time is less than this many seconds away,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen don't assume that other directors haven't yet expired it */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void user_move_iters(struct user_directory *dir, struct user *user)
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainenstatic void user_free(struct user_directory *dir, struct user *user)
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen hash_table_remove(dir->hash, POINTER_CAST(user->username_hash));
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainenstatic bool user_directory_user_has_connections(struct user_directory *dir,
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen time_t expire_timestamp = user->timestamp + dir->timeout_secs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void user_directory_drop_expired(struct user_directory *dir)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen !user_directory_user_has_connections(dir, dir->head))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct user *user_directory_lookup(struct user_directory *dir,
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen return hash_table_lookup(dir->hash, POINTER_CAST(username_hash));
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainenuser_directory_insert_backwards(struct user_directory *dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((time_t)pos->timestamp <= user->timestamp)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen DLLIST2_PREPEND(&dir->head, &dir->tail, user);
e2eac5bb5637c2d4aaf453389750740931822b92Timo Sirainenuser_directory_insert_forwards(struct user_directory *dir,
e2bdacc34dde56aa664059ab56e8b77e82bd1805Timo Sirainen if ((time_t)pos->timestamp >= user->timestamp)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenuser_directory_add(struct user_directory *dir, unsigned int username_hash,
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen /* add it at the end */
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen /* make sure we don't add timestamps higher than ioloop time */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (dir->tail == NULL || (time_t)dir->tail->timestamp <= timestamp)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* need to insert to correct position. we should get here
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen only when handshaking. the handshaking USER requests should
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen come sorted by timestamp. so keep track of the previous
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen insert position, the next USER should be inserted after
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* find the position starting from tail */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user_directory_insert_backwards(dir, dir->tail, user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else if (timestamp < dir->prev_insert_pos->timestamp) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user_directory_insert_backwards(dir, dir->prev_insert_pos,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user_directory_insert_forwards(dir, dir->prev_insert_pos,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_table_insert(dir->hash, POINTER_CAST(user->username_hash), user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid user_directory_refresh(struct user_directory *dir, struct user *user)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid user_directory_remove_host(struct user_directory *dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (user = dir->head; user != NULL; user = next) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenunsigned int user_directory_get_username_hash(struct user_directory *dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return mail_user_hash(username, dir->username_hash_fmt);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenbool user_directory_user_is_recently_updated(struct user_directory *dir,
06eb8c1371aa06478d8840b1373cab7c2752d5edTimo Sirainen return (time_t)(user->timestamp + dir->timeout_secs/2) >= ioloop_time;
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainenbool user_directory_user_is_near_expiring(struct user_directory *dir,
06eb8c1371aa06478d8840b1373cab7c2752d5edTimo Sirainen (dir->timeout_secs - dir->user_near_expiring_secs);
9047d770bfbb93ab6af5363dedb2d01363877243Timo Sirainenuser_directory_init(unsigned int timeout_secs, const char *username_hash_fmt)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen timeout_secs * USER_NEAR_EXPIRING_PERCENTAGE / 100;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen I_MIN(dir->user_near_expiring_secs, USER_NEAR_EXPIRING_MAX);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dir->username_hash_fmt = i_strdup(username_hash_fmt);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen dir->hash = hash_table_create(default_pool, default_pool,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid user_directory_deinit(struct user_directory **_dir)
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainenuser_directory_iter_init(struct user_directory *dir)
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainenstruct user *user_directory_iter_next(struct user_directory_iter *iter)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid user_directory_iter_deinit(struct user_directory_iter **_iter)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, count;
ddedc8b77c5bccc8d224ab5f8716d9874f5d8512Timo Sirainen for (i = 0; i < count; i++) {