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

@@ -126,7 +126,7 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
1. **高性能、占用资源少** 1. **高性能、占用资源少**
多线程异步 IO 模式cache 缓存查询结果。 多线程异步 IO 模式cache 缓存查询结果。
1. **主流系统官方支持** 1. **主流系统官方支持**
主流路由系统官方软件源安装smartdns。 主流路由系统官方软件源安装smartdns。
## 架构 ## 架构

View File

@@ -121,7 +121,7 @@ From the comparison, smartdns found the fastest IP address to visit www.baidu.co
1. **High performance, low resource consumption** 1. **High performance, low resource consumption**
Multi-threaded asynchronous IO mode, cache cache query results. Multi-threaded asynchronous IO mode, cache cache query results.
1. **DNS domain forwarding** 1. **DNS domain forwarding**
Support DNS forwarding, ipset and nftables. Support setting the domain result to ipset and nftset set when speed check fails. Support DNS forwarding, ipset and nftables. Support setting the domain result to ipset and nftset set when speed check fails.
## Architecture ## Architecture

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;
ret = pthread_cond_timedwait(&tlog.cond, &tlog.lock, &tm); if (need_wait_pid != 0) {
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

@@ -79,9 +79,9 @@ level: Current log Levels
format: Log formats format: Log formats
*/ */
#ifndef BASE_FILE_NAME #ifndef BASE_FILE_NAME
#define BASE_FILE_NAME \ #define BASE_FILE_NAME \
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \
: __FILE__) : __FILE__)
#endif #endif
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, NULL, format, ##__VA_ARGS__) #define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, NULL, format, ##__VA_ARGS__)
@@ -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);
@@ -137,7 +140,7 @@ read _tlog_format for example.
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_loginfo *info, void *userptr, const char *format, va_list ap); typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_loginfo *info, void *userptr, const char *format, va_list ap);
extern int tlog_reg_format_func(tlog_format_func func); extern int tlog_reg_format_func(tlog_format_func func);
/* register log output callback /* register log output callback
Note: info is invalid when flag TLOG_SEGMENT is not set. Note: info is invalid when flag TLOG_SEGMENT is not set.
*/ */
typedef int (*tlog_log_output_func)(struct tlog_loginfo *info, const char *buff, int bufflen, void *private_data); typedef int (*tlog_log_output_func)(struct tlog_loginfo *info, const char *buff, int bufflen, void *private_data);
@@ -213,7 +216,7 @@ file: log file permission, default is 640
archive: archive file permission, default is 440 archive: archive file permission, default is 440
*/ */
extern void tlog_set_permission(struct tlog_log *log, mode_t file, mode_t archive); extern void tlog_set_permission(struct tlog_log *log, mode_t file, mode_t archive);
#ifdef __cplusplus #ifdef __cplusplus
class Tlog { class Tlog {