diff --git a/src/dns.c b/src/dns.c index 2df3966..69f4787 100644 --- a/src/dns.c +++ b/src/dns.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#define _GNU_SOURCE #include "dns.h" #include "tlog.h" #include diff --git a/src/fast_ping.c b/src/fast_ping.c index 6b23a91..d9b9739 100644 --- a/src/fast_ping.c +++ b/src/fast_ping.c @@ -237,12 +237,26 @@ static void _fast_ping_host_get(struct ping_host_struct *ping_host) atomic_inc(&ping_host->ref); } +static void _fast_ping_close_host_sock(struct ping_host_struct *ping_host) +{ + if (ping_host->fd < 0) { + return; + } + struct epoll_event *event; + event = (struct epoll_event *)1; + epoll_ctl(ping.epoll_fd, EPOLL_CTL_DEL, ping_host->fd, event); + close(ping_host->fd); + ping_host->fd = -1; +} + static void _fast_ping_host_put(struct ping_host_struct *ping_host) { if (!atomic_dec_and_test(&ping_host->ref)) { return; } + _fast_ping_close_host_sock(ping_host); + pthread_mutex_lock(&ping.map_lock); hash_del(&ping_host->addr_node); pthread_mutex_unlock(&ping.map_lock); @@ -254,13 +268,8 @@ static void _fast_ping_host_put(struct ping_host_struct *ping_host) ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_END, &ping_host->addr, ping_host->addr_len, ping_host->seq, &tv, ping_host->userptr); } - if (ping_host->fd > 0) { - close(ping_host->fd); - ping_host->fd = -1; - } tlog(TLOG_DEBUG, "ping %p end", ping_host); - // memset(ping_host, 0, sizeof(*ping_host)); ping_host->type = FAST_PING_END; free(ping_host); @@ -268,12 +277,15 @@ static void _fast_ping_host_put(struct ping_host_struct *ping_host) static void _fast_ping_host_remove(struct ping_host_struct *ping_host) { + _fast_ping_close_host_sock(ping_host); + pthread_mutex_lock(&ping.map_lock); if (!hash_hashed(&ping_host->addr_node)) { pthread_mutex_unlock(&ping.map_lock); return; } hash_del(&ping_host->addr_node); + pthread_mutex_unlock(&ping.map_lock); if (atomic_inc_return(&ping_host->notified) == 1) { @@ -367,6 +379,8 @@ static int _fast_ping_sendping_tcp(struct ping_host_struct *ping_host) int flags; int fd = -1; + _fast_ping_close_host_sock(ping_host); + fd = socket(ping_host->ss_family, SOCK_STREAM, 0); if (fd < 0) { goto errout; @@ -388,23 +402,21 @@ static int _fast_ping_sendping_tcp(struct ping_host_struct *ping_host) } } + ping_host->fd = fd; memset(&event, 0, sizeof(event)); event.events = EPOLLIN | EPOLLOUT; event.data.ptr = ping_host; if (epoll_ctl(ping.epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) { + ping_host->fd = -1; goto errout; } - if (ping_host->fd > 0) { - close(ping_host->fd); - } - ping_host->fd = fd; - return 0; errout: if (fd > 0) { close(fd); + ping_host->fd = -1; } return -1; } @@ -857,20 +869,12 @@ static int _fast_ping_process_tcp(struct ping_host_struct *ping_host, struct epo ping_host->send = 0; - if (ping_host->fd > 0) { - close(ping_host->fd); - ping_host->fd = -1; - } - if (ping_host->count == 1) { _fast_ping_host_remove(ping_host); } return 0; errout: - if (ping_host->fd > 0) { - close(ping_host->fd); - ping_host->fd = -1; - } + _fast_ping_host_remove(ping_host); return -1; } @@ -888,7 +892,7 @@ static int _fast_ping_process(struct ping_host_struct *ping_host, struct epoll_e ret = _fast_ping_process_tcp(ping_host, event, now); break; default: - tlog(TLOG_ERROR, "BUG: type error : %d,", ping_host->type); + tlog(TLOG_ERROR, "BUG: type error : %p, %d, %s, %d", ping_host, ping_host->sid, ping_host->host, ping_host->fd); abort(); break; } @@ -993,37 +997,41 @@ static void *_fast_ping_work(void *arg) struct epoll_event events[PING_MAX_EVENTS + 1]; int num; int i; - struct timeval last = {0}; - struct timeval now = {0}; - struct timeval diff = {0}; - uint millisec = 0; + unsigned long now = {0}; + struct timeval tvnow = {0}; + int sleep = 100; + int sleep_time = 0; + unsigned long expect_time = 0; + sleep_time = sleep; + now = get_tick_count() - sleep; + expect_time = now + sleep; while (ping.run) { - diff = now; - tv_sub(&diff, &last); - millisec = diff.tv_sec * 1000 + diff.tv_usec / 1000; - if (millisec >= 100) { + now = get_tick_count(); + if (now >= expect_time) { _fast_ping_period_run(); - last = now; + sleep_time = sleep - (now - expect_time); + if (sleep_time < 0) { + sleep_time = 0; + } + expect_time += sleep; } - num = epoll_wait(ping.epoll_fd, events, PING_MAX_EVENTS, 100); + num = epoll_wait(ping.epoll_fd, events, PING_MAX_EVENTS, sleep_time); if (num < 0) { - gettimeofday(&now, 0); usleep(100000); continue; } if (num == 0) { - gettimeofday(&now, 0); continue; } - gettimeofday(&now, 0); + gettimeofday(&tvnow, 0); for (i = 0; i < num; i++) { struct epoll_event *event = &events[i]; struct ping_host_struct *ping_host = (struct ping_host_struct *)event->data.ptr; - _fast_ping_process(ping_host, event, &now); + _fast_ping_process(ping_host, event, &tvnow); } } diff --git a/src/smartdns.c b/src/smartdns.c index d9e7015..af849ec 100644 --- a/src/smartdns.c +++ b/src/smartdns.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#define _GNU_SOURCE #include "art.h" #include "atomic.h" #include "conf.h" @@ -175,7 +176,7 @@ int smartdns_init(void) { int ret; - ret = tlog_init(SMARTDNS_LOG_PATH, SMARTDNS_LOG_FILE, 1024 * 1024, 8, 1, 0, 0); + ret = tlog_init(SMARTDNS_LOG_PATH, SMARTDNS_LOG_FILE, 1024 * 512, 8, 1, 0, 0); if (ret != 0) { tlog(TLOG_ERROR, "start tlog failed.\n"); goto errout; @@ -244,7 +245,8 @@ void sig_handle(int sig) default: break; } - tlog(TLOG_ERROR, "process exit.\n"); + tlog(TLOG_ERROR, "process exit with signal %d\n", sig); + sleep(1); _exit(0); } @@ -284,6 +286,11 @@ int main(int argc, char *argv[]) } signal(SIGABRT, sig_handle); + signal(SIGPIPE, sig_handle); + signal(SIGBUS, sig_handle); + signal(SIGSEGV, sig_handle); + signal(SIGILL, sig_handle); + signal(SIGFPE, sig_handle); if (load_conf(config_file) != 0) { } diff --git a/src/tlog.c b/src/tlog.c index 283b329..40f82e9 100644 --- a/src/tlog.c +++ b/src/tlog.c @@ -586,6 +586,47 @@ static void _tlog_wait_pid(int wait_hang) _tlog_log_unlock(); } +static void _tlog_close_all_fd(void) +{ + char path_name[PATH_MAX]; + DIR *dir = NULL; + struct dirent *ent; + + snprintf(path_name, sizeof(path_name), "/proc/self/fd/"); + dir = opendir(path_name); + if (dir == NULL) { + fprintf(stderr, "open directory failed, %s\n", strerror(errno)); + goto errout; + } + + while ((ent = readdir(dir)) != NULL) { + int fd = atoi(ent->d_name); + if (fd < 0 || dirfd(dir) == fd) { + continue; + } + switch (fd) { + case STDIN_FILENO: + case STDOUT_FILENO: + case STDERR_FILENO: + continue; + break; + default: + break; + } + + close(fd); + } + + closedir(dir); + + return; +errout: + if (dir) { + closedir(dir); + } + return; +} + static int _tlog_archive_log(void) { char gzip_file[PATH_MAX]; @@ -621,15 +662,16 @@ static int _tlog_archive_log(void) if (tlog.zip_pid <= 0) { int pid = vfork(); if (pid == 0) { - execl("/bin/sh", "sh", "-c", gzip_cmd, NULL); - _exit(1); + _tlog_close_all_fd(); + execl("/bin/sh", "sh", "-c", gzip_cmd, NULL); + _exit(1); } else if (pid < 0) { goto errout; } tlog.zip_pid = pid; - } + } - return 0; + return 0; errout: _tlog_log_unlock();