Skip to content

Commit

Permalink
cache: fix dns cache prefetch issue
Browse files Browse the repository at this point in the history
  • Loading branch information
pymumu committed Jun 25, 2022
1 parent 8831167 commit 5006059
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 41 deletions.
46 changes: 32 additions & 14 deletions src/dns_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -541,22 +544,24 @@ 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 (dns_cache->del_pending == 1) {
if (callback_num >= max_callback_num) {
continue;
}

/* 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;
if (dns_cache->del_pending == 1) {
continue;
}

/* If the TTL time is in the pre-timeout range, call callback function */
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);

Expand All @@ -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;
Expand All @@ -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;
}
}
Expand All @@ -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)
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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)) {
Expand All @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/dns_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
15 changes: 15 additions & 0 deletions src/dns_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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;
Expand Down
54 changes: 29 additions & 25 deletions src/dns_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -689,21 +690,21 @@ 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]);
}

/* add AAAA record */
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]);
}
}

Expand Down Expand Up @@ -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]);
}
}

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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.");
}

Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 5006059

Please sign in to comment.