HttpDNS/main.c

168 lines
4.5 KiB
C
Raw Permalink Normal View History

2021-06-12 09:50:56 +08:00
#include <dirent.h>
#include <pthread.h>
#include "main.h"
#define SERVICE_TYPE_STOP 1
#define SERVICE_TYPE_STATUS 2
#define SERVICE_TYPE_STATUS_NOT_PRINT 3
struct global global;
uint16_t tcp_listen_port;
struct httpudp udp;
static char *get_proc_name(char *path)
{
char proc_name[257];
FILE *fp;
int readsize;
fp = fopen(path, "r");
if (fp == NULL)
return NULL;
readsize = fread(proc_name, 1, 256, fp);
fclose(fp);
return strndup(proc_name, readsize - 1);
}
static int8_t additional_service(char *self_name, uint8_t service_type)
{
char commpath[270];
DIR *DP;
struct dirent *dp;
char *proc_name;
pid_t self_pid;
DP = opendir("/proc");
if (DP == NULL)
return 1;
proc_name = strrchr(self_name, '/');
if (proc_name)
self_name = proc_name + 1;
self_pid = getpid();
while ((dp = readdir(DP)) != NULL) {
if (dp->d_type != DT_DIR)
continue;
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0 || atoi(dp->d_name) == self_pid)
continue;
sprintf(commpath, "/proc/%s/comm", dp->d_name);
proc_name = get_proc_name(commpath);
if (proc_name == NULL)
continue;
if (strcmp(proc_name, self_name) == 0) {
if (service_type == SERVICE_TYPE_STOP)
kill(atoi(dp->d_name), SIGTERM);
else {
free(proc_name);
closedir(DP);
if (service_type != SERVICE_TYPE_STATUS_NOT_PRINT)
LOG(RED "%s(" VERSION ") 正在运行\n" NONE, self_name);
return 0;
}
}
free(proc_name);
}
closedir(DP);
if (service_type == SERVICE_TYPE_STATUS)
LOG(RED "%s(" VERSION ") 没有运行\n" NONE, self_name);
else if (service_type == SERVICE_TYPE_STATUS_NOT_PRINT)
return 1;
return 0;
}
void *timeout_check(void *nullPtr)
{
while (1) {
sleep(60);
if (global.dns_listen_fd >= 0)
dns_timeout_check();
}
return NULL;
}
/* 初始化变量 */
static void initVariable()
{
memset(&global, 0, sizeof(global));
memset(&httpdns, 0, sizeof(httpdns));
//saveHdrs = NULL;
httpdns.dst.sin_family = AF_INET;
//http.dst.sin_family = https.dst.sin_family = httpdns.dst.sin_family = AF_INET;
global.tcp_listen_fd = global.dns_listen_fd = global.udp_listen_fd = global.uid = -1;
}
static void handle_cmd(int argc, char **argv)
{
/* 命令行选项 */
if (argc < 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
printf(RED "HttpDNS(" VERSION ")\n"
"Author: aixiao@aixiao.me, mmmdbybyd.\n"
"\n"
"启动命令:\n httpdns httpdns.conf\n"
"结束命令:\n httpdns stop\n"
"检测命令:\n httpdns status\n"
"重启命令:\n httpdns restart httpdns.conf\n"
"\n" NONE);
exit(argc < 2 ? 1 : 0);
}
if (strcasecmp(argv[1], "stop") == 0)
exit(additional_service(argv[0], SERVICE_TYPE_STOP));
else if (strcasecmp(argv[1], "status") == 0)
exit(additional_service(argv[0], SERVICE_TYPE_STATUS));
else if (strcasecmp(argv[1], "restart") == 0) {
additional_service(argv[0], SERVICE_TYPE_STOP);
while (additional_service(argv[0], SERVICE_TYPE_STATUS_NOT_PRINT) == 0) ;
argv++;
}
read_conf(argv[1]);
}
static void server_init()
{
/* 忽略PIPE信号 */
signal(SIGPIPE, SIG_IGN);
//不能用setgid和setuid这两个函数不能切换回root可能导致HTTPUDP代理失败
if (global.uid > -1 && (setegid(global.uid) == -1 || seteuid(global.uid) == -1)) {
perror("setegid(or seteuid)");
exit(1);
}
#ifndef DEBUG
if (daemon(1, 1) == -1) {
perror("daemon");
exit(1);
}
#endif
/*
dns缓存
*/
while (global.procs-- > 1 && (child_pid = fork()) == 0) ;
}
static void start_server_loop()
{
pthread_t thread_id;
if (global.timeout_m)
pthread_create(&thread_id, NULL, &timeout_check, NULL);
if (global.dns_listen_fd >= 0) {
dns_init();
dns_loop(NULL);
}
}
int main(int argc, char *argv[])
{
initVariable();
handle_cmd(argc, argv);
server_init();
start_server_loop();
return 0;
}