|
@ -9,8 +9,17 @@ |
|
|
#include "common.h" |
|
|
#include "common.h" |
|
|
#include "exit_code.h" |
|
|
#include "exit_code.h" |
|
|
|
|
|
|
|
|
|
|
|
#ifndef TRUE |
|
|
|
|
|
#define TRUE 1 |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#ifndef FALSE |
|
|
|
|
|
#define FALSE 0 |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
int exiting = 0; |
|
|
int exiting = 0; |
|
|
|
|
|
|
|
|
|
|
|
pid_t custom_pgid = 0; |
|
|
pid_t adguard_pid = 0; |
|
|
pid_t adguard_pid = 0; |
|
|
pid_t overture_pid = 0; |
|
|
pid_t overture_pid = 0; |
|
|
pid_t domestic_dnsproxy_pid = 0; |
|
|
pid_t domestic_dnsproxy_pid = 0; |
|
@ -20,7 +29,7 @@ void get_sub_exit(); |
|
|
void server_daemon(); |
|
|
void server_daemon(); |
|
|
void get_exit_signal(); |
|
|
void get_exit_signal(); |
|
|
void server_exit(int exit_code); |
|
|
void server_exit(int exit_code); |
|
|
pid_t process_exec(char **command); |
|
|
pid_t process_exec(char **command, int is_new_group); |
|
|
void init_server(char *init_script, char *custom_script); |
|
|
void init_server(char *init_script, char *custom_script); |
|
|
|
|
|
|
|
|
void get_exit_signal() { // get SIGINT or SIGTERM signal
|
|
|
void get_exit_signal() { // get SIGINT or SIGTERM signal
|
|
@ -61,6 +70,20 @@ void server_exit(int exit_code) { // kill sub process and exit |
|
|
ret = waitpid(foreign_dnsproxy_pid, &status, 0); // blocking
|
|
|
ret = waitpid(foreign_dnsproxy_pid, &status, 0); // blocking
|
|
|
fprintf(stderr, "[ClearDNS] foreign dnsproxy exit. (pid = %d)\n", ret); |
|
|
fprintf(stderr, "[ClearDNS] foreign dnsproxy exit. (pid = %d)\n", ret); |
|
|
|
|
|
|
|
|
|
|
|
if (custom_pgid != 0) { |
|
|
|
|
|
ret = waitpid(-custom_pgid, &status, WNOHANG); |
|
|
|
|
|
if (ret == 0) { // custom script still running
|
|
|
|
|
|
fprintf(stderr, "[ClearDNS] Kill custom script.\n"); |
|
|
|
|
|
kill(-custom_pgid, SIGTERM); // kill process group
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "[ClearDNS] Kill all subprocess.\n"); |
|
|
|
|
|
kill(-1, SIGTERM); // send kill signal to all process
|
|
|
|
|
|
while ((ret = wait(&status)) != -1) { |
|
|
|
|
|
fprintf(stderr, "[ClearDNS] Subprocess exit. (pid = %d)\n", ret); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
fprintf(stderr, "[ClearDNS] Exit successfully.\n"); |
|
|
fprintf(stderr, "[ClearDNS] Exit successfully.\n"); |
|
|
exit(exit_code); |
|
|
exit(exit_code); |
|
|
} |
|
|
} |
|
@ -76,7 +99,7 @@ void get_sub_exit() { // catch child process exit |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
} else if (ret) { // process exit
|
|
|
} else if (ret) { // process exit
|
|
|
adguard_pid = process_exec(adguard_command); |
|
|
adguard_pid = process_exec(adguard_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Catch AdGuardHome exit and restart it. (pid = %d -> %d)\n", ret, adguard_pid); |
|
|
fprintf(stderr, "[ClearDNS] Catch AdGuardHome exit and restart it. (pid = %d -> %d)\n", ret, adguard_pid); |
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
return; |
|
|
return; |
|
@ -89,7 +112,7 @@ void get_sub_exit() { // catch child process exit |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
} else if (ret) { // process exit
|
|
|
} else if (ret) { // process exit
|
|
|
overture_pid = process_exec(overture_command); |
|
|
overture_pid = process_exec(overture_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Catch overture exit and restart it. (pid = %d -> %d)\n", ret, overture_pid); |
|
|
fprintf(stderr, "[ClearDNS] Catch overture exit and restart it. (pid = %d -> %d)\n", ret, overture_pid); |
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
return; |
|
|
return; |
|
@ -102,7 +125,7 @@ void get_sub_exit() { // catch child process exit |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
} else if (ret) { // process exit
|
|
|
} else if (ret) { // process exit
|
|
|
domestic_dnsproxy_pid = process_exec(domestic_dnsproxy_command); |
|
|
domestic_dnsproxy_pid = process_exec(domestic_dnsproxy_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Catch domestic dnsproxy exit and restart it. (pid = %d -> %d)\n", ret, domestic_dnsproxy_pid); |
|
|
fprintf(stderr, "[ClearDNS] Catch domestic dnsproxy exit and restart it. (pid = %d -> %d)\n", ret, domestic_dnsproxy_pid); |
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
return; |
|
|
return; |
|
@ -115,7 +138,7 @@ void get_sub_exit() { // catch child process exit |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
perror("[ClearDNS] Waitpid error"); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
server_exit(EXIT_WAIT_ERROR); |
|
|
} else if (ret) { // process exit
|
|
|
} else if (ret) { // process exit
|
|
|
foreign_dnsproxy_pid = process_exec(foreign_dnsproxy_command); |
|
|
foreign_dnsproxy_pid = process_exec(foreign_dnsproxy_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Catch foreign dnsproxy exit and restart it. (pid = %d -> %d)\n", ret, foreign_dnsproxy_pid); |
|
|
fprintf(stderr, "[ClearDNS] Catch foreign dnsproxy exit and restart it. (pid = %d -> %d)\n", ret, foreign_dnsproxy_pid); |
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
sleep(wait_time); // reduce restart frequency
|
|
|
return; |
|
|
return; |
|
@ -133,13 +156,14 @@ void get_sub_exit() { // catch child process exit |
|
|
fprintf(stderr, "[ClearDNS] Subprocess not found.\n"); // get SIGCHLD signal but not exited subprocess found
|
|
|
fprintf(stderr, "[ClearDNS] Subprocess not found.\n"); // get SIGCHLD signal but not exited subprocess found
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
pid_t process_exec(char **command) { |
|
|
pid_t process_exec(char **command, int is_new_group) { |
|
|
pid_t pid; |
|
|
pid_t pid; |
|
|
char **env = {NULL}; |
|
|
char **env = {NULL}; |
|
|
if ((pid = fork()) < 0) { |
|
|
if ((pid = fork()) < 0) { |
|
|
perror("[ClearDNS] Fork error"); |
|
|
perror("[ClearDNS] Fork error"); |
|
|
server_exit(EXIT_FORK_ERROR); |
|
|
server_exit(EXIT_FORK_ERROR); |
|
|
} else if (pid == 0) { // child process
|
|
|
} else if (pid == 0) { // child process
|
|
|
|
|
|
if (is_new_group) { setpgrp(); } // new process group
|
|
|
prctl(PR_SET_PDEATHSIG, SIGKILL); // child process die with father process
|
|
|
prctl(PR_SET_PDEATHSIG, SIGKILL); // child process die with father process
|
|
|
if (execvpe(command[0], command, env) < 0) { |
|
|
if (execvpe(command[0], command, env) < 0) { |
|
|
perror("[ClearDNS] Exec error"); |
|
|
perror("[ClearDNS] Exec error"); |
|
@ -156,7 +180,7 @@ void init_server(char *init_script, char *custom_script) { // run init script (b |
|
|
char *custom_command[] = {"sh", custom_script, NULL}; |
|
|
char *custom_command[] = {"sh", custom_script, NULL}; |
|
|
|
|
|
|
|
|
fprintf(stderr, "[ClearDNS] Start init process.\n"); |
|
|
fprintf(stderr, "[ClearDNS] Start init process.\n"); |
|
|
pid = process_exec(init_command); |
|
|
pid = process_exec(init_command, FALSE); |
|
|
wait(&status); // blocking wait
|
|
|
wait(&status); // blocking wait
|
|
|
fprintf(stderr, "[ClearDNS] Init complete. (pid = %d)\n", pid); // init process
|
|
|
fprintf(stderr, "[ClearDNS] Init complete. (pid = %d)\n", pid); // init process
|
|
|
|
|
|
|
|
@ -164,32 +188,32 @@ void init_server(char *init_script, char *custom_script) { // run init script (b |
|
|
signal(SIGTERM, get_exit_signal); // catch exit signal (15)
|
|
|
signal(SIGTERM, get_exit_signal); // catch exit signal (15)
|
|
|
signal(SIGCHLD, get_sub_exit); // callback when child process die
|
|
|
signal(SIGCHLD, get_sub_exit); // callback when child process die
|
|
|
|
|
|
|
|
|
pid = process_exec(crond_command); |
|
|
pid = process_exec(crond_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Crond load success. (pid = %d)\n", pid); // crond process
|
|
|
fprintf(stderr, "[ClearDNS] Crond load success. (pid = %d)\n", pid); // crond process
|
|
|
|
|
|
|
|
|
if (access(custom_script, F_OK) >= 0) { // custom script exist
|
|
|
if (access(custom_script, F_OK) >= 0) { // custom script exist
|
|
|
pid = process_exec(custom_command); |
|
|
custom_pgid = process_exec(custom_command, TRUE); |
|
|
fprintf(stderr, "[ClearDNS] Custom script is working. (pid = %d)\n", pid); // custom process
|
|
|
fprintf(stderr, "[ClearDNS] Custom script is working. (pgid = %d)\n", custom_pgid); // custom process
|
|
|
sleep(1); // wait a moment
|
|
|
usleep(200000); // wait a moment (200ms)
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void server_daemon() { // run as a daemon of ClearDNS
|
|
|
void server_daemon() { // run as a daemon of ClearDNS
|
|
|
int wait_us_time = 100000; // 100ms
|
|
|
int wait_us_time = 200000; // 200ms
|
|
|
|
|
|
|
|
|
adguard_pid = process_exec(adguard_command); |
|
|
adguard_pid = process_exec(adguard_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Exec AdGuardHome. (pid = %d)\n", adguard_pid); |
|
|
fprintf(stderr, "[ClearDNS] Exec AdGuardHome. (pid = %d)\n", adguard_pid); |
|
|
usleep(wait_us_time); |
|
|
usleep(wait_us_time); |
|
|
|
|
|
|
|
|
overture_pid = process_exec(overture_command); |
|
|
overture_pid = process_exec(overture_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Exec overture. (pid = %d)\n", overture_pid); |
|
|
fprintf(stderr, "[ClearDNS] Exec overture. (pid = %d)\n", overture_pid); |
|
|
usleep(wait_us_time); |
|
|
usleep(wait_us_time); |
|
|
|
|
|
|
|
|
domestic_dnsproxy_pid = process_exec(domestic_dnsproxy_command); |
|
|
domestic_dnsproxy_pid = process_exec(domestic_dnsproxy_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Exec domestic dnsproxy. (pid = %d)\n", domestic_dnsproxy_pid); |
|
|
fprintf(stderr, "[ClearDNS] Exec domestic dnsproxy. (pid = %d)\n", domestic_dnsproxy_pid); |
|
|
usleep(wait_us_time); |
|
|
usleep(wait_us_time); |
|
|
|
|
|
|
|
|
foreign_dnsproxy_pid = process_exec(foreign_dnsproxy_command); |
|
|
foreign_dnsproxy_pid = process_exec(foreign_dnsproxy_command, FALSE); |
|
|
fprintf(stderr, "[ClearDNS] Exec foreign dnsproxy. (pid = %d)\n", foreign_dnsproxy_pid); |
|
|
fprintf(stderr, "[ClearDNS] Exec foreign dnsproxy. (pid = %d)\n", foreign_dnsproxy_pid); |
|
|
usleep(wait_us_time); |
|
|
usleep(wait_us_time); |
|
|
|
|
|
|
|
|