Add prefetch domain feature
This commit is contained in:
@@ -17,6 +17,10 @@ bind [::]:53
|
|||||||
# 0: for no cache
|
# 0: for no cache
|
||||||
cache-size 512
|
cache-size 512
|
||||||
|
|
||||||
|
# prefetch domain
|
||||||
|
# prefetch-domain [true|false]
|
||||||
|
# prefetch-domain true
|
||||||
|
|
||||||
# ttl for all resource record
|
# ttl for all resource record
|
||||||
# rr-ttl: ttl for all record
|
# rr-ttl: ttl for all record
|
||||||
# rr-ttl-min: minimum ttl for resource record
|
# rr-ttl-min: minimum ttl for resource record
|
||||||
|
|||||||
14
src/conf.c
14
src/conf.c
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
char dns_conf_server_ip[DNS_MAX_IPLEN];
|
char dns_conf_server_ip[DNS_MAX_IPLEN];
|
||||||
int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
|
int dns_conf_cachesize = DEFAULT_DNS_CACHE_SIZE;
|
||||||
|
int dns_conf_prefetch = 0;
|
||||||
struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
|
struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
|
||||||
struct dns_bogus_nxdomain dns_conf_bogus_nxdomain;
|
struct dns_bogus_nxdomain dns_conf_bogus_nxdomain;
|
||||||
char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
|
char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
|
||||||
@@ -211,6 +212,18 @@ int config_cache_size(char *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_cache_prefetch_domain(char *value)
|
||||||
|
{
|
||||||
|
/* read dns cache size */
|
||||||
|
if (strncmp("yes", value, sizeof("yes")) == 0 || strncmp("YES", value, sizeof("YES")) == 0) {
|
||||||
|
dns_conf_prefetch = 1;
|
||||||
|
} else if (strncmp("no", value, sizeof("no")) == 0 || strncmp("NO", value, sizeof("NO")) == 0) {
|
||||||
|
dns_conf_prefetch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_log_level(char *value)
|
int config_log_level(char *value)
|
||||||
{
|
{
|
||||||
/* read log level and set */
|
/* read log level and set */
|
||||||
@@ -446,6 +459,7 @@ struct config_item config_item[] = {
|
|||||||
{"server-tcp", config_server_tcp},
|
{"server-tcp", config_server_tcp},
|
||||||
{"server-http", config_server_http},
|
{"server-http", config_server_http},
|
||||||
{"cache-size", config_cache_size},
|
{"cache-size", config_cache_size},
|
||||||
|
{"prefetch-domain", config_cache_prefetch_domain},
|
||||||
{"log-level", config_log_level},
|
{"log-level", config_log_level},
|
||||||
{"log-file", config_log_file},
|
{"log-file", config_log_file},
|
||||||
{"log-size", config_log_size},
|
{"log-size", config_log_size},
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ struct dns_bogus_nxdomain {
|
|||||||
|
|
||||||
extern char dns_conf_server_ip[DNS_MAX_IPLEN];
|
extern char dns_conf_server_ip[DNS_MAX_IPLEN];
|
||||||
extern int dns_conf_cachesize;
|
extern int dns_conf_cachesize;
|
||||||
|
extern int dns_conf_prefetch;
|
||||||
extern struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
|
extern struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
|
||||||
extern int dns_conf_server_num;
|
extern int dns_conf_server_num;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "dns_cache.h"
|
#include "dns_cache.h"
|
||||||
|
#include "tlog.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
struct dns_cache_head {
|
struct dns_cache_head {
|
||||||
@@ -41,6 +42,14 @@ void _dns_cache_delete(struct dns_cache *dns_cache)
|
|||||||
free(dns_cache);
|
free(dns_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dns_cache_get(struct dns_cache *dns_cache)
|
||||||
|
{
|
||||||
|
if (atomic_inc_return(&dns_cache->ref) == 1) {
|
||||||
|
tlog(TLOG_ERROR, "BUG: dns_cache is invalid.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dns_cache_release(struct dns_cache *dns_cache)
|
void dns_cache_release(struct dns_cache *dns_cache)
|
||||||
{
|
{
|
||||||
if (!atomic_dec_and_test(&dns_cache->ref)) {
|
if (!atomic_dec_and_test(&dns_cache->ref)) {
|
||||||
@@ -50,6 +59,52 @@ void dns_cache_release(struct dns_cache *dns_cache)
|
|||||||
_dns_cache_delete(dns_cache);
|
_dns_cache_delete(dns_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dns_cache_replace(char *domain, char *cname, int cname_ttl, int ttl, dns_type_t qtype, unsigned char *addr, int addr_len)
|
||||||
|
{
|
||||||
|
struct dns_cache *dns_cache = NULL;
|
||||||
|
|
||||||
|
if (dns_cache_head.size <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_cache = dns_cache_lookup(domain, qtype);
|
||||||
|
if (dns_cache == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_cache->ttl = ttl;
|
||||||
|
dns_cache->qtype = qtype;
|
||||||
|
dns_cache->ttl = ttl;
|
||||||
|
time(&dns_cache->insert_time);
|
||||||
|
if (qtype == DNS_T_A) {
|
||||||
|
if (addr_len != DNS_RR_A_LEN) {
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
memcpy(dns_cache->addr, addr, DNS_RR_A_LEN);
|
||||||
|
} else if (qtype == DNS_T_AAAA) {
|
||||||
|
if (addr_len != DNS_RR_AAAA_LEN) {
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
memcpy(dns_cache->addr, addr, DNS_RR_AAAA_LEN);
|
||||||
|
} else {
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cname) {
|
||||||
|
strncpy(dns_cache->cname, cname, DNS_MAX_CNAME_LEN);
|
||||||
|
dns_cache->cname_ttl = cname_ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_cache_release(dns_cache);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
if (dns_cache) {
|
||||||
|
dns_cache_release(dns_cache);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type_t qtype, unsigned char *addr, int addr_len)
|
int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type_t qtype, unsigned char *addr, int addr_len)
|
||||||
{
|
{
|
||||||
uint32_t key = 0;
|
uint32_t key = 0;
|
||||||
@@ -59,10 +114,10 @@ int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cache = dns_cache_get(domain, qtype);
|
dns_cache = dns_cache_lookup(domain, qtype);
|
||||||
if (dns_cache) {
|
if (dns_cache) {
|
||||||
dns_cache_release(dns_cache);
|
dns_cache_release(dns_cache);
|
||||||
return 0;
|
dns_cache = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cache = malloc(sizeof(*dns_cache));
|
dns_cache = malloc(sizeof(*dns_cache));
|
||||||
@@ -100,6 +155,7 @@ int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type
|
|||||||
pthread_mutex_lock(&dns_cache_head.lock);
|
pthread_mutex_lock(&dns_cache_head.lock);
|
||||||
hash_add(dns_cache_head.cache_hash, &dns_cache->node, key);
|
hash_add(dns_cache_head.cache_hash, &dns_cache->node, key);
|
||||||
list_add_tail(&dns_cache->list, &dns_cache_head.cache_list);
|
list_add_tail(&dns_cache->list, &dns_cache_head.cache_list);
|
||||||
|
INIT_LIST_HEAD(&dns_cache->check_list);
|
||||||
|
|
||||||
dns_cache_head.num++;
|
dns_cache_head.num++;
|
||||||
if (dns_cache_head.num > dns_cache_head.size) {
|
if (dns_cache_head.num > dns_cache_head.size) {
|
||||||
@@ -118,7 +174,7 @@ errout:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_cache *dns_cache_get(char *domain, dns_type_t qtype)
|
struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
|
||||||
{
|
{
|
||||||
uint32_t key = 0;
|
uint32_t key = 0;
|
||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
@@ -195,12 +251,13 @@ void dns_cache_update(struct dns_cache *dns_cache)
|
|||||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_cache_invalidate(void)
|
void dns_cache_invalidate(dns_cache_preinvalid_callback callback, int ttl_pre)
|
||||||
{
|
{
|
||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
struct dns_cache *tmp;
|
struct dns_cache *tmp;
|
||||||
time_t now;
|
time_t now;
|
||||||
int ttl = 0;
|
int ttl = 0;
|
||||||
|
LIST_HEAD(checklist);
|
||||||
|
|
||||||
if (dns_cache_head.size <= 0) {
|
if (dns_cache_head.size <= 0) {
|
||||||
return;
|
return;
|
||||||
@@ -212,6 +269,17 @@ void dns_cache_invalidate(void)
|
|||||||
{
|
{
|
||||||
ttl = dns_cache->insert_time + dns_cache->ttl - now;
|
ttl = dns_cache->insert_time + dns_cache->ttl - now;
|
||||||
if (ttl > 0) {
|
if (ttl > 0) {
|
||||||
|
if (ttl < ttl_pre) {
|
||||||
|
if (callback) {
|
||||||
|
list_add_tail(&dns_cache->check_list, &checklist);
|
||||||
|
dns_cache_get(dns_cache);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +288,13 @@ void dns_cache_invalidate(void)
|
|||||||
dns_cache_release(dns_cache);
|
dns_cache_release(dns_cache);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&dns_cache_head.lock);
|
pthread_mutex_unlock(&dns_cache_head.lock);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(dns_cache, tmp, &checklist, check_list)
|
||||||
|
{
|
||||||
|
callback(dns_cache);
|
||||||
|
list_del_init(&dns_cache->check_list);
|
||||||
|
dns_cache_release(dns_cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_cache_destroy(void)
|
void dns_cache_destroy(void)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
struct dns_cache {
|
struct dns_cache {
|
||||||
struct hlist_node node;
|
struct hlist_node node;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct list_head check_list;
|
||||||
atomic_t ref;
|
atomic_t ref;
|
||||||
char domain[DNS_MAX_CNAME_LEN];
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
char cname[DNS_MAX_CNAME_LEN];
|
char cname[DNS_MAX_CNAME_LEN];
|
||||||
@@ -27,17 +28,23 @@ struct dns_cache {
|
|||||||
|
|
||||||
int dns_cache_init(int size);
|
int dns_cache_init(int size);
|
||||||
|
|
||||||
|
int dns_cache_replace(char *domain, char *cname, int cname_ttl, int ttl, dns_type_t qtype, unsigned char *addr, int addr_len);
|
||||||
|
|
||||||
int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type_t qtype, unsigned char *addr, int addr_len);
|
int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type_t qtype, unsigned char *addr, int addr_len);
|
||||||
|
|
||||||
struct dns_cache *dns_cache_get(char *domain, dns_type_t qtype);
|
struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype);
|
||||||
|
|
||||||
void dns_cache_delete(struct dns_cache *dns_cache);
|
void dns_cache_delete(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
|
void dns_cache_get(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
void dns_cache_release(struct dns_cache *dns_cache);
|
void dns_cache_release(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
void dns_cache_update(struct dns_cache *dns_cache);
|
void dns_cache_update(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
void dns_cache_invalidate(void);
|
typedef void dns_cache_preinvalid_callback(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
|
void dns_cache_invalidate(dns_cache_preinvalid_callback callback, int ttl_pre);
|
||||||
|
|
||||||
int dns_cache_get_ttl(struct dns_cache *dns_cache);
|
int dns_cache_get_ttl(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
|
|||||||
@@ -1104,7 +1104,7 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
|
|||||||
goto errout_del_list;
|
goto errout_del_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlog(TLOG_INFO, "send request %s, id %d\n", domain, query->sid);
|
tlog(TLOG_INFO, "send request %s, qtype %d, id %d\n", domain, qtype, query->sid);
|
||||||
_dns_client_query_release(query);
|
_dns_client_query_release(query);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
102
src/dns_server.c
102
src/dns_server.c
@@ -124,6 +124,8 @@ struct dns_request {
|
|||||||
/* send original raw packet to server/client like proxy */
|
/* send original raw packet to server/client like proxy */
|
||||||
int passthrough;
|
int passthrough;
|
||||||
|
|
||||||
|
int prefetch;
|
||||||
|
|
||||||
pthread_mutex_t ip_map_lock;
|
pthread_mutex_t ip_map_lock;
|
||||||
int ip_map_num;
|
int ip_map_num;
|
||||||
DECLARE_HASHTABLE(ip_map, 4);
|
DECLARE_HASHTABLE(ip_map, 4);
|
||||||
@@ -293,11 +295,16 @@ int _dns_server_request_complete(struct dns_request *request)
|
|||||||
if (request->has_ping_result == 0 && request->ttl_v4 > DNS_SERVER_TMOUT_TTL) {
|
if (request->has_ping_result == 0 && request->ttl_v4 > DNS_SERVER_TMOUT_TTL) {
|
||||||
request->ttl_v4 = DNS_SERVER_TMOUT_TTL;
|
request->ttl_v4 = DNS_SERVER_TMOUT_TTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request->prefetch) {
|
||||||
|
dns_cache_replace(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
|
||||||
|
} else {
|
||||||
|
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v4, DNS_T_A, request->ipv4_addr, DNS_RR_A_LEN);
|
|
||||||
} else if (request->qtype == DNS_T_AAAA) {
|
} else if (request->qtype == DNS_T_AAAA) {
|
||||||
tlog(TLOG_INFO, "result :%s, rcode: %d, %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", request->domain, request->rcode,
|
tlog(TLOG_INFO, "result: %s, rcode: %d, %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", request->domain, request->rcode,
|
||||||
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
|
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
|
||||||
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
|
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
|
||||||
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
|
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
|
||||||
@@ -306,10 +313,19 @@ int _dns_server_request_complete(struct dns_request *request)
|
|||||||
if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) {
|
if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) {
|
||||||
request->ttl_v6 = DNS_SERVER_TMOUT_TTL;
|
request->ttl_v6 = DNS_SERVER_TMOUT_TTL;
|
||||||
}
|
}
|
||||||
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
|
|
||||||
|
if (request->prefetch) {
|
||||||
|
dns_cache_replace(request->domain, cname, cname_ttl, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
|
||||||
|
} else {
|
||||||
|
dns_cache_insert(request->domain, cname, cname_ttl, request->ttl_v6, DNS_T_AAAA, request->ipv6_addr, DNS_RR_AAAA_LEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request->prefetch) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
_dns_reply(request);
|
_dns_reply(request);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -504,7 +520,7 @@ static int _dns_server_bogus_nxdomain_exists(struct dns_request *request, unsign
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = dns_bogus_nxdomain_exists(ip, addr_type);
|
ret = dns_bogus_nxdomain_exists(ip, addr_type);
|
||||||
if (ret != 0 ) {
|
if (ret != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,7 +597,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
|||||||
_dns_server_request_release(request);
|
_dns_server_request_release(request);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
request->rcode = packet->head.rcode;
|
request->rcode = packet->head.rcode;
|
||||||
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
sprintf(ip, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
|
||||||
|
|
||||||
@@ -604,12 +620,12 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
|
|||||||
/* bogus ip address, skip */
|
/* bogus ip address, skip */
|
||||||
if (_dns_server_bogus_nxdomain_exists(request, addr, DNS_T_AAAA) == 0) {
|
if (_dns_server_bogus_nxdomain_exists(request, addr, DNS_T_AAAA) == 0) {
|
||||||
_dns_server_request_release(request);
|
_dns_server_request_release(request);
|
||||||
tlog(TLOG_DEBUG, "bogus-nxdomain: %s TTL: %d IP: %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", name, ttl, addr[0], addr[1],
|
tlog(TLOG_DEBUG, "bogus-nxdomain: %s TTL: %d IP: %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", name, ttl,
|
||||||
addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
|
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13],
|
||||||
|
addr[14], addr[15]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(request->cname, name, DNS_MAX_CNAME_LEN) != 0) {
|
if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(request->cname, name, DNS_MAX_CNAME_LEN) != 0) {
|
||||||
_dns_server_request_release(request);
|
_dns_server_request_release(request);
|
||||||
break;
|
break;
|
||||||
@@ -693,7 +709,7 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, stru
|
|||||||
pthread_mutex_lock(&request->ip_map_lock);
|
pthread_mutex_lock(&request->ip_map_lock);
|
||||||
ip_num = request->ip_map_num;
|
ip_num = request->ip_map_num;
|
||||||
pthread_mutex_unlock(&request->ip_map_lock);
|
pthread_mutex_unlock(&request->ip_map_lock);
|
||||||
|
|
||||||
/* Not need to wait check result if only has one ip address */
|
/* Not need to wait check result if only has one ip address */
|
||||||
if (ip_num == 1) {
|
if (ip_num == 1) {
|
||||||
_dns_server_request_complete(request);
|
_dns_server_request_complete(request);
|
||||||
@@ -815,8 +831,8 @@ static struct dns_address *_dns_server_get_address_by_domain(char *domain, int q
|
|||||||
|
|
||||||
if (likely(dns_conf_log_level > TLOG_INFO)) {
|
if (likely(dns_conf_log_level > TLOG_INFO)) {
|
||||||
return art_substring(&dns_conf_address, (unsigned char *)domain_key, domain_len, NULL, NULL);
|
return art_substring(&dns_conf_address, (unsigned char *)domain_key, domain_len, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
address = art_substring(&dns_conf_address, (unsigned char *)domain_key, domain_len, matched_key, &matched_key_len);
|
address = art_substring(&dns_conf_address, (unsigned char *)domain_key, domain_len, matched_key, &matched_key_len);
|
||||||
if (address == NULL) {
|
if (address == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -868,7 +884,7 @@ static int _dns_server_process_cache(struct dns_request *request, struct dns_pac
|
|||||||
{
|
{
|
||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
|
|
||||||
dns_cache = dns_cache_get(request->domain, request->qtype);
|
dns_cache = dns_cache_lookup(request->domain, request->qtype);
|
||||||
if (dns_cache == NULL) {
|
if (dns_cache == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
@@ -934,16 +950,17 @@ static int _dns_server_recv(unsigned char *inpacket, int inpacket_len, struct so
|
|||||||
}
|
}
|
||||||
|
|
||||||
request = malloc(sizeof(*request));
|
request = malloc(sizeof(*request));
|
||||||
|
if (request == NULL) {
|
||||||
|
tlog(TLOG_ERROR, "malloc failed.\n");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
memset(request, 0, sizeof(*request));
|
memset(request, 0, sizeof(*request));
|
||||||
pthread_mutex_init(&request->ip_map_lock, 0);
|
pthread_mutex_init(&request->ip_map_lock, 0);
|
||||||
atomic_set(&request->adblock, 0);
|
atomic_set(&request->adblock, 0);
|
||||||
request->ping_ttl_v4 = -1;
|
request->ping_ttl_v4 = -1;
|
||||||
request->ping_ttl_v6 = -1;
|
request->ping_ttl_v6 = -1;
|
||||||
|
request->prefetch = 0;
|
||||||
request->rcode = DNS_RC_SERVFAIL;
|
request->rcode = DNS_RC_SERVFAIL;
|
||||||
if (request == NULL) {
|
|
||||||
tlog(TLOG_ERROR, "malloc failed.\n");
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_dns_recv_addr(request, from, from_len) != 0) {
|
if (_dns_recv_addr(request, from, from_len) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
@@ -1017,6 +1034,45 @@ errout:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct dns_request *request = NULL;
|
||||||
|
|
||||||
|
request = malloc(sizeof(*request));
|
||||||
|
if (request == NULL) {
|
||||||
|
tlog(TLOG_ERROR, "malloc failed.\n");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
memset(request, 0, sizeof(*request));
|
||||||
|
pthread_mutex_init(&request->ip_map_lock, 0);
|
||||||
|
atomic_set(&request->adblock, 0);
|
||||||
|
request->ping_ttl_v4 = -1;
|
||||||
|
request->ping_ttl_v6 = -1;
|
||||||
|
request->prefetch = 1;
|
||||||
|
request->qtype = qtype;
|
||||||
|
request->rcode = DNS_RC_SERVFAIL;
|
||||||
|
|
||||||
|
request->id = 0;
|
||||||
|
hash_init(request->ip_map);
|
||||||
|
strncpy(request->domain, domain, DNS_MAX_CNAME_LEN);
|
||||||
|
|
||||||
|
tlog(TLOG_INFO, "prefetch domain %s, qtype = %d\n", request->domain, qtype);
|
||||||
|
|
||||||
|
_dns_server_request_get(request);
|
||||||
|
pthread_mutex_lock(&server.request_list_lock);
|
||||||
|
list_add_tail(&request->list, &server.request_list);
|
||||||
|
pthread_mutex_unlock(&server.request_list_lock);
|
||||||
|
|
||||||
|
_dns_server_request_get(request);
|
||||||
|
request->send_tick = get_tick_count();
|
||||||
|
dns_client_query(request->domain, qtype, dns_server_resolve_callback, request);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int _dns_server_process(unsigned long now)
|
static int _dns_server_process(unsigned long now)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@@ -1079,13 +1135,25 @@ void _dns_server_tcp_ping_check(struct dns_request *request)
|
|||||||
request->has_ping_tcp = 1;
|
request->has_ping_tcp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
|
||||||
|
{
|
||||||
|
tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d", dns_cache->domain, dns_cache->qtype, dns_cache->ttl);
|
||||||
|
if (_dns_server_prefetch_request(dns_cache->domain, dns_cache->qtype) != 0) {
|
||||||
|
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->domain, dns_cache->qtype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _dns_server_period_run_second(void)
|
void _dns_server_period_run_second(void)
|
||||||
{
|
{
|
||||||
static unsigned int sec = 0;
|
static unsigned int sec = 0;
|
||||||
sec++;
|
sec++;
|
||||||
|
|
||||||
if (sec % 2 == 0) {
|
if (sec % 2 == 0) {
|
||||||
dns_cache_invalidate();
|
if (dns_conf_prefetch) {
|
||||||
|
dns_cache_invalidate(_dns_server_prefetch_domain, 3);
|
||||||
|
} else {
|
||||||
|
dns_cache_invalidate(NULL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -198,8 +198,8 @@ int smartdns_init(void)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tlog_setlogscreen(1); */
|
tlog_setlogscreen(1);
|
||||||
tlog_setlevel(dns_conf_log_level);
|
tlog_setlevel(TLOG_INFO);
|
||||||
|
|
||||||
if (dns_conf_server_num <= 0) {
|
if (dns_conf_server_num <= 0) {
|
||||||
if (smartdns_load_from_resolv() != 0) {
|
if (smartdns_load_from_resolv() != 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user