Просмотр исходного кода

fix: avoid memory consumption issue from invalid conf-file settings

Nick Peng 1 день назад
Родитель
Сommit
e2e10acff7
3 измененных файлов с 29 добавлено и 53 удалено
  1. 4 2
      src/dns_conf/dns_conf.c
  2. 24 45
      src/dns_conf/plugin.c
  3. 1 6
      src/include/smartdns/dns_conf.h

+ 4 - 2
src/dns_conf/dns_conf.c

@@ -264,9 +264,11 @@ static int _conf_value_handler(const char *key, const char *value)
 		return -1;
 	}
 
-	_config_plugin_conf_add(key, value);
+#ifdef BUILD_STATIC
+	return -1;
+#endif
 
-	return 0;
+	return _config_plugin_conf_add(key, value);
 }
 
 int _conf_printf(const char *key, const char *value, const char *file, int lineno, int ret)

+ 24 - 45
src/dns_conf/plugin.c

@@ -24,6 +24,12 @@
 
 struct dns_conf_plugin_table dns_conf_plugin_table;
 
+static int _config_plugin_iter_free(void *data, const unsigned char *key, uint32_t key_len, void *value)
+{
+	free(value);
+	return 0;
+}
+
 static struct dns_conf_plugin *_config_get_plugin(const char *file)
 {
 	uint32_t key = 0;
@@ -42,32 +48,13 @@ static struct dns_conf_plugin *_config_get_plugin(const char *file)
 	return NULL;
 }
 
-static struct dns_conf_plugin_conf *_config_get_plugin_conf(const char *key)
-{
-	uint32_t hash = 0;
-	struct dns_conf_plugin_conf *conf = NULL;
-
-	hash = hash_string(key);
-	hash_for_each_possible(dns_conf_plugin_table.plugins_conf, conf, node, hash)
-	{
-		if (strncmp(conf->key, key, DNS_MAX_PATH) != 0) {
-			continue;
-		}
-
-		return conf;
-	}
-
-	return NULL;
-}
-
 const char *dns_conf_get_plugin_conf(const char *key)
 {
-	struct dns_conf_plugin_conf *conf = _config_get_plugin_conf(key);
-	if (conf == NULL) {
+	if (key == NULL) {
 		return NULL;
 	}
 
-	return conf->value;
+	return art_search(&dns_conf_plugin_table.plugins_conf, (unsigned char *)key, strlen(key) + 1);
 }
 
 int _config_plugin(void *data, int argc, char *argv[])
@@ -168,26 +155,25 @@ errout:
 
 int _config_plugin_conf_add(const char *key, const char *value)
 {
-	uint32_t hash = 0;
-	struct dns_conf_plugin_conf *conf = NULL;
-
+	char *old_value = NULL;
+	char *new_value = NULL;
 	if (key == NULL || value == NULL) {
-		tlog(TLOG_ERROR, "invalid parameter.");
 		goto errout;
 	}
 
-	conf = _config_get_plugin_conf(key);
-	if (conf == NULL) {
+	if (key[0] == '\0' || value[0] == '\0') {
+		goto errout;
+	}
 
-		hash = hash_string(key);
-		conf = zalloc(1, sizeof(*conf));
-		if (conf == NULL) {
-			goto errout;
-		}
-		safe_strncpy(conf->key, key, sizeof(conf->key) - 1);
-		hash_add(dns_conf_plugin_table.plugins_conf, &conf->node, hash);
+	new_value = strdup(value);
+	if (new_value == NULL) {
+		goto errout;
+	}
+
+	old_value = art_insert(&dns_conf_plugin_table.plugins_conf, (unsigned char *)key, strlen(key) + 1, new_value);
+	if (old_value) {
+		free(old_value);
 	}
-	safe_strncpy(conf->value, value, sizeof(conf->value) - 1);
 
 	return 0;
 
@@ -198,7 +184,7 @@ errout:
 void _config_plugin_table_init(void)
 {
 	hash_init(dns_conf_plugin_table.plugins);
-	hash_init(dns_conf_plugin_table.plugins_conf);
+	art_tree_init(&dns_conf_plugin_table.plugins_conf);
 }
 
 void _config_plugin_table_destroy(void)
@@ -216,15 +202,8 @@ void _config_plugin_table_destroy(void)
 
 void _config_plugin_table_conf_destroy(void)
 {
-	struct dns_conf_plugin_conf *plugin_conf = NULL;
-	struct hlist_node *tmp = NULL;
-	unsigned long i = 0;
-
-	hash_for_each_safe(dns_conf_plugin_table.plugins_conf, i, tmp, plugin_conf, node)
-	{
-		hlist_del_init(&plugin_conf->node);
-		free(plugin_conf);
-	}
+	art_iter(&dns_conf_plugin_table.plugins_conf, _config_plugin_iter_free, NULL);
+	art_tree_destroy(&dns_conf_plugin_table.plugins_conf);
 }
 
 void dns_conf_clear_all_plugin_conf(void)

+ 1 - 6
src/include/smartdns/dns_conf.h

@@ -676,15 +676,10 @@ struct dns_conf_plugin {
 	int args_len;
 };
 
-struct dns_conf_plugin_conf {
-	struct hlist_node node;
-	char key[MAX_KEY_LEN];
-	char value[MAX_LINE_LEN];
-};
 
 struct dns_conf_plugin_table {
 	DECLARE_HASHTABLE(plugins, 4);
-	DECLARE_HASHTABLE(plugins_conf, 4);
+	art_tree plugins_conf;
 };
 extern struct dns_conf_plugin_table dns_conf_plugin_table;
 extern char dns_conf_exist_bootstrap_dns;