|
|
|
|
@ -222,20 +222,34 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap
|
|
|
|
|
int config_ensure_keys_and_node_id(const char *filename) { |
|
|
|
|
// ── Read config file into memory (single open) ──
|
|
|
|
|
FILE *fp = fopen(filename, "rb"); |
|
|
|
|
if (!fp) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to open config file: %s (errno=%d)", filename, errno); |
|
|
|
|
return -1; |
|
|
|
|
char *file_buf = NULL; |
|
|
|
|
size_t file_size = 0; |
|
|
|
|
struct utun_config *config = NULL; |
|
|
|
|
|
|
|
|
|
if (fp) { |
|
|
|
|
fseek(fp, 0, SEEK_END); long fsz = ftell(fp); fseek(fp, 0, SEEK_SET); |
|
|
|
|
if (fsz < 0) { fclose(fp); return -1; } |
|
|
|
|
file_size = (size_t)fsz; |
|
|
|
|
file_buf = u_malloc(file_size + 1); |
|
|
|
|
if (!file_buf || fread(file_buf, 1, file_size, fp) != file_size) { u_free(file_buf); fclose(fp); return -1; } |
|
|
|
|
file_buf[file_size] = '\0'; |
|
|
|
|
fclose(fp); |
|
|
|
|
config = parse_config_from_buf(file_buf, file_size, filename); |
|
|
|
|
if (!config) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to parse config from buffer: %s", filename); u_free(file_buf); return -1; } |
|
|
|
|
} else { |
|
|
|
|
// No file — create minimal config
|
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Config file not found, creating new: %s (errno=%d)", filename, errno); |
|
|
|
|
config = u_calloc(1, sizeof(struct utun_config)); |
|
|
|
|
if (!config) return -1; |
|
|
|
|
config->global.my_node_id = 0; |
|
|
|
|
config->global.my_private_key_hex[0] = '\0'; |
|
|
|
|
config->global.my_public_key_hex[0] = '\0'; |
|
|
|
|
config->global.name[0] = '\0'; |
|
|
|
|
config->global.keepalive_timeout = 2000; |
|
|
|
|
config->global.keepalive_interval = 200; |
|
|
|
|
config->global.keepalive_adaptive = 1; |
|
|
|
|
config->global.bbr_max_cwnd = 1048576; |
|
|
|
|
} |
|
|
|
|
fseek(fp, 0, SEEK_END); long fsz = ftell(fp); fseek(fp, 0, SEEK_SET); |
|
|
|
|
if (fsz < 0) { fclose(fp); return -1; } |
|
|
|
|
size_t file_size = (size_t)fsz; |
|
|
|
|
char *file_buf = u_malloc(file_size + 1); |
|
|
|
|
if (!file_buf || fread(file_buf, 1, file_size, fp) != file_size) { u_free(file_buf); fclose(fp); return -1; } |
|
|
|
|
file_buf[file_size] = '\0'; |
|
|
|
|
fclose(fp); |
|
|
|
|
|
|
|
|
|
struct utun_config *config = parse_config_from_buf(file_buf, file_size, filename); |
|
|
|
|
if (!config) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to parse config from buffer: %s", filename); u_free(file_buf); return -1; } |
|
|
|
|
|
|
|
|
|
struct global_config *global = &config->global; |
|
|
|
|
|
|
|
|
|
@ -294,34 +308,54 @@ int config_ensure_keys_and_node_id(const char *filename) {
|
|
|
|
|
|
|
|
|
|
if (!need_priv_key && !need_pub_key && !need_node_id) { free_config(config); u_free(file_buf); return 0; } |
|
|
|
|
|
|
|
|
|
char cfg_name[16]; snprintf(cfg_name, sizeof(cfg_name), "%s", global->name[0] ? global->name : "utun"); |
|
|
|
|
|
|
|
|
|
free_config(config); |
|
|
|
|
|
|
|
|
|
// ── Modify file buffer in place ──
|
|
|
|
|
size_t buf_capacity = file_size + 1024; |
|
|
|
|
char *work_buf = u_malloc(buf_capacity); |
|
|
|
|
if (!work_buf) { u_free(file_buf); return -1; } |
|
|
|
|
memcpy(work_buf, file_buf, file_size); |
|
|
|
|
u_free(file_buf); |
|
|
|
|
size_t work_len = file_size; |
|
|
|
|
char node_id_hex[HEXNODEID_LEN + 1]; |
|
|
|
|
snprintf(node_id_hex, sizeof(node_id_hex), "%016llx", (unsigned long long)new_node_id); |
|
|
|
|
|
|
|
|
|
// ── Modify/create config buffer ──
|
|
|
|
|
char *work_buf = NULL; size_t work_len = 0; size_t buf_capacity = 0; |
|
|
|
|
int is_new_file = (!file_buf || !file_size); |
|
|
|
|
|
|
|
|
|
if (is_new_file) { |
|
|
|
|
buf_capacity = 2048; |
|
|
|
|
work_buf = u_malloc(buf_capacity); |
|
|
|
|
if (!work_buf) { u_free(file_buf); return -1; } |
|
|
|
|
work_len = (size_t)snprintf(work_buf, buf_capacity, |
|
|
|
|
"[global]\nmy_node_name=%s\nmy_private_key=%s\nmy_public_key=%s\nmy_node_id=%s\n", |
|
|
|
|
cfg_name, new_priv_key, new_pub_key, node_id_hex); |
|
|
|
|
u_free(file_buf); file_buf = NULL; |
|
|
|
|
} else { |
|
|
|
|
buf_capacity = file_size + 1024; |
|
|
|
|
work_buf = u_malloc(buf_capacity); |
|
|
|
|
if (!work_buf) { u_free(file_buf); return -1; } |
|
|
|
|
memcpy(work_buf, file_buf, file_size); |
|
|
|
|
work_len = file_size; |
|
|
|
|
u_free(file_buf); file_buf = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ret = 0; |
|
|
|
|
int write_keys = (need_priv_key || need_pub_key || need_node_id); |
|
|
|
|
|
|
|
|
|
if (need_node_id) { |
|
|
|
|
char node_id_hex[HEXNODEID_LEN + 1]; |
|
|
|
|
snprintf(node_id_hex, sizeof(node_id_hex), "%016llx", (unsigned long long)new_node_id); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Writing my_node_id=%s to %s", node_id_hex, filename); |
|
|
|
|
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_node_id", node_id_hex) < 0) ret = -1; |
|
|
|
|
} |
|
|
|
|
if (write_keys && ret == 0) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Writing my_private_key to %s", filename); |
|
|
|
|
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_private_key", new_priv_key) < 0) ret = -1; |
|
|
|
|
} |
|
|
|
|
if (write_keys && ret == 0) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Writing my_public_key to %s", filename); |
|
|
|
|
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_public_key", new_pub_key) < 0) ret = -1; |
|
|
|
|
if (!is_new_file) { |
|
|
|
|
int write_keys = (need_priv_key || need_pub_key || need_node_id); |
|
|
|
|
|
|
|
|
|
if (need_node_id) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Writing my_node_id=%s to %s", node_id_hex, filename); |
|
|
|
|
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_node_id", node_id_hex) < 0) ret = -1; |
|
|
|
|
} |
|
|
|
|
if (write_keys && ret == 0) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Writing my_private_key to %s", filename); |
|
|
|
|
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_private_key", new_priv_key) < 0) ret = -1; |
|
|
|
|
} |
|
|
|
|
if (write_keys && ret == 0) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Writing my_public_key to %s", filename); |
|
|
|
|
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_public_key", new_pub_key) < 0) ret = -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ret == 0) { |
|
|
|
|
if (ret == 0 && work_buf) { |
|
|
|
|
if (write_mem_to_file(filename, work_buf, work_len) < 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to write updated config file: %s", filename); |
|
|
|
|
ret = -1; |
|
|
|
|
|