From f3bc8862fb036808d584fcfe87dfa2cbf77b70e5 Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Tue, 13 Sep 2022 01:04:32 +0800 Subject: [PATCH] update: complete json parser --- include/{load.h => loader.h} | 0 src/CMakeLists.txt | 4 +- src/cleardns.c | 2 +- src/{load => loader}/CMakeLists.txt | 2 +- src/{load/load.c => loader/config.c} | 7 ++- src/{load/json.c => loader/parser.c} | 75 ++++++++++++++++++++++++---- 6 files changed, 75 insertions(+), 15 deletions(-) rename include/{load.h => loader.h} (100%) rename src/{load => loader}/CMakeLists.txt (51%) rename src/{load/load.c => loader/config.c} (97%) rename src/{load/json.c => loader/parser.c} (68%) diff --git a/include/load.h b/include/loader.h similarity index 100% rename from include/load.h rename to include/loader.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ac2906..ac65f3f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12) include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_SOURCE_DIR}/include/utils) -add_subdirectory(load) +add_subdirectory(loader) add_subdirectory(utils) add_executable(cleardns cleardns.c dnsproxy.c common.c overture.c) -target_link_libraries(cleardns load utils) +target_link_libraries(cleardns loader utils) diff --git a/src/cleardns.c b/src/cleardns.c index 242fc12..f0f2ec9 100644 --- a/src/cleardns.c +++ b/src/cleardns.c @@ -1,5 +1,5 @@ #include -#include "load.h" +#include "loader.h" #include "logger.h" #include "common.h" #include "dnsproxy.h" diff --git a/src/load/CMakeLists.txt b/src/loader/CMakeLists.txt similarity index 51% rename from src/load/CMakeLists.txt rename to src/loader/CMakeLists.txt index fc14767..f8a6f74 100644 --- a/src/load/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 2.8.12) -add_library(load load.c json.c) +add_library(loader config.c parser.c) diff --git a/src/load/load.c b/src/loader/config.c similarity index 97% rename from src/load/load.c rename to src/loader/config.c index 727a2c5..92ee0d8 100644 --- a/src/load/load.c +++ b/src/loader/config.c @@ -1,4 +1,4 @@ -#include "load.h" +#include "loader.h" #include "common.h" #include "logger.h" #include "structure.h" @@ -82,4 +82,9 @@ void load_config(const char *config_file) { log_info("Configure load success"); config_dump(config); + + // TODO: load into process + + // TODO: free config struct + } diff --git a/src/load/json.c b/src/loader/parser.c similarity index 68% rename from src/load/json.c rename to src/loader/parser.c index 3ff434a..26a0851 100644 --- a/src/load/json.c +++ b/src/loader/parser.c @@ -1,6 +1,6 @@ #include #include -#include "load.h" +#include "loader.h" #include "cJSON.h" #include "common.h" #include "logger.h" @@ -41,7 +41,7 @@ char** json_string_list_value(char *key, cJSON *json, char **string_list) { string_list = string_list_append(string_list, json->valuestring); json = json->next; // next field } - } else { + } else if (!cJSON_IsNull(json)) { log_fatal("`%s` must be array or string", key); } return string_list; @@ -59,7 +59,7 @@ uint32_t** json_uint32_list_value(char *key, cJSON *json, uint32_t **uint32_list uint32_list = uint32_list_append(uint32_list, json->valueint); json = json->next; // next field } - } else { + } else if (!cJSON_IsNull(json)) { log_fatal("`%s` must be array or number", key); } return uint32_list; @@ -73,6 +73,10 @@ uint8_t json_bool_value(char *key, cJSON *json) { // json bool value -> bool } void json_cache_parser(cache_config *config, cJSON *json) { // cache options parser + if (!cJSON_IsObject(json)) { + log_fatal("`cache` must be object"); + } + json = json->child; while (json != NULL) { if (!strcmp(json->string, "size")) { config->size = json_int_value("cache.size", json); @@ -87,7 +91,52 @@ void json_cache_parser(cache_config *config, cJSON *json) { // cache options par } } +void json_upstream_parser(char *caption, upstream_config *config, cJSON *json) { + if (!cJSON_IsObject(json)) { + log_fatal("`%s` must be object", caption); + } + char *key_name; + json = json->child; + while (json != NULL) { + if (!strcmp(json->string, "port")) { + key_name = string_join(caption, ".port"); + config->port = json_int_value(key_name, json); + free(key_name); + } + if (!strcmp(json->string, "verify")) { + key_name = string_join(caption, ".verify"); + config->verify = json_bool_value(key_name, json); + free(key_name); + } + if (!strcmp(json->string, "parallel")) { + key_name = string_join(caption, ".parallel"); + config->parallel = json_bool_value(key_name, json); + free(key_name); + } + if (!strcmp(json->string, "bootstrap")) { + key_name = string_join(caption, ".bootstrap"); + config->bootstrap = json_string_list_value(key_name, json, config->bootstrap); + free(key_name); + } + if (!strcmp(json->string, "fallback")) { + key_name = string_join(caption, ".fallback"); + config->fallback = json_string_list_value(key_name, json, config->fallback); + free(key_name); + } + if (!strcmp(json->string, "primary")) { + key_name = string_join(caption, ".primary"); + config->primary = json_string_list_value(key_name, json, config->primary); + free(key_name); + } + json = json->next; // next field + } +} + void json_diverter_parser(diverter_config *config, cJSON *json) { // diverter options parser + if (!cJSON_IsObject(json)) { + log_fatal("`diverter` must be object"); + } + json = json->child; while (json != NULL) { if (!strcmp(json->string, "port")) { config->port = json_int_value("diverter.port", json); @@ -106,6 +155,10 @@ void json_diverter_parser(diverter_config *config, cJSON *json) { // diverter op } void json_adguard_parser(adguard_config *config, cJSON *json) { // adguard options parser + if (!cJSON_IsObject(json)) { + log_fatal("`adguard` must be array"); + } + json = json->child; while (json != NULL) { if (!strcmp(json->string, "port")) { config->port = json_int_value("adguard.port", json); @@ -135,17 +188,19 @@ void json_config_parser(cleardns_config *config, const char *config_file) { // J config->port = json_int_value("port", json); } if (!strcmp(json->string, "cache")) { - json_cache_parser(&config->cache, json->child); + json_cache_parser(&config->cache, json); + } + if (!strcmp(json->string, "domestic")) { + json_upstream_parser("domestic", &config->domestic, json); + } + if (!strcmp(json->string, "foreign")) { + json_upstream_parser("foreign", &config->foreign, json); } - - // domestic - // foreign - if (!strcmp(json->string, "diverter")) { - json_diverter_parser(&config->diverter, json->child); + json_diverter_parser(&config->diverter, json); } if (!strcmp(json->string, "adguard")) { - json_adguard_parser(&config->adguard, json->child); + json_adguard_parser(&config->adguard, json); } if (!strcmp(json->string, "reject")) { config->reject = json_uint32_list_value("reject", json, config->reject);