Przeglądaj źródła

feature: new option cache-mem-size

Nick Peng 1 rok temu
rodzic
commit
af3435138f
7 zmienionych plików z 41 dodań i 16 usunięć
  1. 3 0
      etc/smartdns/smartdns.conf
  2. 19 2
      src/dns_cache.c
  3. 3 1
      src/dns_cache.h
  4. 2 0
      src/dns_conf.c
  5. 1 0
      src/dns_conf.h
  6. 2 2
      src/dns_server.c
  7. 11 11
      src/include/atomic.h

+ 3 - 0
etc/smartdns/smartdns.conf

@@ -70,6 +70,9 @@ bind [::]:53
 #   -1: auto set cache size
 # cache-size 32768
 
+# dns cache memory size
+# cache-mem-size [size]
+
 # enable persist cache when restart
 # cache-persist no
 

+ 19 - 2
src/dns_cache.c

@@ -39,7 +39,9 @@ struct dns_cache_head {
 	struct hash_table cache_hash;
 	struct list_head cache_list;
 	atomic_t num;
+	atomic_t mem_size;
 	int size;
+	long max_mem_size;
 	pthread_mutex_t lock;
 	dns_cache_callback timeout_callback;
 };
@@ -49,7 +51,7 @@ typedef int (*dns_cache_read_callback)(struct dns_cache_record *cache_record, st
 static int is_cache_init;
 static struct dns_cache_head dns_cache_head;
 
-int dns_cache_init(int size, dns_cache_callback timeout_callback)
+int dns_cache_init(int size, int mem_size, dns_cache_callback timeout_callback)
 {
 	int bits = 0;
 	pthread_mutexattr_t mta;
@@ -68,7 +70,12 @@ int dns_cache_init(int size, dns_cache_callback timeout_callback)
 
 	hash_table_init(dns_cache_head.cache_hash, bits, malloc);
 	atomic_set(&dns_cache_head.num, 0);
+	atomic_set(&dns_cache_head.mem_size, 0);
 	dns_cache_head.size = size;
+	dns_cache_head.max_mem_size = mem_size;
+	if (mem_size > 0) {
+		dns_cache_head.size = INT32_MAX;
+	}
 	dns_cache_head.timeout_callback = timeout_callback;
 	pthread_mutexattr_init(&mta);
 	pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
@@ -91,6 +98,7 @@ static void _dns_cache_delete(struct dns_cache *dns_cache)
 	list_del_init(&dns_cache->list);
 	pthread_mutex_unlock(&dns_cache_head.lock);
 	atomic_dec(&dns_cache_head.num);
+	atomic_sub(sizeof(*dns_cache), &dns_cache_head.mem_size);
 	if (dns_cache->cache_data) {
 		dns_cache_data_put(dns_cache->cache_data);
 	}
@@ -158,6 +166,7 @@ struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len
 	cache_packet->head.size = packet_len;
 	cache_packet->head.magic = MAGIC_CACHE_DATA;
 	atomic_set(&cache_packet->head.ref, 1);
+	atomic_add(data_size, &dns_cache_head.mem_size);
 
 	return (struct dns_cache_data *)cache_packet;
 }
@@ -314,6 +323,7 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data
 	}
 
 	memset(dns_cache, 0, sizeof(*dns_cache));
+	atomic_add(sizeof(*dns_cache), &dns_cache_head.mem_size);
 	key = hash_string(info->domain);
 	key = jhash(&info->qtype, sizeof(info->qtype), key);
 	key = hash_string_initval(info->dns_group_name, key);
@@ -333,7 +343,8 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data
 	list_add_tail(&dns_cache->list, head);
 
 	/* Release extra cache, remove oldest cache record */
-	if (atomic_inc_return(&dns_cache_head.num) > dns_cache_head.size) {
+	if (atomic_inc_return(&dns_cache_head.num) > dns_cache_head.size ||
+		(dns_cache_head.max_mem_size > 0 && atomic_read(&dns_cache_head.mem_size) > dns_cache_head.max_mem_size)) {
 		struct dns_cache *del_cache = NULL;
 		del_cache = _dns_cache_first();
 		if (del_cache) {
@@ -519,6 +530,7 @@ void dns_cache_data_put(struct dns_cache_data *cache_data)
 		return;
 	}
 
+	atomic_sub(cache_data->head.size + sizeof(*cache_data), &dns_cache_head.mem_size);
 	free(cache_data);
 }
 
@@ -532,6 +544,11 @@ int dns_cache_total_num(void)
 	return atomic_read(&dns_cache_head.num);
 }
 
+long dns_cache_total_memsize(void)
+{
+	return atomic_read(&dns_cache_head.mem_size);
+}
+
 void dns_cache_delete(struct dns_cache *dns_cache)
 {
 	pthread_mutex_lock(&dns_cache_head.lock);

+ 3 - 1
src/dns_cache.h

@@ -132,7 +132,7 @@ typedef enum DNS_CACHE_TMOUT_ACTION {
 
 typedef dns_cache_tmout_action_t (*dns_cache_callback)(struct dns_cache *dns_cache);
 
-int dns_cache_init(int size, dns_cache_callback timeout_callback);
+int dns_cache_init(int size, int mem_size, dns_cache_callback timeout_callback);
 
 int dns_cache_replace(struct dns_cache_key *key, int rcode, int ttl, int speed, int timeout, int update_time,
 					  struct dns_cache_data *cache_data);
@@ -144,6 +144,8 @@ struct dns_cache *dns_cache_lookup(struct dns_cache_key *key);
 
 int dns_cache_total_num(void);
 
+long dns_cache_total_memsize(void);
+
 int dns_cache_update_timer(struct dns_cache_key *key, int timeout);
 
 void dns_cache_delete(struct dns_cache *dns_cache);

+ 2 - 0
src/dns_conf.c

@@ -88,6 +88,7 @@ enum response_mode_type dns_conf_default_response_mode = DNS_RESPONSE_MODE_FIRST
 
 /* cache */
 ssize_t dns_conf_cachesize = -1;
+ssize_t dns_conf_cache_max_memsize = -1;
 
 /* upstream servers */
 struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
@@ -5937,6 +5938,7 @@ static struct config_item _config_item[] = {
 	CONF_CUSTOM("speed-check-mode", _config_speed_check_mode, NULL),
 	CONF_INT("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600),
 	CONF_SSIZE("cache-size", &dns_conf_cachesize, -1, CONF_INT_MAX),
+	CONF_SSIZE("cache-mem-size", &dns_conf_cache_max_memsize, 0, CONF_INT_MAX),
 	CONF_CUSTOM("cache-file", _config_option_parser_filepath, (char *)&dns_conf_cache_file),
 	CONF_YESNO("cache-persist", &dns_conf_cache_persist),
 	CONF_INT("cache-checkpoint-time", &dns_conf_cache_checkpoint_time, 0, 3600 * 24 * 7),

+ 1 - 0
src/dns_conf.h

@@ -665,6 +665,7 @@ extern char dns_conf_need_cert;
 
 extern int dns_conf_tcp_idle_time;
 extern ssize_t dns_conf_cachesize;
+extern ssize_t dns_conf_cache_max_memsize;
 extern struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
 extern int dns_conf_server_num;
 

+ 2 - 2
src/dns_server.c

@@ -7152,7 +7152,7 @@ static int _dns_server_recv(struct dns_server_conn_head *conn, unsigned char *in
 		goto errout;
 	}
 
-	tlog(TLOG_DEBUG, "query %s from %s, qtype: %d, id: %d, query-num: %d", request->domain, name, request->qtype,
+	tlog(TLOG_DEBUG, "query %s from %s, qtype: %d, id: %d, query-num: %ld", request->domain, name, request->qtype,
 		 request->id, atomic_read(&server.request_num));
 
 	if (atomic_read(&server.request_num) > dns_conf_max_query_limit && dns_conf_max_query_limit > 0) {
@@ -9144,7 +9144,7 @@ errout:
 
 static int _dns_server_cache_init(void)
 {
-	if (dns_cache_init(dns_conf_cachesize, _dns_server_cache_expired) != 0) {
+	if (dns_cache_init(dns_conf_cachesize, dns_conf_cache_max_memsize, _dns_server_cache_expired) != 0) {
 		tlog(TLOG_ERROR, "init cache failed.");
 		return -1;
 	}

+ 11 - 11
src/include/atomic.h

@@ -29,7 +29,7 @@
  * Atomic type.
  */
 typedef struct {
-	int counter;
+	long counter;
 } atomic_t;
 
 #define ATOMIC_INIT(i)  { (i) }
@@ -40,7 +40,7 @@ typedef struct {
  *
  * Atomically reads the value of @v.
  */
-static inline int atomic_read(const atomic_t *v)
+static inline long atomic_read(const atomic_t *v)
 {
 	return READ_ONCE((v)->counter);
 }
@@ -50,7 +50,7 @@ static inline int atomic_read(const atomic_t *v)
  * @param v pointer of type atomic_t
  * @param i required value
  */
-static inline void atomic_set(atomic_t *v, int i)
+static inline void atomic_set(atomic_t *v, long i)
 {
     v->counter = i;
 }
@@ -60,7 +60,7 @@ static inline void atomic_set(atomic_t *v, int i)
  * @param i integer value to add
  * @param v pointer of type atomic_t
  */
-static inline void atomic_add( int i, atomic_t *v )
+static inline void atomic_add( long i, atomic_t *v )
 {
 	(void)__sync_add_and_fetch(&v->counter, i);
 }
@@ -72,7 +72,7 @@ static inline void atomic_add( int i, atomic_t *v )
  *
  * Atomically subtracts @i from @v.
  */
-static inline void atomic_sub( int i, atomic_t *v )
+static inline void atomic_sub( long i, atomic_t *v )
 {
 	(void)__sync_sub_and_fetch(&v->counter, i);
 }
@@ -86,7 +86,7 @@ static inline void atomic_sub( int i, atomic_t *v )
  * true if the result is zero, or false for all
  * other cases.
  */
-static inline int atomic_sub_and_test( int i, atomic_t *v )
+static inline long atomic_sub_and_test( long i, atomic_t *v )
 {
 	return !(__sync_sub_and_fetch(&v->counter, i));
 }
@@ -120,7 +120,7 @@ static inline void atomic_dec( atomic_t *v )
  *
  * Atomically increments @v by 1.
  */
-static inline int atomic_inc_return( atomic_t *v )
+static inline long atomic_inc_return( atomic_t *v )
 {
 	return __sync_add_and_fetch(&v->counter, 1);
 }
@@ -132,7 +132,7 @@ static inline int atomic_inc_return( atomic_t *v )
  * Atomically decrements @v by 1.  Note that the guaranteed
  * useful range of an atomic_t is only 24 bits.
  */
-static inline int atomic_dec_return( atomic_t *v )
+static inline long atomic_dec_return( atomic_t *v )
 {
 	return __sync_sub_and_fetch(&v->counter, 1);
 }
@@ -145,7 +145,7 @@ static inline int atomic_dec_return( atomic_t *v )
  * returns true if the result is 0, or false for all other
  * cases.
  */
-static inline int atomic_dec_and_test( atomic_t *v )
+static inline long atomic_dec_and_test( atomic_t *v )
 {
 	return !(__sync_sub_and_fetch(&v->counter, 1));
 }
@@ -158,7 +158,7 @@ static inline int atomic_dec_and_test( atomic_t *v )
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-static inline int atomic_inc_and_test( atomic_t *v )
+static inline long atomic_inc_and_test( atomic_t *v )
 {
 	return !(__sync_add_and_fetch(&v->counter, 1));
 }
@@ -172,7 +172,7 @@ static inline int atomic_inc_and_test( atomic_t *v )
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-static inline int atomic_add_negative( int i, atomic_t *v )
+static inline long atomic_add_negative( long i, atomic_t *v )
 {
 	return (__sync_add_and_fetch(&v->counter, i) < 0);
 }