容器化的无污染DNS服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

117 lines
4.5 KiB

#include <stdlib.h>
#include <string.h>
#include "json.h"
#include "bcrypt.h"
#include "logger.h"
#include "sundry.h"
#include "system.h"
#include "adguard.h"
#include "constant.h"
void adguard_dump(adguard *info);
char *adguard_config(adguard *info, const char *raw_config);
void adguard_free(adguard *info) { // free adguard options
free(info->upstream);
free(info->username);
free(info->password);
free(info);
}
adguard* adguard_init() { // init adguard options
adguard *info = (adguard *)malloc(sizeof(adguard));
char *port_str = uint32_to_string(DIVERTER_PORT); // diverter port in string
info->debug = FALSE;
info->dns_port = DNS_PORT;
info->web_port = ADGUARD_PORT;
info->upstream = string_join("127.0.0.1:", port_str); // default upstream
info->username = string_init(ADGUARD_USER);
info->password = string_init(ADGUARD_PASSWD);
free(port_str);
return info;
}
void adguard_dump(adguard *info) { // show adguard options in debug log
log_debug("AdGuardHome debug -> %s", show_bool(info->debug));
log_debug("AdGuardHome dns port -> %u", info->dns_port);
log_debug("AdGuardHome web port -> %u", info->web_port);
log_debug("AdGuardHome upstream -> %s", info->upstream);
log_debug("AdGuardHome username -> %s", info->username);
log_debug("AdGuardHome password -> %s", info->password);
}
char *adguard_config(adguard *info, const char *raw_config) { // modify adguard configure
cJSON *json = cJSON_Parse(raw_config);
if (json == NULL) {
log_fatal("AdGuardHome configure error");
}
cJSON *user_config = cJSON_CreateObject(); // setting up username and password
cJSON *users_config = cJSON_CreateArray();
char *password = bcrypt_cal(info->password);
cJSON_AddItemToObject(user_config, "name", cJSON_CreateString(info->username));
cJSON_AddItemToObject(user_config, "password", cJSON_CreateString(password));
cJSON_AddItemToArray(users_config, user_config);
json_field_replace(json, "users", users_config);
free(password);
cJSON *dns = json_field_get(json, "dns"); // setting up dns options
cJSON *upstream = cJSON_CreateArray();
cJSON_AddItemToArray(upstream, cJSON_CreateString(info->upstream));
json_field_replace(dns, "port", cJSON_CreateNumber(info->dns_port));
json_field_replace(dns, "bind_host", cJSON_CreateString("0.0.0.0"));
json_field_replace(dns, "upstream_dns", upstream);
json_field_replace(dns, "upstream_dns_file", cJSON_CreateString(""));
json_field_replace(dns, "bootstrap_dns", cJSON_CreateArray());
char *config = cJSON_Print(json); // generate json string
cJSON_free(json);
return config;
}
process* adguard_load(adguard *info, const char *dir) { // load adguard options
adguard_dump(info);
if (!check_port(info->dns_port)) { // invalid dns port
log_fatal("Invalid dns port `%u`", info->dns_port);
}
if (!check_port(info->web_port)) { // invalid web port
log_fatal("Invalid web port `%u`", info->web_port);
}
if (!strcmp(info->username, "")) { // invalid username
log_fatal("Invalid AdGuardHome username");
}
if (!strcmp(info->password, "")) { // invalid password
log_fatal("Invalid AdGuardHome password");
}
create_folder(dir); // ensure adguard work dir exist
char *adguard_config_ret;
char *adguard_config_file = string_join(dir, "AdGuardHome.yaml");
// TODO: skip to-json if AdGuardHome configure not exist
char *adguard_config_raw = to_json(adguard_config_file);
if (adguard_config_raw == NULL) { // configure not exist
log_info("Create AdGuardHome configure");
adguard_config_ret = adguard_config(info, "{}"); // begin with empty json
} else {
adguard_config_ret = adguard_config(info, adguard_config_raw);
free(adguard_config_raw);
}
save_file(adguard_config_file, adguard_config_ret); // save modified configure
free(adguard_config_file);
process *proc = process_init("AdGuardHome", ADGUARD_BIN); // generate adguard command
char *port_str = uint32_to_string(info->web_port);
process_add_arg(proc, "--no-check-update"); // disable update check (invalid in docker)
process_add_arg(proc, "--work-dir");
process_add_arg(proc, dir);
process_add_arg(proc, "--port"); // web server port
process_add_arg(proc, port_str);
if (info->debug) {
process_add_arg(proc, "--verbose"); // adguard enable debug mode
}
free(port_str);
log_info("AdGuardHome load success");
return proc;
}