Compare commits

...

6 Commits

Author SHA1 Message Date
Nick Peng
2ca4c92c9f dns-client: allow same upstream server with different proxy. 2023-02-22 21:55:07 +08:00
Nick Peng
e3271b07c4 tlog: update tlog 2023-02-22 21:54:16 +08:00
Nick Peng
c5ca3ccf43 luci: add dns64 option 2023-02-21 23:28:17 +08:00
Nick Peng
a6cb6061ec optware: fix optware init script issue 2023-02-21 22:59:50 +08:00
Nick Peng
995d5dce95 dns-client: fix tcp connect timeout issue. 2023-02-21 22:38:55 +08:00
Nick Peng
c21be04632 dns_server: update ttl issue for domain-rule 2023-02-18 21:10:44 +08:00
12 changed files with 241 additions and 55 deletions

View File

@@ -82,6 +82,9 @@ msgstr "协议类型"
msgid "DNS domain result cache size" msgid "DNS domain result cache size"
msgstr "缓存DNS的结果缓存大小配置零则不缓存" msgstr "缓存DNS的结果缓存大小配置零则不缓存"
msgid "DNS64 Server Settings"
msgstr "DNS64服务器配置"
msgid "Description" msgid "Description"
msgstr "描述" msgstr "描述"

View File

@@ -34,6 +34,7 @@ s.anonymous = true
s:tab("settings", translate("General Settings")) s:tab("settings", translate("General Settings"))
s:tab("advanced", translate('Advanced Settings')) s:tab("advanced", translate('Advanced Settings'))
s:tab("seconddns", translate("Second Server Settings")) s:tab("seconddns", translate("Second Server Settings"))
s:tab("dns64", translate("DNS64 Server Settings"))
s:tab("proxy", translate("Proxy Server Settings")) s:tab("proxy", translate("Proxy Server Settings"))
s:tab("custom", translate("Custom Settings")) s:tab("custom", translate("Custom Settings"))
@@ -371,6 +372,12 @@ function o.validate(self, value)
return value return value
end end
----- dns64 server settings
o = s:taboption("dns64", Value, "dns64", translate("DNS64"));
o.placeholder = "64:ff9b::/96"
o.datatype = 'ip6addr'
o.rmempty = true
----- custom settings ----- custom settings
custom = s:taboption("custom", Value, "Custom Settings", custom = s:taboption("custom", Value, "Custom Settings",
translate(""), translate(""),

View File

@@ -90,6 +90,9 @@ msgstr "协议类型"
msgid "DNS domain result cache size" msgid "DNS domain result cache size"
msgstr "缓存DNS的结果缓存大小配置零则不缓存" msgstr "缓存DNS的结果缓存大小配置零则不缓存"
msgid "DNS64 Server Settings"
msgstr "DNS64服务器配置"
msgid "default" msgid "default"
msgstr "默认" msgstr "默认"

View File

@@ -131,6 +131,7 @@ return view.extend({
s.tab("settings", _("General Settings")); s.tab("settings", _("General Settings"));
s.tab("advanced", _('Advanced Settings')); s.tab("advanced", _('Advanced Settings'));
s.tab("seconddns", _("Second Server Settings")); s.tab("seconddns", _("Second Server Settings"));
s.tab("dns64", _("DNS64 Server Settings"));
s.tab("files", _("Download Files Setting"), _("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect.")); s.tab("files", _("Download Files Setting"), _("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect."));
s.tab("proxy", _("Proxy Server Settings")); s.tab("proxy", _("Proxy Server Settings"));
s.tab("custom", _("Custom Settings")); s.tab("custom", _("Custom Settings"));
@@ -430,6 +431,14 @@ return view.extend({
o.rmempty = false; o.rmempty = false;
o.default = o.disabled; o.default = o.disabled;
///////////////////////////////////////
// DNS64 Settings
///////////////////////////////////////
o = s.taboption("dns64", form.Value, "dns64", _("DNS64"));
o.placeholder = "64:ff9b::/96";
o.datatype = "ip6addr";
o.rempty = true;
/////////////////////////////////////// ///////////////////////////////////////
// download Files Settings // download Files Settings
/////////////////////////////////////// ///////////////////////////////////////

View File

@@ -480,6 +480,7 @@ load_service()
config_get port "$section" "port" "53" config_get port "$section" "port" "53"
config_get ipv6_server "$section" "ipv6_server" "1" config_get ipv6_server "$section" "ipv6_server" "1"
config_get tcp_server "$section" "tcp_server" "1" config_get tcp_server "$section" "tcp_server" "1"
config_get server_flags "$section" "server_flags" ""
config_get speed_check_mode "$section" "speed_check_mode" "" config_get speed_check_mode "$section" "speed_check_mode" ""
[ ! -z "$speed_check_mode" ] && conf_append "speed-check-mode" "$speed_check_mode" [ ! -z "$speed_check_mode" ] && conf_append "speed-check-mode" "$speed_check_mode"
@@ -563,6 +564,9 @@ load_service()
config_get proxy_server "$section" "proxy_server" "" config_get proxy_server "$section" "proxy_server" ""
[ -z "$proxy_server" ] || conf_append "proxy-server" "$proxy_server -name default-proxy" [ -z "$proxy_server" ] || conf_append "proxy-server" "$proxy_server -name default-proxy"
config_get dns64 "$section" "dns64" ""
[ -z "$dns64" ] || conf_append "dns64" "$dns64"
config_get redirect "$section" "redirect" "" config_get redirect "$section" "redirect" ""
config_get old_port "$section" "old_port" "0" config_get old_port "$section" "old_port" "0"
config_get old_enabled "$section" "old_enabled" "0" config_get old_enabled "$section" "old_enabled" "0"
@@ -629,7 +633,7 @@ load_service()
[ "$auto_set_dnsmasq" = "0" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0" [ "$auto_set_dnsmasq" = "0" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0"
} }
conf_append_bind "$port" "$device" "$tcp_server" "$ipv6_server" "$ARGS" conf_append_bind "$port" "$device" "$tcp_server" "$ipv6_server" "$server_flags"
load_second_server "$section" load_second_server "$section"

View File

@@ -343,28 +343,28 @@ case "$1" in
$SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID $SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
clear_rule clear_rule
exit 1
fi fi
;; ;;
status) status)
pid="$(cat $SMARTDNS_PID |head -n 1 2>/dev/null)" pid="$(cat $SMARTDNS_PID |head -n 1 2>/dev/null)"
if [ -z "$pid" ]; then if [ -z "$pid" ]; then
echo "smartdns not running." echo "smartdns not running."
return 0 exit 0
fi fi
if [ -d "/proc/$pid" ]; then if [ -d "/proc/$pid" ]; then
echo "smartdns running" echo "smartdns is running"
return 0; exit 0
fi fi
echo "smartdns not running." echo "smartdns not running."
return 0; exit 0
;; ;;
stop) stop)
clear_rule
pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)" pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
if [ -z "$pid" ]; then if [ -z "$pid" ]; then
echo "smartdns not running." echo "smartdns not running."
return 0 exit 0
fi fi
kill -15 "$pid" 2>/dev/null kill -15 "$pid" 2>/dev/null
@@ -379,17 +379,17 @@ case "$1" in
do do
pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)" pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
if [ -z "$pid" ]; then if [ -z "$pid" ]; then
return 0 break
fi fi
if [ ! -d "/proc/$pid" ]; then if [ ! -d "/proc/$pid" ]; then
return 0 break
fi fi
stat="$(cat /proc/${pid}/stat | awk '{print $3}' 2>/dev/null)" stat="$(cat /proc/${pid}/stat | awk '{print $3}' 2>/dev/null)"
if [ "$stat" = "Z" ]; then if [ "$stat" = "Z" ]; then
$SLEEP $SLEEPTIME $SLEEP $SLEEPTIME
return 0 break
fi fi
$SLEEP $SLEEPTIME 2>/dev/null $SLEEP $SLEEPTIME 2>/dev/null
@@ -397,11 +397,15 @@ case "$1" in
done done
kill -9 "$pid" 2>/dev/null kill -9 "$pid" 2>/dev/null
clear_rule
exit 0
;; ;;
restart) restart)
$0 stop $0 stop
$0 start $0 start
;; ;;
reload)
;;
enable) enable)
nvram set apps_state_enable=2 nvram set apps_state_enable=2
nvram set apps_state_error=0 nvram set apps_state_error=0

View File

@@ -41,13 +41,14 @@
#include <netinet/ip_icmp.h> #include <netinet/ip_icmp.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/ssl.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@@ -196,7 +197,6 @@ struct dns_client {
/* query list */ /* query list */
struct list_head dns_request_list; struct list_head dns_request_list;
pthread_cond_t run_cond;
atomic_t run_period; atomic_t run_period;
atomic_t dns_server_num; atomic_t dns_server_num;
@@ -208,6 +208,8 @@ struct dns_client {
pthread_mutex_t domain_map_lock; pthread_mutex_t domain_map_lock;
DECLARE_HASHTABLE(domain_map, 6); DECLARE_HASHTABLE(domain_map, 6);
DECLARE_HASHTABLE(group, 4); DECLARE_HASHTABLE(group, 4);
int fd_wakeup;
}; };
/* dns replied server info */ /* dns replied server info */
@@ -264,6 +266,8 @@ static pthread_mutex_t pending_server_mutex = PTHREAD_MUTEX_INITIALIZER;
static int dns_client_has_bootstrap_dns = 0; static int dns_client_has_bootstrap_dns = 0;
static int _dns_client_send_udp(struct dns_server_info *server_info, void *packet, int len); static int _dns_client_send_udp(struct dns_server_info *server_info, void *packet, int len);
static void _dns_client_clear_wakeup_event(void);
static void _dns_client_do_wakeup_event(void);
static ssize_t _ssl_read(struct dns_server_info *server, void *buff, int num) static ssize_t _ssl_read(struct dns_server_info *server, void *buff, int num)
{ {
@@ -443,7 +447,7 @@ errout:
} }
/* check whether server exists */ /* check whether server exists */
static int _dns_client_server_exist(const char *server_ip, int port, dns_server_type_t server_type) static int _dns_client_server_exist(const char *server_ip, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags)
{ {
struct dns_server_info *server_info = NULL; struct dns_server_info *server_info = NULL;
struct dns_server_info *tmp = NULL; struct dns_server_info *tmp = NULL;
@@ -454,6 +458,10 @@ static int _dns_client_server_exist(const char *server_ip, int port, dns_server_
continue; continue;
} }
if (memcmp(&server_info->flags, flags, sizeof(*flags)) == 0) {
continue;
}
if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN) != 0) { if (strncmp(server_info->ip, server_ip, DNS_HOSTNAME_LEN) != 0) {
continue; continue;
} }
@@ -1025,7 +1033,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
} }
/* if server exist, return */ /* if server exist, return */
if (_dns_client_server_exist(server_ip, port, server_type) == 0) { if (_dns_client_server_exist(server_ip, port, server_type, flags) == 0) {
return 0; return 0;
} }
@@ -1337,9 +1345,8 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type
atomic_set(&client.run_period, 1); atomic_set(&client.run_period, 1);
pthread_mutex_unlock(&pending_server_mutex); pthread_mutex_unlock(&pending_server_mutex);
pthread_mutex_lock(&client.domain_map_lock); _dns_client_do_wakeup_event();
pthread_cond_signal(&client.run_cond);
pthread_mutex_unlock(&client.domain_map_lock);
return 0; return 0;
errout: errout:
if (pending) { if (pending) {
@@ -1514,7 +1521,7 @@ static void _dns_client_check_tcp(void)
} }
if (server_info->status == DNS_SERVER_STATUS_CONNECTING) { if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
if (server_info->last_send + DNS_TCP_CONNECT_TIMEOUT < now) { if (server_info->last_recv + DNS_TCP_CONNECT_TIMEOUT < now) {
tlog(TLOG_DEBUG, "server %s connect timeout.", server_info->ip); tlog(TLOG_DEBUG, "server %s connect timeout.", server_info->ip);
_dns_client_close_socket(server_info); _dns_client_close_socket(server_info);
} }
@@ -3569,7 +3576,7 @@ int dns_client_query(const char *domain, int qtype, dns_client_callback callback
pthread_mutex_lock(&client.domain_map_lock); pthread_mutex_lock(&client.domain_map_lock);
if (hash_hashed(&query->domain_node)) { if (hash_hashed(&query->domain_node)) {
if (list_empty(&client.dns_request_list)) { if (list_empty(&client.dns_request_list)) {
pthread_cond_signal(&client.run_cond); _dns_client_do_wakeup_event();
} }
list_add_tail(&query->dns_request_list, &client.dns_request_list); list_add_tail(&query->dns_request_list, &client.dns_request_list);
@@ -3818,15 +3825,12 @@ static void _dns_client_period_run_second(void)
_dns_client_add_pending_servers(); _dns_client_add_pending_servers();
} }
static void _dns_client_period_run(void) static void _dns_client_period_run(unsigned int msec)
{ {
struct dns_query_struct *query = NULL; struct dns_query_struct *query = NULL;
struct dns_query_struct *tmp = NULL; struct dns_query_struct *tmp = NULL;
static unsigned int msec = 0;
msec++;
LIST_HEAD(check_list); LIST_HEAD(check_list);
unsigned long now = get_tick_count(); unsigned long now = get_tick_count();
/* get query which timed out to check list */ /* get query which timed out to check list */
@@ -3869,9 +3873,11 @@ static void *_dns_client_work(void *arg)
int i = 0; int i = 0;
unsigned long now = {0}; unsigned long now = {0};
unsigned long last = {0}; unsigned long last = {0};
unsigned int msec = 0;
unsigned int sleep = 100; unsigned int sleep = 100;
int sleep_time = 0; int sleep_time = 0;
unsigned long expect_time = 0; unsigned long expect_time = 0;
int unused __attribute__((unused));
sleep_time = sleep; sleep_time = sleep;
now = get_tick_count() - sleep; now = get_tick_count() - sleep;
@@ -3884,11 +3890,17 @@ static void *_dns_client_work(void *arg)
if (sleep_time <= 0) { if (sleep_time <= 0) {
sleep_time = 0; sleep_time = 0;
} }
int cnt = sleep_time / sleep;
msec -= cnt;
expect_time -= cnt * sleep;
sleep_time -= cnt * sleep;
} }
if (now >= expect_time) { if (now >= expect_time) {
msec++;
if (last != now) { if (last != now) {
_dns_client_period_run(); _dns_client_period_run(msec);
} }
sleep_time = sleep - (now - expect_time); sleep_time = sleep - (now - expect_time);
@@ -3896,19 +3908,21 @@ static void *_dns_client_work(void *arg)
sleep_time = 0; sleep_time = 0;
expect_time = now; expect_time = now;
} }
/* When client is idle, the sleep time is 1000ms, to reduce CPU usage */
pthread_mutex_lock(&client.domain_map_lock);
if (list_empty(&client.dns_request_list)) {
int cnt = 10 - (msec % 10) - 1;
sleep_time += sleep * cnt;
msec += cnt;
/* sleep to next second */
expect_time += sleep * cnt;
}
pthread_mutex_unlock(&client.domain_map_lock);
expect_time += sleep; expect_time += sleep;
} }
last = now; last = now;
pthread_mutex_lock(&client.domain_map_lock);
if (list_empty(&client.dns_request_list) && atomic_read(&client.run_period) == 0) {
pthread_cond_wait(&client.run_cond, &client.domain_map_lock);
expect_time = get_tick_count();
pthread_mutex_unlock(&client.domain_map_lock);
continue;
}
pthread_mutex_unlock(&client.domain_map_lock);
num = epoll_wait(client.epoll_fd, events, DNS_MAX_EVENTS, sleep_time); num = epoll_wait(client.epoll_fd, events, DNS_MAX_EVENTS, sleep_time);
if (num < 0) { if (num < 0) {
usleep(100000); usleep(100000);
@@ -3918,6 +3932,11 @@ static void *_dns_client_work(void *arg)
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
struct epoll_event *event = &events[i]; struct epoll_event *event = &events[i];
struct dns_server_info *server_info = (struct dns_server_info *)event->data.ptr; struct dns_server_info *server_info = (struct dns_server_info *)event->data.ptr;
if (event->data.fd == client.fd_wakeup) {
_dns_client_clear_wakeup_event();
continue;
}
if (server_info == NULL) { if (server_info == NULL) {
tlog(TLOG_WARN, "server info is invalid."); tlog(TLOG_WARN, "server info is invalid.");
continue; continue;
@@ -3971,10 +3990,71 @@ int dns_client_set_ecs(char *ip, int subnet)
return 0; return 0;
} }
static int _dns_client_create_wakeup_event(void)
{
int fd_wakeup = -1;
fd_wakeup = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (fd_wakeup < 0) {
tlog(TLOG_ERROR, "create eventfd failed, %s\n", strerror(errno));
goto errout;
}
struct epoll_event event;
memset(&event, 0, sizeof(event));
event.events = EPOLLIN;
event.data.fd = fd_wakeup;
if (epoll_ctl(client.epoll_fd, EPOLL_CTL_ADD, fd_wakeup, &event) < 0) {
tlog(TLOG_ERROR, "add eventfd to epoll failed, %s\n", strerror(errno));
goto errout;
}
return fd_wakeup;
errout:
if (fd_wakeup > 0) {
close(fd_wakeup);
}
return -1;
}
static void _dns_client_close_wakeup_event(void)
{
if (client.fd_wakeup > 0) {
close(client.fd_wakeup);
client.fd_wakeup = -1;
}
}
static void _dns_client_clear_wakeup_event(void)
{
uint64_t val = 0;
int unused __attribute__((unused));
if (client.fd_wakeup <= 0) {
return;
}
unused = read(client.fd_wakeup, &val, sizeof(val));
}
static void _dns_client_do_wakeup_event(void)
{
uint64_t val = 1;
int unused __attribute__((unused));
if (client.fd_wakeup <= 0) {
return;
}
unused = write(client.fd_wakeup, &val, sizeof(val));
}
int dns_client_init(void) int dns_client_init(void)
{ {
pthread_attr_t attr; pthread_attr_t attr;
int epollfd = -1; int epollfd = -1;
int fd_wakeup = -1;
int ret = 0; int ret = 0;
if (client.epoll_fd > 0) { if (client.epoll_fd > 0) {
@@ -4002,8 +4082,6 @@ int dns_client_init(void)
hash_init(client.group); hash_init(client.group);
INIT_LIST_HEAD(&client.dns_request_list); INIT_LIST_HEAD(&client.dns_request_list);
pthread_cond_init(&client.run_cond, NULL);
if (dns_client_add_group(DNS_SERVER_GROUP_DEFAULT) != 0) { if (dns_client_add_group(DNS_SERVER_GROUP_DEFAULT) != 0) {
tlog(TLOG_ERROR, "add default server group failed."); tlog(TLOG_ERROR, "add default server group failed.");
goto errout; goto errout;
@@ -4020,6 +4098,14 @@ int dns_client_init(void)
goto errout; goto errout;
} }
fd_wakeup = _dns_client_create_wakeup_event();
if (fd_wakeup < 0) {
tlog(TLOG_ERROR, "create wakeup event failed, %s\n", strerror(errno));
goto errout;
}
client.fd_wakeup = fd_wakeup;
return 0; return 0;
errout: errout:
if (client.tid) { if (client.tid) {
@@ -4029,13 +4115,16 @@ errout:
client.tid = 0; client.tid = 0;
} }
if (epollfd) { if (epollfd > 0) {
close(epollfd); close(epollfd);
} }
if (fd_wakeup > 0) {
close(fd_wakeup);
}
pthread_mutex_destroy(&client.server_list_lock); pthread_mutex_destroy(&client.server_list_lock);
pthread_mutex_destroy(&client.domain_map_lock); pthread_mutex_destroy(&client.domain_map_lock);
pthread_cond_destroy(&client.run_cond);
return -1; return -1;
} }
@@ -4045,14 +4134,13 @@ void dns_client_exit(void)
if (client.tid) { if (client.tid) {
void *ret = NULL; void *ret = NULL;
atomic_set(&client.run, 0); atomic_set(&client.run, 0);
pthread_mutex_lock(&client.domain_map_lock); _dns_client_do_wakeup_event();
pthread_cond_signal(&client.run_cond);
pthread_mutex_unlock(&client.domain_map_lock);
pthread_join(client.tid, &ret); pthread_join(client.tid, &ret);
client.tid = 0; client.tid = 0;
} }
/* free all resources */ /* free all resources */
_dns_client_close_wakeup_event();
_dns_client_remove_all_pending_servers(); _dns_client_remove_all_pending_servers();
_dns_client_server_remove_all(); _dns_client_server_remove_all();
_dns_client_query_remove_all(); _dns_client_query_remove_all();
@@ -4060,7 +4148,6 @@ void dns_client_exit(void)
pthread_mutex_destroy(&client.server_list_lock); pthread_mutex_destroy(&client.server_list_lock);
pthread_mutex_destroy(&client.domain_map_lock); pthread_mutex_destroy(&client.domain_map_lock);
pthread_cond_destroy(&client.run_cond);
if (client.ssl_ctx) { if (client.ssl_ctx) {
SSL_CTX_free(client.ssl_ctx); SSL_CTX_free(client.ssl_ctx);
client.ssl_ctx = NULL; client.ssl_ctx = NULL;

View File

@@ -346,9 +346,9 @@ static int _dns_server_get_conf_ttl(struct dns_request *request, int ttl)
return rr_ttl; return rr_ttl;
} }
if (rr_ttl_max > 0 && ttl > rr_ttl_max) { if (rr_ttl_max > 0 && ttl >= rr_ttl_max) {
ttl = rr_ttl_max; ttl = rr_ttl_max;
} else if (rr_ttl_min > 0 && ttl < rr_ttl_min) { } else if (rr_ttl_min > 0 && ttl <= rr_ttl_min) {
ttl = rr_ttl_min; ttl = rr_ttl_min;
} }
@@ -2948,6 +2948,12 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, const
dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN); dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
} break; } break;
default: default:
if (ttl == 0) {
/* Get TTL */
char tmpname[DNS_MAX_CNAME_LEN];
char tmpbuf[DNS_MAX_CNAME_LEN];
dns_get_CNAME(rrs, tmpname, DNS_MAX_CNAME_LEN, &ttl, tmpbuf, DNS_MAX_CNAME_LEN);
}
break; break;
} }
} }

View File

@@ -110,6 +110,7 @@ struct tlog {
tlog_log_output_func output_func; tlog_log_output_func output_func;
struct tlog_log *wait_on_log; struct tlog_log *wait_on_log;
int is_wait; int is_wait;
char gzip_cmd[PATH_MAX];
}; };
struct tlog_segment_log_head { struct tlog_segment_log_head {
@@ -520,7 +521,7 @@ static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, v
return -1; return -1;
} }
if (unlikely(log->logcount <= 0 && log->logscreen == 0) ) { if (unlikely(log->logcount <= 0 && log->logscreen == 0)) {
return 0; return 0;
} }
@@ -1018,7 +1019,6 @@ errout:
static int _tlog_archive_log_compressed(struct tlog_log *log) static int _tlog_archive_log_compressed(struct tlog_log *log)
{ {
char gzip_file[TLOG_BUFF_LEN]; char gzip_file[TLOG_BUFF_LEN];
char gzip_cmd[PATH_MAX * 2];
char log_file[TLOG_BUFF_LEN]; char log_file[TLOG_BUFF_LEN];
char pending_file[TLOG_BUFF_LEN]; char pending_file[TLOG_BUFF_LEN];
@@ -1046,12 +1046,11 @@ static int _tlog_archive_log_compressed(struct tlog_log *log)
} }
/* start gzip process to compress log file */ /* start gzip process to compress log file */
snprintf(gzip_cmd, sizeof(gzip_cmd), "gzip -1 %s", pending_file);
if (log->zip_pid <= 0) { if (log->zip_pid <= 0) {
int pid = vfork(); int pid = vfork();
if (pid == 0) { if (pid == 0) {
_tlog_close_all_fd(); _tlog_close_all_fd();
execl("/bin/sh", "sh", "-c", gzip_cmd, NULL); execl(tlog.gzip_cmd, tlog.gzip_cmd, "-1", pending_file, NULL);
_exit(1); _exit(1);
} else if (pid < 0) { } else if (pid < 0) {
goto errout; goto errout;
@@ -1363,12 +1362,26 @@ static struct tlog_log *_tlog_wait_log_locked(struct tlog_log *last_log)
int ret = 0; int ret = 0;
struct timespec tm; struct timespec tm;
struct tlog_log *log = NULL; struct tlog_log *log = NULL;
struct tlog_log *next = NULL;
int need_wait_pid = 0;
for (next = tlog.log; next != NULL; next = next->next) {
if (next->zip_pid > 0) {
need_wait_pid = 1;
break;
}
}
clock_gettime(CLOCK_REALTIME, &tm); clock_gettime(CLOCK_REALTIME, &tm);
tm.tv_sec += 2; tm.tv_sec += 2;
tlog.is_wait = 1; tlog.is_wait = 1;
tlog.wait_on_log = last_log; tlog.wait_on_log = last_log;
if (need_wait_pid != 0) {
ret = pthread_cond_timedwait(&tlog.cond, &tlog.lock, &tm); ret = pthread_cond_timedwait(&tlog.cond, &tlog.lock, &tm);
} else {
ret = pthread_cond_wait(&tlog.cond, &tlog.lock);
}
tlog.is_wait = 0; tlog.is_wait = 0;
tlog.wait_on_log = NULL; tlog.wait_on_log = NULL;
errno = ret; errno = ret;
@@ -1676,6 +1689,15 @@ int tlog_setlevel(tlog_level level)
return 0; return 0;
} }
int tlog_log_enabled(tlog_level level)
{
if (level >= TLOG_END) {
return 0;
}
return (tlog_set_level >= level) ? 1 : 0;
}
tlog_level tlog_getlevel(void) tlog_level tlog_getlevel(void)
{ {
return tlog_set_level; return tlog_set_level;
@@ -1686,6 +1708,35 @@ void tlog_set_logfile(const char *logfile)
tlog_rename_logfile(tlog.root, logfile); tlog_rename_logfile(tlog.root, logfile);
} }
static void _tlog_get_gzip_cmd_path(void)
{
char *copy_path = NULL;
char gzip_cmd_path[PATH_MAX];
const char *env_path = getenv("PATH");
char *save_ptr = NULL;
if (env_path == NULL) {
env_path = "/bin:/usr/bin:/usr/local/bin";
}
copy_path = strdup(env_path);
if (copy_path == NULL) {
return;
}
for (char *tok = strtok_r(copy_path, ":", &save_ptr); tok; tok = strtok_r(NULL, ":", &save_ptr)) {
snprintf(gzip_cmd_path, sizeof(gzip_cmd_path), "%s/gzip", tok);
if (access(gzip_cmd_path, X_OK) != 0) {
continue;
}
snprintf(tlog.gzip_cmd, sizeof(tlog.gzip_cmd), "%s", gzip_cmd_path);
break;
}
free(copy_path);
}
tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag) tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int buffsize, unsigned int flag)
{ {
struct tlog_log *log = NULL; struct tlog_log *log = NULL;
@@ -1726,6 +1777,10 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bu
log->file_perm = S_IRUSR | S_IWUSR | S_IRGRP; log->file_perm = S_IRUSR | S_IWUSR | S_IRGRP;
log->archive_perm = S_IRUSR | S_IRGRP; log->archive_perm = S_IRUSR | S_IRGRP;
if (log->nocompress == 0 && tlog.gzip_cmd[0] == '\0') {
log->nocompress = 1;
}
tlog_rename_logfile(log, logfile); tlog_rename_logfile(log, logfile);
if (log->nocompress) { if (log->nocompress) {
strncpy(log->suffix, TLOG_SUFFIX_LOG, sizeof(log->suffix)); strncpy(log->suffix, TLOG_SUFFIX_LOG, sizeof(log->suffix));
@@ -1859,6 +1914,7 @@ int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int buffsize
memset(&tlog, 0, sizeof(tlog)); memset(&tlog, 0, sizeof(tlog));
tlog.is_wait = 0; tlog.is_wait = 0;
_tlog_get_gzip_cmd_path();
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_cond_init(&tlog.cond, NULL); pthread_cond_init(&tlog.cond, NULL);
pthread_mutex_init(&tlog.lock, NULL); pthread_mutex_init(&tlog.lock, NULL);
@@ -1871,6 +1927,10 @@ int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int buffsize
} }
tlog_reg_output_func(log, _tlog_root_write_log); tlog_reg_output_func(log, _tlog_root_write_log);
if ((flag & TLOG_NOCOMPRESS) == 0 && tlog.gzip_cmd[0] == '\0') {
fprintf(stderr, "can not find gzip command, disable compress.\n");
}
tlog.root = log; tlog.root = log;
ret = pthread_create(&tlog.tid, &attr, _tlog_work, NULL); ret = pthread_create(&tlog.tid, &attr, _tlog_work, NULL);
if (ret != 0) { if (ret != 0) {

View File

@@ -95,6 +95,9 @@ extern int tlog_write_log(char *buff, int bufflen);
/* set log level */ /* set log level */
extern int tlog_setlevel(tlog_level level); extern int tlog_setlevel(tlog_level level);
/* is log level enabled*/
extern int tlog_log_enabled(tlog_level level);
/* get log level */ /* get log level */
extern tlog_level tlog_getlevel(void); extern tlog_level tlog_getlevel(void);