From 85a5c866372ab69fb4ebf06e470e9ce0f3fd0216 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Wed, 26 Oct 2016 08:53:21 +0800 Subject: [PATCH] Refine LRU cache by clearing old objects --- src/acl.c | 6 ++++++ src/acl.h | 1 + src/cache.c | 44 +++++++++++++++++++++++++++++++++++++++++++- src/cache.h | 15 +++++++++------ src/encrypt.c | 6 +++--- src/local.c | 2 +- src/redir.c | 4 ++++ src/server.c | 14 +++++++++++++- src/tunnel.c | 4 ++++ 9 files changed, 84 insertions(+), 12 deletions(-) diff --git a/src/acl.c b/src/acl.c index 4a5302f0..9a4a02ae 100644 --- a/src/acl.c +++ b/src/acl.c @@ -56,6 +56,12 @@ remove_from_block_list(char *addr) return cache_remove(block_list, addr, addr_len); } +void +clear_block_list() +{ + cache_clear(block_list, 3600); // Clear items older than 1 hour +} + int check_block_list(char *addr, int err_level) { diff --git a/src/acl.h b/src/acl.h index 2ab1c917..d786d46e 100644 --- a/src/acl.h +++ b/src/acl.h @@ -34,6 +34,7 @@ int init_acl(const char *path); void free_acl(void); +void clear_block_list(void); int acl_match_host(const char *ip); int acl_add_ip(const char *ip); diff --git a/src/cache.c b/src/cache.c index 5387d021..0b1268e8 100644 --- a/src/cache.c +++ b/src/cache.c @@ -94,7 +94,7 @@ cache_delete(struct cache *cache, int keep_data) if (cache->free_cb) { cache->free_cb(entry->data); } else { - ss_free(tmp->data); + ss_free(entry->data); } } ss_free(entry->key); @@ -106,6 +106,45 @@ cache_delete(struct cache *cache, int keep_data) return 0; } +/** Clear old cache object + * + * @param cache + * The cache object to clear + * + * @param age + * Clear only objects older than the age (sec) + * + * @return EINVAL if cache is NULL, 0 otherwise + */ +int +cache_clear(struct cache *cache, ev_tstamp age) +{ + struct cache_entry *entry, *tmp; + + if (!cache) { + return EINVAL; + } + + ev_tstamp now = ev_time(); + + HASH_ITER(hh, cache->entries, entry, tmp){ + if (now - entry->ts > age) { + HASH_DEL(cache->entries, entry); + if (entry->data != NULL) { + if (cache->free_cb) { + cache->free_cb(entry->data); + } else { + ss_free(entry->data); + } + } + ss_free(entry->key); + ss_free(entry); + } + } + + return 0; +} + /** Removes a cache entry * * @param cache @@ -179,6 +218,7 @@ cache_lookup(struct cache *cache, char *key, size_t key_len, void *result) HASH_FIND(hh, cache->entries, key, key_len, tmp); if (tmp) { HASH_DELETE(hh, cache->entries, tmp); + tmp->ts = ev_time(); HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); *dirty_hack = tmp->data; } else { @@ -200,6 +240,7 @@ cache_key_exist(struct cache *cache, char *key, size_t key_len) HASH_FIND(hh, cache->entries, key, key_len, tmp); if (tmp) { HASH_DELETE(hh, cache->entries, tmp); + tmp->ts = ev_time(); HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); return 1; } else { @@ -242,6 +283,7 @@ cache_insert(struct cache *cache, char *key, size_t key_len, void *data) entry->key = ss_malloc(key_len); memcpy(entry->key, key, key_len); entry->data = data; + entry->ts = ev_time(); HASH_ADD_KEYPTR(hh, cache->entries, entry->key, key_len, entry); if (HASH_COUNT(cache->entries) >= cache->max_entries) { diff --git a/src/cache.h b/src/cache.h index 4bab8a81..9e97a4ad 100644 --- a/src/cache.h +++ b/src/cache.h @@ -29,6 +29,7 @@ #define _CACHE_ #include "uthash.h" +#include "ev.h" /** * A cache entry @@ -36,6 +37,7 @@ struct cache_entry { char *key; /**= CIPHER_NUM) { - LOGE("Invalid cipher name: %s, use table instead", method); - m = TABLE; + LOGE("Invalid cipher name: %s, use rc4-md5 instead", method); + m = RC4_MD5; } } if (m == TABLE) { diff --git a/src/local.c b/src/local.c index c5ec4cd0..2e483475 100644 --- a/src/local.c +++ b/src/local.c @@ -1316,7 +1316,7 @@ main(int argc, char **argv) } if (method == NULL) { - method = "table"; + method = "rc4-md5"; } if (timeout == NULL) { diff --git a/src/redir.c b/src/redir.c index 52844189..6ba901e4 100644 --- a/src/redir.c +++ b/src/redir.c @@ -910,6 +910,10 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } + if (method == NULL) { + method = "rc4-md5"; + } + if (timeout == NULL) { timeout = "60"; } diff --git a/src/server.c b/src/server.c index 3357432a..b20a4267 100644 --- a/src/server.c +++ b/src/server.c @@ -91,6 +91,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents); static void remote_recv_cb(EV_P_ ev_io *w, int revents); static void remote_send_cb(EV_P_ ev_io *w, int revents); static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents); +static void block_list_clear_cb(EV_P_ ev_timer *watcher, int revents); static remote_t *new_remote(int fd); static server_t *new_server(int fd, listen_ctx_t *listener); @@ -127,6 +128,7 @@ static char *manager_address = NULL; uint64_t tx = 0; uint64_t rx = 0; ev_timer stat_update_watcher; +ev_timer block_list_watcher; static struct cork_dllist connections; @@ -974,6 +976,12 @@ server_send_cb(EV_P_ ev_io *w, int revents) } } +static void +block_list_clear_cb(EV_P_ ev_timer *watcher, int revents) +{ + clear_block_list(); +} + static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents) { @@ -1653,7 +1661,7 @@ main(int argc, char **argv) } if (method == NULL) { - method = "table"; + method = "rc4-md5"; } if (timeout == NULL) { @@ -1793,6 +1801,9 @@ main(int argc, char **argv) ev_timer_start(EV_DEFAULT, &stat_update_watcher); } + ev_timer_init(&block_list_watcher, block_list_clear_cb, UPDATE_INTERVAL, UPDATE_INTERVAL); + ev_timer_start(EV_DEFAULT, &block_list_watcher); + // setuid if (user != NULL) { run_as(user); @@ -1811,6 +1822,7 @@ main(int argc, char **argv) if (manager_address != NULL) { ev_timer_stop(EV_DEFAULT, &stat_update_watcher); } + ev_timer_stop(EV_DEFAULT, &block_list_watcher); // Clean up for (int i = 0; i <= server_num; i++) { diff --git a/src/tunnel.c b/src/tunnel.c index 663b83d2..1a7c52cb 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -909,6 +909,10 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } + if (method == NULL) { + method = "rc4-md5"; + } + if (timeout == NULL) { timeout = "60"; }