From e89161b52b0109756acc82e58c1c4cbc106adb42 Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Sun, 4 Sep 2022 17:47:30 +0800 Subject: [PATCH] update: utils refactor --- include/common.h | 2 +- include/sip003.h | 1 + include/utils/dns.h | 2 +- include/utils/logger.h | 1 + include/utils/network.h | 2 +- include/utils/process.h | 10 +- src/local.c | 5 +- src/sip003.c | 1 + src/utils/CMakeLists.txt | 2 + src/utils/dns.c | 16 +-- src/utils/logger.c | 12 +++ src/utils/network.c | 21 ++-- src/utils/process.c | 219 +++++++++++++++++++-------------------- 13 files changed, 151 insertions(+), 143 deletions(-) diff --git a/include/common.h b/include/common.h index c0d77af..fa0bb9e 100644 --- a/include/common.h +++ b/include/common.h @@ -1,7 +1,7 @@ #ifndef _COMMON_H_ #define _COMMON_H_ -#define VERSION "0.9.2" +#define VERSION "0.9.3" #define RANDOM_PORT_START 41952 #define RANDOM_PORT_END 65535 diff --git a/include/sip003.h b/include/sip003.h index 46aa2b5..21eadfc 100644 --- a/include/sip003.h +++ b/include/sip003.h @@ -11,6 +11,7 @@ typedef struct { char *SS_PLUGIN_OPTIONS; char *plugin_file; char **shadowsocks_cmd; + int is_udp_proxy; } sip003; sip003* load_sip003(char *ss_default, bootstrap *info); diff --git a/include/utils/dns.h b/include/utils/dns.h index d816263..8fe0c47 100644 --- a/include/utils/dns.h +++ b/include/utils/dns.h @@ -1,6 +1,6 @@ #ifndef _DNS_H_ #define _DNS_H_ -char* dns_resolve(char *domain); +char* dns_resolve(const char *domain); #endif diff --git a/include/utils/logger.h b/include/utils/logger.h index 2c08be1..a555e41 100644 --- a/include/utils/logger.h +++ b/include/utils/logger.h @@ -20,6 +20,7 @@ enum { #define log_fatal(...) log_printf(LOG_FATAL, __VA_ARGS__) extern int LOG_LEVEL; +void log_perror(char *prefix); void log_printf(int level, const char *fmt, ...); #endif diff --git a/include/utils/network.h b/include/utils/network.h index 1699a5d..0f542d6 100644 --- a/include/utils/network.h +++ b/include/utils/network.h @@ -1,7 +1,7 @@ #ifndef _NETWORK_H_ #define _NETWORK_H_ -extern int proxy_exit; +extern int PROXY_EXIT; int is_ip_addr(char *address); int get_available_port(unsigned short range_start, unsigned short range_end); diff --git a/include/utils/process.h b/include/utils/process.h index 94ff6c5..11baedf 100644 --- a/include/utils/process.h +++ b/include/utils/process.h @@ -1,14 +1,8 @@ #ifndef _PROCESS_H_ #define _PROCESS_H_ -extern char **shadowsocks_args; -extern char *plugin_file; -extern char *SS_REMOTE_HOST; -extern char *SS_REMOTE_PORT; -extern char *SS_LOCAL_HOST; -extern char *SS_LOCAL_PORT; -extern char *SS_PLUGIN_OPTIONS; +#include "sip003.h" -void start_bootstrap(char *ss_type, int is_udp_proxy); +void start_bootstrap(int local_mode, sip003 *service); #endif diff --git a/src/local.c b/src/local.c index 4f0fe6f..14a305f 100644 --- a/src/local.c +++ b/src/local.c @@ -32,9 +32,6 @@ int main(int argc, char *argv[]) { init(argc, argv, help_msg); log_info("Shadowsocks bootstrap local (%s)", VERSION); bootstrap *info = load_info(argc, argv); - load_sip003("sslocal", info); - -// start_bootstrap("sslocal", is_udp_proxy); // local or server mode - + start_bootstrap(1, load_sip003("sslocal", info)); return 0; } diff --git a/src/sip003.c b/src/sip003.c index eac6469..74d4de2 100644 --- a/src/sip003.c +++ b/src/sip003.c @@ -38,6 +38,7 @@ sip003* load_sip003(char *ss_default, bootstrap *info) { // load shadowsocks and info->shadowsocks_opts[0] = info->shadowsocks; // fill with file name service->plugin_file = NULL; + service->is_udp_proxy = info->is_udp_proxy; if (info->plugin != NULL) { // with sip003 plugin char *rand_port = int_to_string(get_available_port(RANDOM_PORT_START, RANDOM_PORT_END)); service->SS_REMOTE_HOST = info->server_addr; diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 1a5b281..dcb9334 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -1,2 +1,4 @@ +cmake_minimum_required(VERSION 2.8.12) + aux_source_directory(. utils_src) add_library(utils ${utils_src}) diff --git a/src/utils/dns.c b/src/utils/dns.c index 5c5945d..9c991c4 100644 --- a/src/utils/dns.c +++ b/src/utils/dns.c @@ -1,17 +1,17 @@ -#include #include #include #include #include #include #include +#include "logger.h" #include "dns.h" char** init_dns_result(); char** add_dns_result(char **dns_result, char *str); void free_dns_result(char **dns_result); -char** ipv4_dns_resolve(char *domain); -char** ipv6_dns_resolve(char *domain); +char** ipv4_dns_resolve(const char *domain); +char** ipv6_dns_resolve(const char *domain); char** init_dns_result() { // 初始化DNS解析存储结构 char **dns_result = (char**)malloc(sizeof(char*)); @@ -35,7 +35,7 @@ void free_dns_result(char **dns_result) { // 释放DNS解析结果 } } -char** ipv4_dns_resolve(char *domain) { // DNS解析IPv4地址 +char** ipv4_dns_resolve(const char *domain) { // DNS解析IPv4地址 char **result = init_dns_result(); char ip_str[16]; // IPv4地址字符串 (3 * 4 + 1 * 3 + 1) struct sockaddr_in *ipv4_addr; @@ -45,7 +45,7 @@ char** ipv4_dns_resolve(char *domain) { // DNS解析IPv4地址 hint.ai_socktype = SOCK_STREAM; int ret = getaddrinfo(domain, NULL, &hint, &answer); // 发起解析 if (ret != 0) { // 解析失败 - printf("[Shadowsocks Bootstrap] IPv4 DNS resolve `%s`: %s\n", domain, gai_strerror(ret)); + log_debug("IPv4 DNS resolve `%s`: %s", domain, gai_strerror(ret)); return result; // 返回空数据 } for (p = answer; p != NULL; p = p->ai_next) { // 遍历解析结果 @@ -57,7 +57,7 @@ char** ipv4_dns_resolve(char *domain) { // DNS解析IPv4地址 return result; } -char** ipv6_dns_resolve(char *domain) { // DNS解析IPv6地址 +char** ipv6_dns_resolve(const char *domain) { // DNS解析IPv6地址 char **result = init_dns_result(); char ip_str[40]; // IPv6地址字符串 (4 * 8 + 1 * 7 + 1) struct sockaddr_in6 *ipv6_addr; @@ -67,7 +67,7 @@ char** ipv6_dns_resolve(char *domain) { // DNS解析IPv6地址 hint.ai_socktype = SOCK_STREAM; int ret = getaddrinfo(domain, NULL, &hint, &answer); // 发起解析 if (ret != 0) { // 解析失败 - printf("[Shadowsocks Bootstrap] IPv6 DNS resolve `%s`: %s\n", domain, gai_strerror(ret)); + log_debug("IPv6 DNS resolve `%s`: %s", domain, gai_strerror(ret)); return result; // 返回空数据 } for (p = answer; p != NULL; p = p->ai_next) { // 遍历解析结果 @@ -79,7 +79,7 @@ char** ipv6_dns_resolve(char *domain) { // DNS解析IPv6地址 return result; } -char* dns_resolve(char *domain) { // DNS解析 返回首个IP地址 IPv4优先 +char* dns_resolve(const char *domain) { // DNS解析 返回首个IP地址 IPv4优先 int num = 0; char **result = ipv4_dns_resolve(domain); // IPv4解析 while(result[num++] != NULL); // num - 1 为IPv4地址数 diff --git a/src/utils/logger.c b/src/utils/logger.c index 57fcd81..ef4ea45 100644 --- a/src/utils/logger.c +++ b/src/utils/logger.c @@ -40,3 +40,15 @@ void log_printf(int level, const char *fmt, ...) { exit(1); } } + +void log_perror(char *prefix) { + time_t t; + time(&t); + struct tm *lt = localtime(&t); + fprintf(stderr, "\x1b[36m[Bootstrap]\x1b[0m "); + fprintf(stderr, "\x1b[90m%04d-%02d-%02d %02d:%02d:%02d\x1b[0m", + lt->tm_year + 1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec); + fprintf(stderr, " %s%s\x1b[0m ", log_color[3], log_string[3]); // error level + fflush(stderr); + perror(prefix); +} diff --git a/src/utils/network.c b/src/utils/network.c index f7541d8..28f8259 100644 --- a/src/utils/network.c +++ b/src/utils/network.c @@ -7,11 +7,12 @@ #include #include #include "network.h" +#include "logger.h" #define TIMEOUT 15 #define BUFFER_SIZE 4096 -int proxy_exit; +int PROXY_EXIT; int get_random_num(int range_start, int range_end); int check_port_available(unsigned int port, int is_udp, int is_ipv6); @@ -256,12 +257,12 @@ void ipv4_proxy(void *ipv4_info) { // 代理IPv4客户端 char *recv_buffer = (char*)malloc(BUFFER_SIZE); // 申请接收缓冲区内存 long recv_len = send_and_receive(info->server_ip, info->server_port, info->buffer, info->len, recv_buffer); // 服务端交互 if (recv_len < 0) { // 服务端超时 - printf("[Shadowsocks Bootstrap] UDP Proxy: server return timeout\n"); + log_warn("UDP Proxy: server return timeout"); } else { if (sendto(info->ipv4_client_fd, recv_buffer, recv_len, 0, (struct sockaddr*)&(info->ipv4_client_addr), sizeof(info->ipv4_client_addr)) < 0) { // 服务端数据返回给客户端 perror("[Shadowsocks Bootstrap] IPv4 UDP return failed"); } else { - printf("[Shadowsocks Bootstrap] UDP Proxy: ↑ %ld bytes ↓ %ld bytes\n", info->len, recv_len); + log_info("UDP Proxy: ↑ %ld bytes ↓ %ld bytes", info->len, recv_len); } } free(recv_buffer); // 释放接收缓冲区内存 @@ -274,12 +275,12 @@ void ipv6_proxy(void *ipv6_info) { // 代理IPv6客户端 char *recv_buffer = (char*)malloc(BUFFER_SIZE); // 申请接收缓冲区内存 long recv_len = send_and_receive(info->server_ip, info->server_port, info->buffer, info->len, recv_buffer); // 服务端交互 if (recv_len < 0) { // 服务端超时 - printf("[Shadowsocks Bootstrap] Server return timeout\n"); + log_warn("UDP Proxy: Server return timeout"); } else { if (sendto(info->ipv6_client_fd, recv_buffer, recv_len, 0, (struct sockaddr*)&(info->ipv6_client_addr), sizeof(info->ipv6_client_addr)) < 0) { // 服务端数据返回给客户端 perror("[Shadowsocks Bootstrap] IPv6 UDP return failed"); } else { - printf("[Shadowsocks Bootstrap] UDP Proxy: ↑ %ld bytes ↓ %ld bytes\n", info->len, recv_len); + log_info("UDP Proxy: ↑ %ld bytes ↓ %ld bytes", info->len, recv_len); } } free(recv_buffer); // 释放接收缓冲区内存 @@ -310,12 +311,12 @@ void proxy(char *server_ip, int server_port, char *listen_ip, int listen_port) { } } if (bind_error_flag) { // 端口被占用 - printf("[Shadowsocks Bootstrap] The UDP port seems to be occupied by the SIP003 plugin\n"); - printf("[Shadowsocks Bootstrap] WARNING: UDP communication of the agent will not work properly\n"); + log_warn("The UDP port seems to be occupied by the SIP003 plugin"); + log_warn("UDP communication of the agent will not work properly"); return; } - proxy_exit = 0; // 重置退出标识 - printf("[Shadowsocks Bootstrap] UDP Proxy: %s:%d -> %s:%d\n", listen_ip, listen_port, server_ip, server_port); + PROXY_EXIT = 0; // 重置退出标识 + log_info("UDP Proxy: %s:%d -> %s:%d", listen_ip, listen_port, server_ip, server_port); for (;;) { if (!is_listen_ipv6) { // IPv4客户端 recv_len = recvfrom(ipv4_client_fd, recv_buffer, BUFFER_SIZE, 0, (struct sockaddr*)&ipv4_client_addr, &ipv4_client_addr_len); @@ -342,7 +343,7 @@ void proxy(char *server_ip, int server_port, char *listen_ip, int listen_port) { info->len = recv_len; pthread_create(&tid, NULL, (void*)ipv6_proxy, (void*)info); // 新线程代理请求 } - if (proxy_exit) { + if (PROXY_EXIT) { break; // 退出代理 } } diff --git a/src/utils/process.c b/src/utils/process.c index dda5775..1f306a9 100644 --- a/src/utils/process.c +++ b/src/utils/process.c @@ -1,52 +1,56 @@ -#include -#include #include +#include + +#include #include #include #include #include "network.h" #include "process.h" +#include "logger.h" #include "dns.h" -char **shadowsocks_args; -char *plugin_file; -char *SS_REMOTE_HOST; -char *SS_REMOTE_PORT; -char *SS_LOCAL_HOST; -char *SS_LOCAL_PORT; -char *SS_PLUGIN_OPTIONS; - -char **plugin_env; -char *plugin_arg[] = { NULL, NULL }; - -int exiting = 0; -int exit_complete = 0; - -typedef struct exit_info { +typedef struct { int pid; int exit_code; int exit_signal; } exit_info; -//GMainLoop* main_loop; +char *plugin; pid_t ss_pid = 0, plugin_pid = 0; +int exiting = 0; // sub process exiting +int exited = 0; // all sub process exited + +//void process_exec(); +//void get_sub_exit(); +//void exit_with_child(); +//void plugin_env_load(); +//void show_exit_info(exit_info info); +//exit_info get_exit_info(int status, pid_t pid); + +void error_exit(); +void normal_exit(); +void kill_sub_process(); + +void normal_exit() { // exit normally + kill_sub_process(); + log_info("Exit complete"); + exit(0); +} -void show_params(); -void process_exec(); -void get_sub_exit(); -void exit_with_child(); -void plugin_env_load(); -void show_exit_info(exit_info info); -exit_info get_exit_info(int status, pid_t pid); +void error_exit() { // exit with error + kill_sub_process(); + log_info("Exit with error"); + exit(1); +} -void show_exit_info(exit_info info) { // show info of child process death - printf("(PID = %d) -> ", info.pid); +void show_exit_info(exit_info info, char *prefix) { // show info of child process death if (info.exit_code != -1) { // exit normally - printf("exit code %d.\n", info.exit_code); + log_warn("%s (PID = %d) -> exit code %d", prefix, info.pid, info.exit_code); } else if (info.exit_signal != -1) { // abnormal exit - printf("killed by signal %d.\n", info.exit_signal); + log_warn("%s (PID = %d) -> killed by signal %d", prefix, info.pid, info.exit_signal); } else { - printf("unknown reason.\n"); + log_warn("%s (PID = %d) -> unknown reason", prefix, info.pid); } } @@ -63,6 +67,25 @@ exit_info get_exit_info(int status, pid_t pid) { // get why the child process de return temp; } +void kill_sub_process() { // kill child process + while (exiting) { + sleep(1); // exit process already working -> block + } + exiting = 1; // exit process flag + PROXY_EXIT = 1; // udp proxy cancel + if (ss_pid != 0) { + kill(ss_pid, SIGKILL); + log_info("Kill shadowsocks process"); + } + if (plugin != NULL && plugin_pid != 0) { + kill(plugin_pid, SIGKILL); + log_info("Kill plugin process"); + } + int status; + log_info("Wait child process exit"); + waitpid(0, &status, 0); // block wait +} + void get_sub_exit() { // catch child process die exit_info sub_exit_info; int ss_ret, plugin_ret, ss_status, plugin_status; @@ -75,67 +98,68 @@ void get_sub_exit() { // catch child process die ss_ret = waitpid(ss_pid, &ss_status, WNOHANG); // non-blocking if (ss_ret == -1) { perror("[Shadowsocks Bootstrap] shadowsocks waitpid error"); - exit_with_child(); + error_exit(); } else if (ss_ret) { // ss exit sub_exit_info = get_exit_info(ss_status, ss_pid); - printf("[Shadowsocks Bootstrap] shadowsocks exit "); - show_exit_info(sub_exit_info); - exit_with_child(); + show_exit_info(sub_exit_info, "Shadowsocks exit"); + error_exit(); } } - if (plugin_file != NULL && plugin_pid != 0) { // with plugin + if (plugin != NULL && plugin_pid != 0) { // with plugin plugin_ret = waitpid(plugin_pid, &plugin_status, WNOHANG); // non-blocking if (plugin_ret == -1) { perror("[Shadowsocks Bootstrap] plugin waitpid error"); - exit_with_child(); + error_exit(); } else if (plugin_ret) { // plugin exit sub_exit_info = get_exit_info(plugin_status, plugin_pid); - printf("[Shadowsocks Bootstrap] plugin exit "); - show_exit_info(sub_exit_info); - exit_with_child(); + show_exit_info(sub_exit_info, "Plugin exit"); + error_exit(); } } -// g_main_loop_quit(main_loop); // exit main loop - exit_complete = 1; + exited = 1; } -void plugin_env_load() { // load plugin's environment variable +char** plugin_env_load(sip003 *service) { // load plugin's environment variable char *remote_host = "SS_REMOTE_HOST="; char *remote_port = "SS_REMOTE_PORT="; char *local_host = "SS_LOCAL_HOST="; char *local_port = "SS_LOCAL_PORT="; char *plugin_options = "SS_PLUGIN_OPTIONS="; - plugin_env = (char**)malloc(sizeof(char*) * 6); - plugin_env[0] = (char*)malloc(strlen(remote_host) + strlen(SS_REMOTE_HOST) + 1); - plugin_env[1] = (char*)malloc(strlen(remote_port) + strlen(SS_REMOTE_PORT) + 1); - plugin_env[2] = (char*)malloc(strlen(local_host) + strlen(SS_LOCAL_HOST) + 1); - plugin_env[3] = (char*)malloc(strlen(local_port) + strlen(SS_LOCAL_PORT) + 1); - strcat(strcpy(plugin_env[0], remote_host), SS_REMOTE_HOST); - strcat(strcpy(plugin_env[1], remote_port), SS_REMOTE_PORT); - strcat(strcpy(plugin_env[2], local_host), SS_LOCAL_HOST); - strcat(strcpy(plugin_env[3], local_port), SS_LOCAL_PORT); - if (SS_PLUGIN_OPTIONS == NULL) { + char **plugin_env = (char**)malloc(sizeof(char*) * 6); + plugin_env[0] = (char*)malloc(strlen(remote_host) + strlen(service->SS_REMOTE_HOST) + 1); + plugin_env[1] = (char*)malloc(strlen(remote_port) + strlen(service->SS_REMOTE_PORT) + 1); + plugin_env[2] = (char*)malloc(strlen(local_host) + strlen(service->SS_LOCAL_HOST) + 1); + plugin_env[3] = (char*)malloc(strlen(local_port) + strlen(service->SS_LOCAL_PORT) + 1); + strcat(strcpy(plugin_env[0], remote_host), service->SS_REMOTE_HOST); + strcat(strcpy(plugin_env[1], remote_port), service->SS_REMOTE_PORT); + strcat(strcpy(plugin_env[2], local_host), service->SS_LOCAL_HOST); + strcat(strcpy(plugin_env[3], local_port), service->SS_LOCAL_PORT); + if (service->SS_PLUGIN_OPTIONS == NULL) { plugin_env[4] = NULL; } else { - plugin_env[4] = (char*)malloc(strlen(plugin_options) + strlen(SS_PLUGIN_OPTIONS) + 1); - strcat(strcpy(plugin_env[4], plugin_options), SS_PLUGIN_OPTIONS); + plugin_env[4] = (char*)malloc(strlen(plugin_options) + strlen(service->SS_PLUGIN_OPTIONS) + 1); + strcat(strcpy(plugin_env[4], plugin_options), service->SS_PLUGIN_OPTIONS); } plugin_env[5] = NULL; - plugin_arg[0] = plugin_file; + return plugin_env; } -void process_exec() { // run shadowsocks main process and plugin (as child process) +void process_exec(sip003 *service) { // run shadowsocks main process and plugin if ((ss_pid = fork()) < 0) { perror("[Shadowsocks Bootstrap] fork error"); - exit_with_child(); + error_exit(); } else if (ss_pid == 0) { // child process prctl(PR_SET_PDEATHSIG, SIGKILL); // child die with his father - if (execvp(shadowsocks_args[0], shadowsocks_args) < 0) { - perror("[Shadowsocks Bootstrap] shadowsocks exec error"); + if (execvp(service->shadowsocks_cmd[0], service->shadowsocks_cmd) < 0) { + + log_perror("Shadowsocks exec error"); + +// perror("[Shadowsocks Bootstrap] shadowsocks exec error"); exit(2); } } - if (plugin_file == NULL) { // plugin no need + plugin = service->plugin_file; + if (plugin == NULL) { // plugin no need return; } usleep(100 * 1000); // sleep 100ms (python always a little slower) @@ -144,77 +168,52 @@ void process_exec() { // run shadowsocks main process and plugin (as child proce } if ((plugin_pid = fork()) < 0) { perror("[Shadowsocks Bootstrap] fork error"); - exit_with_child(); + error_exit(); } else if (plugin_pid == 0) { // child process prctl(PR_SET_PDEATHSIG, SIGKILL); // child die with his father - plugin_env_load(); - if (execvpe(plugin_file, plugin_arg, plugin_env) < 0) { + char **plugin_env = plugin_env_load(service); + char *plugin_arg[] = { plugin, NULL }; + if (execvpe(plugin, plugin_arg, plugin_env) < 0) { perror("[Shadowsocks Bootstrap] plugin exec error"); exit(2); } } } -void exit_with_child() { // exit and kill his child process - while (exiting) { - sleep(1); // block - } - exiting = 1; - proxy_exit = 1; - if (ss_pid != 0) { - kill(ss_pid, SIGKILL); - printf("[Shadowsocks Bootstrap] kill shadowsocks process.\n"); - } - if (plugin_file != NULL && plugin_pid != 0) { - kill(plugin_pid, SIGKILL); - printf("[Shadowsocks Bootstrap] kill plugin process.\n"); - } - int status; - printf("[Shadowsocks Bootstrap] wait for child process.\n"); - waitpid(0, &status, 0); // block - printf("[Shadowsocks Bootstrap] exit.\n"); - exit(1); -} - - - -void start_bootstrap(char *ss_type, int is_udp_proxy) { // start shadowsocks and plugin (optional) - show_params(); -// main_loop = g_main_loop_new(NULL, FALSE); - signal(SIGINT, exit_with_child); // catch Ctrl + C (2) - signal(SIGTERM, exit_with_child); // catch exit signal (15) +void start_bootstrap(int local_mode, sip003 *service) { // start shadowsocks (and plugin) + log_info("Start shadowsocks bootstrap"); + signal(SIGINT, normal_exit); // catch Ctrl + C (2) + signal(SIGTERM, normal_exit); // catch exit signal (15) signal(SIGCHLD, get_sub_exit); // callback when child process die - process_exec(); // exec child process - if (plugin_file != NULL && is_udp_proxy) { // start udp proxy when using plugin + process_exec(service); // exec child process + + if (service->plugin_file == NULL || !service->is_udp_proxy) { // start udp proxy when using plugin + log_info("UDP Proxy no need"); + } else { char *remote_ip; - if (is_ip_addr(SS_REMOTE_HOST)) { // remote_host -> ip address - remote_ip = SS_REMOTE_HOST; + if (is_ip_addr(service->SS_REMOTE_HOST)) { // remote_host -> ip address + remote_ip = service->SS_REMOTE_HOST; } else { // remote_host -> domain - printf("[Shadowsocks Bootstrap] DNS Resolve: %s\n", SS_REMOTE_HOST); - remote_ip = dns_resolve(SS_REMOTE_HOST); // dns resolve + log_info("DNS Resolve: %s", service->SS_REMOTE_HOST); + remote_ip = dns_resolve(service->SS_REMOTE_HOST); // dns resolve if (remote_ip == NULL) { // no result - printf("[Shadowsocks Bootstrap] DNS record not found.\n"); + log_warn("DNS record not found"); } else { // dns resolve success - printf("[Shadowsocks Bootstrap] %s => %s\n", SS_REMOTE_HOST, remote_ip); + log_info("%s => %s", service->SS_REMOTE_HOST, remote_ip); } } if (remote_ip == NULL) { // resolve error - printf("[Shadowsocks Bootstrap] Skip UDP Proxy.\n"); + log_warn("Skip UDP Proxy"); } else { // udp proxy - if (!strcmp(ss_type, "sslocal")) { // local mode - proxy(remote_ip, atoi(SS_REMOTE_PORT), SS_LOCAL_HOST, atoi(SS_LOCAL_PORT)); // NOLINT + if (local_mode) { // local mode + proxy(remote_ip, atoi(service->SS_REMOTE_PORT), service->SS_LOCAL_HOST, atoi(service->SS_LOCAL_PORT)); // NOLINT } else { // server mode - proxy(SS_LOCAL_HOST, atoi(SS_LOCAL_PORT), remote_ip, atoi(SS_REMOTE_PORT)); // NOLINT + proxy(service->SS_LOCAL_HOST, atoi(service->SS_LOCAL_PORT), remote_ip, atoi(service->SS_REMOTE_PORT)); // NOLINT } } - } else { - printf("[Shadowsocks Bootstrap] UDP Proxy no need.\n"); } - - while (!exit_complete) { + while (!exited) { pause(); - printf("!!! get signal !!!\n"); } - - exit_with_child(); + normal_exit(); }