cache: fix dns cache prefetch issue
This commit is contained in:
@@ -243,7 +243,8 @@ struct dns_cache_data *dns_cache_new_data_packet(uint32_t cache_flag, void *pack
|
||||
return (struct dns_cache_data *)cache_packet;
|
||||
}
|
||||
|
||||
int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, int inactive, struct dns_cache_data *cache_data)
|
||||
int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, int inactive,
|
||||
struct dns_cache_data *cache_data)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache_data *old_cache_data = NULL;
|
||||
@@ -521,10 +522,12 @@ void dns_cache_update(struct dns_cache *dns_cache)
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
}
|
||||
|
||||
void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int ttl_inactive_pre, time_t *now)
|
||||
void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int ttl_inactive_pre,
|
||||
unsigned int max_callback_num, time_t *now)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *tmp;
|
||||
int callback_num = 0;
|
||||
int ttl = 0;
|
||||
LIST_HEAD(checklist);
|
||||
|
||||
@@ -541,8 +544,12 @@ void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int
|
||||
continue;
|
||||
}
|
||||
|
||||
ttl = dns_cache->info.replace_time + dns_cache->info.ttl - *now;
|
||||
if (ttl > 0) {
|
||||
ttl = *now - dns_cache->info.replace_time;
|
||||
if (ttl < ttl_inactive_pre || inactive_precallback == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (callback_num >= max_callback_num) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -551,12 +558,10 @@ void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int
|
||||
}
|
||||
|
||||
/* If the TTL time is in the pre-timeout range, call callback function */
|
||||
if (inactive_precallback && ttl_inactive_pre < -ttl) {
|
||||
list_add_tail(&dns_cache->check_list, &checklist);
|
||||
dns_cache_get(dns_cache);
|
||||
dns_cache->del_pending = 1;
|
||||
continue;
|
||||
}
|
||||
dns_cache_get(dns_cache);
|
||||
list_add_tail(&dns_cache->check_list, &checklist);
|
||||
dns_cache->del_pending = 1;
|
||||
callback_num++;
|
||||
}
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
|
||||
@@ -570,14 +575,19 @@ void _dns_cache_remove_expired_ttl(dns_cache_callback inactive_precallback, int
|
||||
}
|
||||
}
|
||||
|
||||
void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, dns_cache_callback inactive_precallback,
|
||||
int ttl_inactive_pre)
|
||||
void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, unsigned int max_callback_num,
|
||||
dns_cache_callback inactive_precallback, int ttl_inactive_pre)
|
||||
{
|
||||
struct dns_cache *dns_cache = NULL;
|
||||
struct dns_cache *tmp;
|
||||
time_t now;
|
||||
int ttl = 0;
|
||||
LIST_HEAD(checklist);
|
||||
int callback_num = 0;
|
||||
|
||||
if (max_callback_num <= 0) {
|
||||
max_callback_num = -1;
|
||||
}
|
||||
|
||||
if (dns_cache_head.size <= 0) {
|
||||
return;
|
||||
@@ -590,10 +600,11 @@ void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, dns_cache
|
||||
ttl = dns_cache->info.insert_time + dns_cache->info.ttl - now;
|
||||
if (ttl > 0 && ttl < ttl_pre) {
|
||||
/* If the TTL time is in the pre-timeout range, call callback function */
|
||||
if (precallback && dns_cache->del_pending == 0) {
|
||||
if (precallback && dns_cache->del_pending == 0 && callback_num < max_callback_num) {
|
||||
list_add_tail(&dns_cache->check_list, &checklist);
|
||||
dns_cache_get(dns_cache);
|
||||
dns_cache->del_pending = 1;
|
||||
callback_num++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -609,7 +620,7 @@ void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, dns_cache
|
||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||
|
||||
if (dns_cache_head.enable_inactive && dns_cache_head.inactive_list_expired != 0) {
|
||||
_dns_cache_remove_expired_ttl(inactive_precallback, ttl_inactive_pre, &now);
|
||||
_dns_cache_remove_expired_ttl(inactive_precallback, ttl_inactive_pre, max_callback_num, &now);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(dns_cache, tmp, &checklist, check_list)
|
||||
@@ -618,6 +629,7 @@ void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, dns_cache
|
||||
if (precallback) {
|
||||
precallback(dns_cache);
|
||||
}
|
||||
list_del(&dns_cache->check_list);
|
||||
dns_cache_release(dns_cache);
|
||||
}
|
||||
}
|
||||
@@ -695,11 +707,16 @@ int dns_cache_load(const char *file)
|
||||
{
|
||||
int fd = -1;
|
||||
int ret = 0;
|
||||
size_t filesize;
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
filesize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
posix_fadvise(fd, 0, filesize, POSIX_FADV_WILLNEED | POSIX_FADV_SEQUENTIAL);
|
||||
|
||||
struct dns_cache_file cache_file;
|
||||
ret = read(fd, &cache_file, sizeof(cache_file));
|
||||
if (ret != sizeof(cache_file)) {
|
||||
@@ -717,6 +734,7 @@ int dns_cache_load(const char *file)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tlog(TLOG_INFO, "load cache file %s, total %d records", file, cache_file.cache_number);
|
||||
if (_dns_cache_read_record(fd, cache_file.cache_number) != 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ void dns_cache_update(struct dns_cache *dns_cache);
|
||||
|
||||
typedef void dns_cache_callback(struct dns_cache *dns_cache);
|
||||
|
||||
void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, dns_cache_callback inactive_precallback,
|
||||
int ttl_inactive_pre);
|
||||
void dns_cache_invalidate(dns_cache_callback precallback, int ttl_pre, unsigned int max_callback_num,
|
||||
dns_cache_callback inactive_precallback, int ttl_inactive_pre);
|
||||
|
||||
int dns_cache_get_ttl(struct dns_cache *dns_cache);
|
||||
|
||||
|
||||
@@ -913,6 +913,7 @@ static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
|
||||
char group_name[DNS_GROUP_NAME_LEN];
|
||||
const char *group = NULL;
|
||||
unsigned int server_flag = 0;
|
||||
int i = 0;
|
||||
|
||||
/* clang-format off */
|
||||
static struct option long_options[] = {
|
||||
@@ -940,6 +941,20 @@ static int _config_bind_ip(int argc, char *argv[], DNS_BIND_TYPE type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < dns_conf_bind_ip_num; i++) {
|
||||
bind_ip = &dns_conf_bind_ip[i];
|
||||
if (bind_ip->type != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(bind_ip->ip, ip, DNS_MAX_IPLEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tlog(TLOG_WARN, "Bind server %s, type %d, already configured, skip.", ip, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bind_ip = &dns_conf_bind_ip[index];
|
||||
bind_ip->type = type;
|
||||
bind_ip->flags = 0;
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#define SOCKET_PRIORITY (6)
|
||||
#define CACHE_AUTO_ENABLE_SIZE (1024 * 1024 * 128)
|
||||
#define EXPIRED_DOMAIN_PREFTCH_TIME (3600 * 8)
|
||||
#define DNS_MAX_DOMAIN_REFETCH_NUM 16
|
||||
|
||||
#define RECV_ERROR_AGAIN 1
|
||||
#define RECV_ERROR_OK 0
|
||||
@@ -556,14 +557,14 @@ static void _dns_rrs_result_log(struct dns_server_post_context *context, struct
|
||||
}
|
||||
|
||||
if (addr_map->addr_type == DNS_T_A) {
|
||||
tlog(TLOG_INFO, "result: %s, id: %d, index: %d, rtt: %d, %d.%d.%d.%d", request->domain, request->id,
|
||||
context->ip_num, addr_map->ping_time, addr_map->ip_addr[0], addr_map->ip_addr[1], addr_map->ip_addr[2],
|
||||
addr_map->ip_addr[3]);
|
||||
tlog(TLOG_INFO, "result: %s, id: %d, index: %d, rtt: %.1f ms, %d.%d.%d.%d", request->domain, request->id,
|
||||
context->ip_num, ((float)addr_map->ping_time) / 10, addr_map->ip_addr[0], addr_map->ip_addr[1],
|
||||
addr_map->ip_addr[2], addr_map->ip_addr[3]);
|
||||
} else if (addr_map->addr_type == DNS_T_AAAA) {
|
||||
tlog(TLOG_INFO,
|
||||
"result: %s, id: %d, index: %d, rtt: %d, "
|
||||
"result: %s, id: %d, index: %d, rtt: %.1f ms, "
|
||||
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||
request->domain, request->id, context->ip_num, addr_map->ping_time, addr_map->ip_addr[0],
|
||||
request->domain, request->id, context->ip_num, ((float)addr_map->ping_time) / 10, addr_map->ip_addr[0],
|
||||
addr_map->ip_addr[1], addr_map->ip_addr[2], addr_map->ip_addr[3], addr_map->ip_addr[4],
|
||||
addr_map->ip_addr[5], addr_map->ip_addr[6], addr_map->ip_addr[7], addr_map->ip_addr[8],
|
||||
addr_map->ip_addr[9], addr_map->ip_addr[10], addr_map->ip_addr[11], addr_map->ip_addr[12],
|
||||
@@ -689,7 +690,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
|
||||
context->ip_num++;
|
||||
if (context->qtype == DNS_T_A) {
|
||||
ret |= dns_add_A(context->packet, DNS_RRS_AN, domain, request->ip_ttl, request->ip_addr);
|
||||
tlog(TLOG_DEBUG, "result: %s, rtt: %d, %d.%d.%d.%d", request->domain, request->ping_time,
|
||||
tlog(TLOG_DEBUG, "result: %s, rtt: %.1f ms, %d.%d.%d.%d", request->domain, ((float)request->ping_time) / 10,
|
||||
request->ip_addr[0], request->ip_addr[1], request->ip_addr[2], request->ip_addr[3]);
|
||||
}
|
||||
|
||||
@@ -697,13 +698,13 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
|
||||
if (context->qtype == DNS_T_AAAA) {
|
||||
ret |= dns_add_AAAA(context->packet, DNS_RRS_AN, domain, request->ip_ttl, request->ip_addr);
|
||||
tlog(TLOG_DEBUG,
|
||||
"result: %s, rtt: %d, "
|
||||
"result: %s, rtt: %.1f ms, "
|
||||
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||
request->domain, request->ping_time, request->ip_addr[0], request->ip_addr[1], request->ip_addr[2],
|
||||
request->ip_addr[3], request->ip_addr[4], request->ip_addr[5], request->ip_addr[6],
|
||||
request->ip_addr[7], request->ip_addr[8], request->ip_addr[9], request->ip_addr[10],
|
||||
request->ip_addr[11], request->ip_addr[12], request->ip_addr[13], request->ip_addr[14],
|
||||
request->ip_addr[15]);
|
||||
request->domain, ((float)request->ping_time) / 10, request->ip_addr[0], request->ip_addr[1],
|
||||
request->ip_addr[2], request->ip_addr[3], request->ip_addr[4], request->ip_addr[5],
|
||||
request->ip_addr[6], request->ip_addr[7], request->ip_addr[8], request->ip_addr[9],
|
||||
request->ip_addr[10], request->ip_addr[11], request->ip_addr[12], request->ip_addr[13],
|
||||
request->ip_addr[14], request->ip_addr[15]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1539,18 +1540,18 @@ static int _dns_server_request_complete(struct dns_request *request)
|
||||
tlog(TLOG_INFO, "result: %s, qtype: %d, SOA", request->domain, request->qtype);
|
||||
} else {
|
||||
if (request->qtype == DNS_T_A) {
|
||||
tlog(TLOG_INFO, "result: %s, qtype: %d, rtt: %d, %d.%d.%d.%d", request->domain, request->qtype,
|
||||
request->ping_time, request->ip_addr[0], request->ip_addr[1], request->ip_addr[2],
|
||||
tlog(TLOG_INFO, "result: %s, qtype: %d, rtt: %.1f ms, %d.%d.%d.%d", request->domain, request->qtype,
|
||||
((float)request->ping_time) / 10, request->ip_addr[0], request->ip_addr[1], request->ip_addr[2],
|
||||
request->ip_addr[3]);
|
||||
} else if (request->qtype == DNS_T_AAAA) {
|
||||
tlog(TLOG_INFO,
|
||||
"result: %s, qtype: %d, rtt: %d, "
|
||||
"result: %s, qtype: %d, rtt: %.1f ms, "
|
||||
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||
request->domain, request->qtype, request->ping_time, request->ip_addr[0], request->ip_addr[1],
|
||||
request->ip_addr[2], request->ip_addr[3], request->ip_addr[4], request->ip_addr[5],
|
||||
request->ip_addr[6], request->ip_addr[7], request->ip_addr[8], request->ip_addr[9],
|
||||
request->ip_addr[10], request->ip_addr[11], request->ip_addr[12], request->ip_addr[13],
|
||||
request->ip_addr[14], request->ip_addr[15]);
|
||||
request->domain, request->qtype, ((float)request->ping_time) / 10, request->ip_addr[0],
|
||||
request->ip_addr[1], request->ip_addr[2], request->ip_addr[3], request->ip_addr[4],
|
||||
request->ip_addr[5], request->ip_addr[6], request->ip_addr[7], request->ip_addr[8],
|
||||
request->ip_addr[9], request->ip_addr[10], request->ip_addr[11], request->ip_addr[12],
|
||||
request->ip_addr[13], request->ip_addr[14], request->ip_addr[15]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2649,7 +2650,7 @@ void _dns_server_query_end(struct dns_request *request)
|
||||
if (request->dualstack_selection_has_ip && request->dualstack_selection_ping_time > 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
request->has_ping_result = 1;
|
||||
_dns_server_request_complete(request);
|
||||
}
|
||||
@@ -4560,7 +4561,7 @@ static void _dns_server_period_run_second(void)
|
||||
}
|
||||
|
||||
if (now - 180 > last) {
|
||||
dns_cache_invalidate(NULL, 0, NULL, 0);
|
||||
dns_cache_invalidate(NULL, 0, 0, NULL, 0);
|
||||
tlog(TLOG_WARN, "Service paused for 180s, force invalidate cache.");
|
||||
}
|
||||
|
||||
@@ -4578,12 +4579,13 @@ static void _dns_server_period_run_second(void)
|
||||
prefetch_time = EXPIRED_DOMAIN_PREFTCH_TIME;
|
||||
}
|
||||
}
|
||||
dns_cache_invalidate(NULL, 0, _dns_server_prefetch_expired_domain, prefetch_time);
|
||||
dns_cache_invalidate(NULL, 0, DNS_MAX_DOMAIN_REFETCH_NUM, _dns_server_prefetch_expired_domain,
|
||||
prefetch_time);
|
||||
} else {
|
||||
dns_cache_invalidate(_dns_server_prefetch_domain, 3, NULL, 0);
|
||||
dns_cache_invalidate(_dns_server_prefetch_domain, 3, DNS_MAX_DOMAIN_REFETCH_NUM, NULL, 0);
|
||||
}
|
||||
} else {
|
||||
dns_cache_invalidate(NULL, 0, NULL, 0);
|
||||
dns_cache_invalidate(NULL, 0, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4806,6 +4808,8 @@ static int _dns_create_socket(const char *host_ip, int type)
|
||||
}
|
||||
}
|
||||
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
|
||||
freeaddrinfo(gai);
|
||||
|
||||
return fd;
|
||||
|
||||
Reference in New Issue
Block a user