dns_cache: separate DNS cache
This commit is contained in:
117
src/dns_cache.c
117
src/dns_cache.c
@@ -30,7 +30,7 @@
|
|||||||
#define DNS_CACHE_HITNUM_STEP_MAX 6
|
#define DNS_CACHE_HITNUM_STEP_MAX 6
|
||||||
|
|
||||||
struct dns_cache_head {
|
struct dns_cache_head {
|
||||||
DECLARE_HASHTABLE(cache_hash, 10);
|
DECLARE_HASHTABLE(cache_hash, 16);
|
||||||
struct list_head cache_list;
|
struct list_head cache_list;
|
||||||
struct list_head inactive_list;
|
struct list_head inactive_list;
|
||||||
atomic_t num;
|
atomic_t num;
|
||||||
@@ -128,14 +128,14 @@ enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data)
|
|||||||
return cache_data->head.cache_type;
|
return cache_data->head.cache_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t dns_cache_get_query_flag(struct dns_cache_data *cache_data)
|
uint32_t dns_cache_get_query_flag(struct dns_cache *dns_cache)
|
||||||
{
|
{
|
||||||
return cache_data->head.query_flag;
|
return dns_cache->info.query_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *dns_cache_get_dns_group_name(struct dns_cache_data *cache_data)
|
const char *dns_cache_get_dns_group_name(struct dns_cache *dns_cache)
|
||||||
{
|
{
|
||||||
return cache_data->head.dns_group_name;
|
return dns_cache->info.dns_group_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_cache_data_free(struct dns_cache_data *data)
|
void dns_cache_data_free(struct dns_cache_data *data)
|
||||||
@@ -161,8 +161,7 @@ struct dns_cache_data *dns_cache_new_data(void)
|
|||||||
return (struct dns_cache_data *)cache_addr;
|
return (struct dns_cache_data *)cache_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, char *cname, int cname_ttl)
|
||||||
int cname_ttl)
|
|
||||||
{
|
{
|
||||||
if (dns_cache == NULL) {
|
if (dns_cache == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
@@ -185,13 +184,6 @@ void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, struct dns_cache_q
|
|||||||
cache_addr->addr_data.cname_ttl = cname_ttl;
|
cache_addr->addr_data.cname_ttl = cname_ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query_option) {
|
|
||||||
cache_addr->head.query_flag = query_option->query_flag;
|
|
||||||
if (query_option->dns_group_name) {
|
|
||||||
safe_strncpy(cache_addr->head.dns_group_name, query_option->dns_group_name, DNS_CACHE_GROUP_NAME_LEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_addr->addr_data.soa = 1;
|
cache_addr->addr_data.soa = 1;
|
||||||
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
||||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||||
@@ -199,8 +191,8 @@ errout:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, char *cname, int cname_ttl, unsigned char *addr,
|
||||||
int cname_ttl, unsigned char *addr, int addr_len)
|
int addr_len)
|
||||||
{
|
{
|
||||||
if (dns_cache == NULL) {
|
if (dns_cache == NULL) {
|
||||||
goto errout;
|
goto errout;
|
||||||
@@ -224,21 +216,13 @@ void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, struct dns_cache_
|
|||||||
cache_addr->addr_data.cname_ttl = cname_ttl;
|
cache_addr->addr_data.cname_ttl = cname_ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query_option) {
|
|
||||||
cache_addr->head.query_flag = query_option->query_flag;
|
|
||||||
if (query_option->dns_group_name) {
|
|
||||||
safe_strncpy(cache_addr->head.dns_group_name, query_option->dns_group_name, DNS_CACHE_GROUP_NAME_LEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
cache_addr->head.cache_type = CACHE_TYPE_ADDR;
|
||||||
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head);
|
||||||
errout:
|
errout:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_cache_data *dns_cache_new_data_packet(struct dns_cache_query_option *query_option, void *packet,
|
struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len)
|
||||||
size_t packet_len)
|
|
||||||
{
|
{
|
||||||
struct dns_cache_packet *cache_packet = NULL;
|
struct dns_cache_packet *cache_packet = NULL;
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
@@ -255,19 +239,13 @@ struct dns_cache_data *dns_cache_new_data_packet(struct dns_cache_query_option *
|
|||||||
memcpy(cache_packet->data, packet, packet_len);
|
memcpy(cache_packet->data, packet, packet_len);
|
||||||
memset(&cache_packet->head, 0, sizeof(cache_packet->head));
|
memset(&cache_packet->head, 0, sizeof(cache_packet->head));
|
||||||
|
|
||||||
if (query_option) {
|
|
||||||
cache_packet->head.query_flag = query_option->query_flag;
|
|
||||||
if (query_option->dns_group_name) {
|
|
||||||
strncpy(cache_packet->head.dns_group_name, query_option->dns_group_name, DNS_CACHE_GROUP_NAME_LEN - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cache_packet->head.cache_type = CACHE_TYPE_PACKET;
|
cache_packet->head.cache_type = CACHE_TYPE_PACKET;
|
||||||
cache_packet->head.size = packet_len;
|
cache_packet->head.size = packet_len;
|
||||||
|
|
||||||
return (struct dns_cache_data *)cache_packet;
|
return (struct dns_cache_data *)cache_packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, int inactive,
|
static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int inactive,
|
||||||
struct dns_cache_data *cache_data)
|
struct dns_cache_data *cache_data)
|
||||||
{
|
{
|
||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
@@ -278,9 +256,9 @@ static int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* lookup existing cache */
|
/* lookup existing cache */
|
||||||
dns_cache = dns_cache_lookup(domain, qtype);
|
dns_cache = dns_cache_lookup(cache_key);
|
||||||
if (dns_cache == NULL) {
|
if (dns_cache == NULL) {
|
||||||
return dns_cache_insert(domain, ttl, qtype, speed, cache_data);
|
return dns_cache_insert(cache_key, ttl, speed, cache_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ttl < DNS_CACHE_TTL_MIN) {
|
if (ttl < DNS_CACHE_TTL_MIN) {
|
||||||
@@ -291,7 +269,8 @@ static int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed
|
|||||||
pthread_mutex_lock(&dns_cache_head.lock);
|
pthread_mutex_lock(&dns_cache_head.lock);
|
||||||
dns_cache->del_pending = 0;
|
dns_cache->del_pending = 0;
|
||||||
dns_cache->info.ttl = ttl;
|
dns_cache->info.ttl = ttl;
|
||||||
dns_cache->info.qtype = qtype;
|
dns_cache->info.qtype = cache_key->qtype;
|
||||||
|
dns_cache->info.query_flag = cache_key->query_flag;
|
||||||
dns_cache->info.ttl = ttl;
|
dns_cache->info.ttl = ttl;
|
||||||
dns_cache->info.speed = speed;
|
dns_cache->info.speed = speed;
|
||||||
old_cache_data = dns_cache->cache_data;
|
old_cache_data = dns_cache->cache_data;
|
||||||
@@ -314,31 +293,42 @@ static int _dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, struct dns_cache_data *cache_data)
|
int dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, struct dns_cache_data *cache_data)
|
||||||
{
|
{
|
||||||
return _dns_cache_replace(domain, ttl, qtype, speed, 0, cache_data);
|
return _dns_cache_replace(cache_key, ttl, speed, 0, cache_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_cache_replace_inactive(char *domain, int ttl, dns_type_t qtype, int speed, struct dns_cache_data *cache_data)
|
int dns_cache_replace_inactive(struct dns_cache_key *cache_key, int ttl, int speed, struct dns_cache_data *cache_data)
|
||||||
{
|
{
|
||||||
return _dns_cache_replace(domain, ttl, qtype, speed, 1, cache_data);
|
return _dns_cache_replace(cache_key, ttl, speed, 1, cache_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _dns_cache_remove_by_domain(const char *domain, dns_type_t qtype)
|
static void _dns_cache_remove_by_domain(struct dns_cache_key *cache_key)
|
||||||
{
|
{
|
||||||
uint32_t key = 0;
|
uint32_t key = 0;
|
||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
|
|
||||||
key = hash_string(domain);
|
key = hash_string(cache_key->domain);
|
||||||
key = jhash(&qtype, sizeof(qtype), key);
|
key = jhash(&cache_key->qtype, sizeof(cache_key->qtype), key);
|
||||||
|
key = hash_string_initval(cache_key->dns_group_name, key);
|
||||||
|
key = jhash(&cache_key->query_flag, sizeof(cache_key->query_flag), key);
|
||||||
|
|
||||||
pthread_mutex_lock(&dns_cache_head.lock);
|
pthread_mutex_lock(&dns_cache_head.lock);
|
||||||
hash_for_each_possible(dns_cache_head.cache_hash, dns_cache, node, key)
|
hash_for_each_possible(dns_cache_head.cache_hash, dns_cache, node, key)
|
||||||
{
|
{
|
||||||
if (dns_cache->info.qtype != qtype) {
|
if (dns_cache->info.qtype != cache_key->qtype) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(domain, dns_cache->info.domain, DNS_MAX_CNAME_LEN) != 0) {
|
if (dns_cache->info.query_flag != cache_key->query_flag) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(cache_key->domain, dns_cache->info.domain, DNS_MAX_CNAME_LEN) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(dns_cache->info.dns_group_name, cache_key->dns_group_name, DNS_MAX_CNAME_LEN) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +345,12 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data
|
|||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
|
|
||||||
/* if cache already exists, free */
|
/* if cache already exists, free */
|
||||||
_dns_cache_remove_by_domain(info->domain, info->qtype);
|
struct dns_cache_key cache_key;
|
||||||
|
cache_key.qtype = info->qtype;
|
||||||
|
cache_key.query_flag = info->query_flag;
|
||||||
|
cache_key.domain = info->domain;
|
||||||
|
cache_key.dns_group_name = info->dns_group_name;
|
||||||
|
_dns_cache_remove_by_domain(&cache_key);
|
||||||
|
|
||||||
dns_cache = malloc(sizeof(*dns_cache));
|
dns_cache = malloc(sizeof(*dns_cache));
|
||||||
if (dns_cache == NULL) {
|
if (dns_cache == NULL) {
|
||||||
@@ -365,6 +360,8 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data
|
|||||||
memset(dns_cache, 0, sizeof(*dns_cache));
|
memset(dns_cache, 0, sizeof(*dns_cache));
|
||||||
key = hash_string(info->domain);
|
key = hash_string(info->domain);
|
||||||
key = jhash(&info->qtype, sizeof(info->qtype), key);
|
key = jhash(&info->qtype, sizeof(info->qtype), key);
|
||||||
|
key = hash_string_initval(info->dns_group_name, key);
|
||||||
|
key = jhash(&info->query_flag, sizeof(info->query_flag), key);
|
||||||
atomic_set(&dns_cache->ref, 1);
|
atomic_set(&dns_cache->ref, 1);
|
||||||
memcpy(&dns_cache->info, info, sizeof(*info));
|
memcpy(&dns_cache->info, info, sizeof(*info));
|
||||||
dns_cache->del_pending = 0;
|
dns_cache->del_pending = 0;
|
||||||
@@ -393,11 +390,11 @@ errout:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_cache_insert(char *domain, int ttl, dns_type_t qtype, int speed, struct dns_cache_data *cache_data)
|
int dns_cache_insert(struct dns_cache_key *cache_key, int ttl, int speed, struct dns_cache_data *cache_data)
|
||||||
{
|
{
|
||||||
struct dns_cache_info info;
|
struct dns_cache_info info;
|
||||||
|
|
||||||
if (cache_data == NULL || domain == NULL) {
|
if (cache_data == NULL || cache_key == NULL || cache_key->dns_group_name == NULL || cache_key->domain == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,8 +408,10 @@ int dns_cache_insert(char *domain, int ttl, dns_type_t qtype, int speed, struct
|
|||||||
}
|
}
|
||||||
|
|
||||||
info.hitnum = 3;
|
info.hitnum = 3;
|
||||||
safe_strncpy(info.domain, domain, DNS_MAX_CNAME_LEN);
|
safe_strncpy(info.domain, cache_key->domain, DNS_MAX_CNAME_LEN);
|
||||||
info.qtype = qtype;
|
info.qtype = cache_key->qtype;
|
||||||
|
safe_strncpy(info.dns_group_name, cache_key->dns_group_name, DNS_GROUP_NAME_LEN);
|
||||||
|
info.query_flag = cache_key->query_flag;
|
||||||
info.ttl = ttl;
|
info.ttl = ttl;
|
||||||
info.hitnum_update_add = DNS_CACHE_HITNUM_STEP;
|
info.hitnum_update_add = DNS_CACHE_HITNUM_STEP;
|
||||||
info.speed = speed;
|
info.speed = speed;
|
||||||
@@ -422,7 +421,7 @@ int dns_cache_insert(char *domain, int ttl, dns_type_t qtype, int speed, struct
|
|||||||
return _dns_cache_insert(&info, cache_data, &dns_cache_head.cache_list);
|
return _dns_cache_insert(&info, cache_data, &dns_cache_head.cache_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
|
struct dns_cache *dns_cache_lookup(struct dns_cache_key *cache_key)
|
||||||
{
|
{
|
||||||
uint32_t key = 0;
|
uint32_t key = 0;
|
||||||
struct dns_cache *dns_cache = NULL;
|
struct dns_cache *dns_cache = NULL;
|
||||||
@@ -433,19 +432,29 @@ struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
key = hash_string(domain);
|
key = hash_string(cache_key->domain);
|
||||||
key = jhash(&qtype, sizeof(qtype), key);
|
key = jhash(&cache_key->qtype, sizeof(cache_key->qtype), key);
|
||||||
|
key = hash_string_initval(cache_key->dns_group_name, key);
|
||||||
|
key = jhash(&cache_key->query_flag, sizeof(cache_key->query_flag), key);
|
||||||
|
|
||||||
time(&now);
|
time(&now);
|
||||||
/* find cache */
|
/* find cache */
|
||||||
pthread_mutex_lock(&dns_cache_head.lock);
|
pthread_mutex_lock(&dns_cache_head.lock);
|
||||||
hash_for_each_possible(dns_cache_head.cache_hash, dns_cache, node, key)
|
hash_for_each_possible(dns_cache_head.cache_hash, dns_cache, node, key)
|
||||||
{
|
{
|
||||||
if (dns_cache->info.qtype != qtype) {
|
if (dns_cache->info.qtype != cache_key->qtype) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(domain, dns_cache->info.domain, DNS_MAX_CNAME_LEN) != 0) {
|
if (strncmp(cache_key->domain, dns_cache->info.domain, DNS_MAX_CNAME_LEN) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(cache_key->dns_group_name, dns_cache->info.dns_group_name, DNS_GROUP_NAME_LEN) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache_key->query_flag != dns_cache->info.query_flag) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
|
#include "dns_conf.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "hashtable.h"
|
#include "hashtable.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
@@ -48,15 +49,8 @@ enum CACHE_RECORD_TYPE {
|
|||||||
CACHE_RECORD_TYPE_INACTIVE,
|
CACHE_RECORD_TYPE_INACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dns_cache_query_option {
|
|
||||||
uint32_t query_flag;
|
|
||||||
const char *dns_group_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dns_cache_data_head {
|
struct dns_cache_data_head {
|
||||||
enum CACHE_TYPE cache_type;
|
enum CACHE_TYPE cache_type;
|
||||||
uint32_t query_flag;
|
|
||||||
char dns_group_name[DNS_CACHE_GROUP_NAME_LEN];
|
|
||||||
int is_soa;
|
int is_soa;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
};
|
};
|
||||||
@@ -87,13 +81,15 @@ struct dns_cache_packet {
|
|||||||
|
|
||||||
struct dns_cache_info {
|
struct dns_cache_info {
|
||||||
char domain[DNS_MAX_CNAME_LEN];
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
dns_type_t qtype;
|
||||||
|
char dns_group_name[DNS_GROUP_NAME_LEN];
|
||||||
|
uint32_t query_flag;
|
||||||
int ttl;
|
int ttl;
|
||||||
int hitnum;
|
int hitnum;
|
||||||
int speed;
|
int speed;
|
||||||
int hitnum_update_add;
|
int hitnum_update_add;
|
||||||
time_t insert_time;
|
time_t insert_time;
|
||||||
time_t replace_time;
|
time_t replace_time;
|
||||||
dns_type_t qtype;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dns_cache_record {
|
struct dns_cache_record {
|
||||||
@@ -120,26 +116,32 @@ struct dns_cache_file {
|
|||||||
uint32_t cache_number;
|
uint32_t cache_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dns_cache_key {
|
||||||
|
const char *domain;
|
||||||
|
dns_type_t qtype;
|
||||||
|
const char *dns_group_name;
|
||||||
|
uint32_t query_flag;
|
||||||
|
};
|
||||||
|
|
||||||
enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data);
|
enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data);
|
||||||
|
|
||||||
uint32_t dns_cache_get_query_flag(struct dns_cache_data *cache_data);
|
uint32_t dns_cache_get_query_flag(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
const char *dns_cache_get_dns_group_name(struct dns_cache_data *cache_data);
|
const char *dns_cache_get_dns_group_name(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
void dns_cache_data_free(struct dns_cache_data *data);
|
void dns_cache_data_free(struct dns_cache_data *data);
|
||||||
|
|
||||||
struct dns_cache_data *dns_cache_new_data_packet(struct dns_cache_query_option *query_option, void *packet,
|
struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len);
|
||||||
size_t packet_len);
|
|
||||||
|
|
||||||
int dns_cache_init(int size, int enable_inactive, int inactive_list_expired);
|
int dns_cache_init(int size, int enable_inactive, int inactive_list_expired);
|
||||||
|
|
||||||
int dns_cache_replace(char *domain, int ttl, dns_type_t qtype, int speed, struct dns_cache_data *cache_data);
|
int dns_cache_replace(struct dns_cache_key *key, int ttl, int speed, struct dns_cache_data *cache_data);
|
||||||
|
|
||||||
int dns_cache_replace_inactive(char *domain, int ttl, dns_type_t qtype, int speed, struct dns_cache_data *cache_data);
|
int dns_cache_replace_inactive(struct dns_cache_key *key, int ttl, int speed, struct dns_cache_data *cache_data);
|
||||||
|
|
||||||
int dns_cache_insert(char *domain, int ttl, dns_type_t qtype, int speed, struct dns_cache_data *cache_data);
|
int dns_cache_insert(struct dns_cache_key *key, int ttl, int speed, struct dns_cache_data *cache_data);
|
||||||
|
|
||||||
struct dns_cache *dns_cache_lookup(char *domain, dns_type_t qtype);
|
struct dns_cache *dns_cache_lookup(struct dns_cache_key *key);
|
||||||
|
|
||||||
void dns_cache_delete(struct dns_cache *dns_cache);
|
void dns_cache_delete(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
@@ -166,11 +168,10 @@ struct dns_cache_data *dns_cache_new_data(void);
|
|||||||
|
|
||||||
struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache);
|
struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache);
|
||||||
|
|
||||||
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, char *cname, int cname_ttl, unsigned char *addr,
|
||||||
int cname_ttl, unsigned char *addr, int addr_len);
|
int addr_len);
|
||||||
|
|
||||||
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, struct dns_cache_query_option *query_option, char *cname,
|
void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, char *cname, int cname_ttl);
|
||||||
int cname_ttl);
|
|
||||||
|
|
||||||
void dns_cache_destroy(void);
|
void dns_cache_destroy(void);
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ struct dns_request_pending_list {
|
|||||||
pthread_mutex_t request_list_lock;
|
pthread_mutex_t request_list_lock;
|
||||||
unsigned short qtype;
|
unsigned short qtype;
|
||||||
char domain[DNS_MAX_CNAME_LEN];
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
uint32_t server_flags;
|
||||||
|
char dns_group_name[DNS_GROUP_NAME_LEN];
|
||||||
struct list_head request_list;
|
struct list_head request_list;
|
||||||
struct hlist_node node;
|
struct hlist_node node;
|
||||||
};
|
};
|
||||||
@@ -1016,8 +1018,6 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ
|
|||||||
speed = request->ping_time;
|
speed = request->ping_time;
|
||||||
|
|
||||||
if (has_soa) {
|
if (has_soa) {
|
||||||
struct dns_cache_query_option cache_option;
|
|
||||||
|
|
||||||
if (request->dualstack_selection && request->has_ip && request->qtype == DNS_T_AAAA) {
|
if (request->dualstack_selection && request->has_ip && request->qtype == DNS_T_AAAA) {
|
||||||
ttl = _dns_server_get_conf_ttl(request->ip_ttl);
|
ttl = _dns_server_get_conf_ttl(request->ip_ttl);
|
||||||
} else {
|
} else {
|
||||||
@@ -1027,27 +1027,31 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_option.query_flag = request->server_flags;
|
dns_cache_set_data_soa(cache_data, request->cname, request->ttl_cname);
|
||||||
cache_option.dns_group_name = 0;
|
|
||||||
dns_cache_set_data_soa(cache_data, &cache_option, request->cname, request->ttl_cname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "cache %s qtype: %d ttl: %d\n", request->domain, qtype, ttl);
|
tlog(TLOG_DEBUG, "cache %s qtype: %d ttl: %d\n", request->domain, qtype, ttl);
|
||||||
|
|
||||||
/* if doing prefetch, update cache only */
|
/* if doing prefetch, update cache only */
|
||||||
|
struct dns_cache_key cache_key;
|
||||||
|
cache_key.dns_group_name = request->dns_group_name;
|
||||||
|
cache_key.domain = request->domain;
|
||||||
|
cache_key.qtype = request->qtype;
|
||||||
|
cache_key.query_flag = request->server_flags;
|
||||||
|
|
||||||
if (request->prefetch) {
|
if (request->prefetch) {
|
||||||
if (request->prefetch_expired_domain == 0) {
|
if (request->prefetch_expired_domain == 0) {
|
||||||
if (dns_cache_replace(request->domain, ttl, qtype, speed, cache_data) != 0) {
|
if (dns_cache_replace(&cache_key, ttl, speed, cache_data) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dns_cache_replace_inactive(request->domain, ttl, qtype, speed, cache_data) != 0) {
|
if (dns_cache_replace_inactive(&cache_key, ttl, speed, cache_data) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* insert result to cache */
|
/* insert result to cache */
|
||||||
if (dns_cache_insert(request->domain, ttl, qtype, speed, cache_data) != 0) {
|
if (dns_cache_insert(&cache_key, ttl, speed, cache_data) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1068,6 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
|||||||
{
|
{
|
||||||
struct dns_packet *packet = context->packet;
|
struct dns_packet *packet = context->packet;
|
||||||
struct dns_packet *cname_packet = NULL;
|
struct dns_packet *cname_packet = NULL;
|
||||||
struct dns_cache_query_option cache_option;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
@@ -1163,9 +1166,7 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_option.query_flag = request->server_flags;
|
cache_packet = dns_cache_new_data_packet(inpacket_buff, inpacket_len);
|
||||||
cache_option.dns_group_name = request->dns_group_name;
|
|
||||||
cache_packet = dns_cache_new_data_packet(&cache_option, inpacket_buff, inpacket_len);
|
|
||||||
if (cache_packet == NULL) {
|
if (cache_packet == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1180,19 +1181,25 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context)
|
|||||||
tlog(TLOG_DEBUG, "Cache CNAME: %s, qtype: %d, speed: %d", request->cname, request->qtype, speed);
|
tlog(TLOG_DEBUG, "Cache CNAME: %s, qtype: %d, speed: %d", request->cname, request->qtype, speed);
|
||||||
|
|
||||||
/* if doing prefetch, update cache only */
|
/* if doing prefetch, update cache only */
|
||||||
|
struct dns_cache_key cache_key;
|
||||||
|
cache_key.dns_group_name = request->dns_group_name;
|
||||||
|
cache_key.domain = request->cname;
|
||||||
|
cache_key.qtype = context->qtype;
|
||||||
|
cache_key.query_flag = request->server_flags;
|
||||||
|
|
||||||
if (request->prefetch) {
|
if (request->prefetch) {
|
||||||
if (request->prefetch_expired_domain == 0) {
|
if (request->prefetch_expired_domain == 0) {
|
||||||
if (dns_cache_replace(request->cname, ttl, context->qtype, speed, cache_packet) != 0) {
|
if (dns_cache_replace(&cache_key, ttl, speed, cache_packet) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dns_cache_replace_inactive(request->cname, ttl, context->qtype, speed, cache_packet) != 0) {
|
if (dns_cache_replace_inactive(&cache_key, ttl, speed, cache_packet) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* insert result to cache */
|
/* insert result to cache */
|
||||||
if (dns_cache_insert(request->cname, ttl, context->qtype, speed, cache_packet) != 0) {
|
if (dns_cache_insert(&cache_key, ttl, speed, cache_packet) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1208,25 +1215,28 @@ errout:
|
|||||||
|
|
||||||
static int _dns_cache_packet(struct dns_server_post_context *context)
|
static int _dns_cache_packet(struct dns_server_post_context *context)
|
||||||
{
|
{
|
||||||
struct dns_cache_query_option cache_option;
|
|
||||||
struct dns_request *request = context->request;
|
struct dns_request *request = context->request;
|
||||||
|
|
||||||
cache_option.query_flag = request->server_flags;
|
struct dns_cache_data *cache_packet = dns_cache_new_data_packet(context->inpacket, context->inpacket_len);
|
||||||
cache_option.dns_group_name = request->dns_group_name;
|
|
||||||
struct dns_cache_data *cache_packet =
|
|
||||||
dns_cache_new_data_packet(&cache_option, context->inpacket, context->inpacket_len);
|
|
||||||
if (cache_packet == NULL) {
|
if (cache_packet == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if doing prefetch, update cache only */
|
/* if doing prefetch, update cache only */
|
||||||
|
|
||||||
|
struct dns_cache_key cache_key;
|
||||||
|
cache_key.dns_group_name = request->dns_group_name;
|
||||||
|
cache_key.domain = request->domain;
|
||||||
|
cache_key.qtype = context->qtype;
|
||||||
|
cache_key.query_flag = request->server_flags;
|
||||||
|
|
||||||
if (request->prefetch) {
|
if (request->prefetch) {
|
||||||
if (dns_cache_replace(request->domain, context->reply_ttl, context->qtype, -1, cache_packet) != 0) {
|
if (dns_cache_replace(&cache_key, context->reply_ttl, -1, cache_packet) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* insert result to cache */
|
/* insert result to cache */
|
||||||
if (dns_cache_insert(request->domain, context->reply_ttl, context->qtype, -1, cache_packet) != 0) {
|
if (dns_cache_insert(&cache_key, context->reply_ttl, -1, cache_packet) != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1338,11 +1348,7 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
|
|||||||
return _dns_cache_specify_packet(context);
|
return _dns_cache_specify_packet(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_cache_query_option cache_option;
|
struct dns_cache_data *cache_packet = dns_cache_new_data_packet(context->inpacket, context->inpacket_len);
|
||||||
cache_option.query_flag = request->server_flags;
|
|
||||||
cache_option.dns_group_name = request->dns_group_name;
|
|
||||||
struct dns_cache_data *cache_packet =
|
|
||||||
dns_cache_new_data_packet(&cache_option, context->inpacket, context->inpacket_len);
|
|
||||||
if (cache_packet == NULL) {
|
if (cache_packet == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -2009,7 +2015,9 @@ static int _dns_server_set_to_pending_list(struct dns_request *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
key = hash_string(request->domain);
|
key = hash_string(request->domain);
|
||||||
|
key = hash_string_initval(request->dns_group_name, key);
|
||||||
key = jhash(&(request->qtype), sizeof(request->qtype), key);
|
key = jhash(&(request->qtype), sizeof(request->qtype), key);
|
||||||
|
key = jhash(&(request->server_flags), sizeof(request->server_flags), key);
|
||||||
pthread_mutex_lock(&server.request_pending_lock);
|
pthread_mutex_lock(&server.request_pending_lock);
|
||||||
hash_for_each_possible(server.request_pending, pending_list_tmp, node, key)
|
hash_for_each_possible(server.request_pending, pending_list_tmp, node, key)
|
||||||
{
|
{
|
||||||
@@ -2017,6 +2025,14 @@ static int _dns_server_set_to_pending_list(struct dns_request *request)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request->server_flags != pending_list_tmp->server_flags) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(request->dns_group_name, pending_list_tmp->dns_group_name) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp(request->domain, pending_list_tmp->domain, DNS_MAX_CNAME_LEN) != 0) {
|
if (strncmp(request->domain, pending_list_tmp->domain, DNS_MAX_CNAME_LEN) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2037,7 +2053,9 @@ static int _dns_server_set_to_pending_list(struct dns_request *request)
|
|||||||
INIT_LIST_HEAD(&pending_list->request_list);
|
INIT_LIST_HEAD(&pending_list->request_list);
|
||||||
INIT_HLIST_NODE(&pending_list->node);
|
INIT_HLIST_NODE(&pending_list->node);
|
||||||
pending_list->qtype = request->qtype;
|
pending_list->qtype = request->qtype;
|
||||||
|
pending_list->server_flags = request->server_flags;
|
||||||
safe_strncpy(pending_list->domain, request->domain, DNS_MAX_CNAME_LEN);
|
safe_strncpy(pending_list->domain, request->domain, DNS_MAX_CNAME_LEN);
|
||||||
|
safe_strncpy(pending_list->dns_group_name, request->dns_group_name, DNS_GROUP_NAME_LEN);
|
||||||
hash_add(server.request_pending, &pending_list->node, key);
|
hash_add(server.request_pending, &pending_list->node, key);
|
||||||
request->request_pending_list = pending_list;
|
request->request_pending_list = pending_list;
|
||||||
} else {
|
} else {
|
||||||
@@ -3741,7 +3759,13 @@ static int _dns_server_process_cache(struct dns_request *request)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cache = dns_cache_lookup(request->domain, request->qtype);
|
struct dns_cache_key cache_key;
|
||||||
|
cache_key.dns_group_name = request->dns_group_name;
|
||||||
|
cache_key.domain = request->domain;
|
||||||
|
cache_key.qtype = request->qtype;
|
||||||
|
cache_key.query_flag = request->server_flags;
|
||||||
|
|
||||||
|
dns_cache = dns_cache_lookup(&cache_key);
|
||||||
if (dns_cache == NULL) {
|
if (dns_cache == NULL) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -3764,7 +3788,8 @@ static int _dns_server_process_cache(struct dns_request *request)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dualstack_dns_cache = dns_cache_lookup(request->domain, dualstack_qtype);
|
cache_key.qtype = dualstack_qtype;
|
||||||
|
dualstack_dns_cache = dns_cache_lookup(&cache_key);
|
||||||
if (dualstack_dns_cache && dns_cache_is_soa(dualstack_dns_cache) == 0 &&
|
if (dualstack_dns_cache && dns_cache_is_soa(dualstack_dns_cache) == 0 &&
|
||||||
(dualstack_dns_cache->info.speed > 0)) {
|
(dualstack_dns_cache->info.speed > 0)) {
|
||||||
|
|
||||||
@@ -3804,8 +3829,8 @@ out_update_cache:
|
|||||||
dns_query_options.server_flags = request->server_flags;
|
dns_query_options.server_flags = request->server_flags;
|
||||||
dns_query_options.dns_group_name = request->dns_group_name;
|
dns_query_options.dns_group_name = request->dns_group_name;
|
||||||
if (request->conn == NULL) {
|
if (request->conn == NULL) {
|
||||||
dns_query_options.server_flags = dns_cache_get_query_flag(dns_cache->cache_data);
|
dns_query_options.server_flags = dns_cache_get_query_flag(dns_cache);
|
||||||
dns_query_options.dns_group_name = dns_cache_get_dns_group_name(dns_cache->cache_data);
|
dns_query_options.dns_group_name = dns_cache_get_dns_group_name(dns_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_query_options.ecs_enable_flag = 0;
|
dns_query_options.ecs_enable_flag = 0;
|
||||||
@@ -4846,8 +4871,8 @@ static void _dns_server_prefetch_domain(struct dns_cache *dns_cache)
|
|||||||
/* start prefetch domain */
|
/* start prefetch domain */
|
||||||
tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d, hitnum %d", dns_cache->info.domain, dns_cache->info.qtype,
|
tlog(TLOG_DEBUG, "prefetch by cache %s, qtype %d, ttl %d, hitnum %d", dns_cache->info.domain, dns_cache->info.qtype,
|
||||||
dns_cache->info.ttl, hitnum);
|
dns_cache->info.ttl, hitnum);
|
||||||
server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache->cache_data);
|
server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache);
|
||||||
server_query_option.server_flags = dns_cache_get_query_flag(dns_cache->cache_data);
|
server_query_option.server_flags = dns_cache_get_query_flag(dns_cache);
|
||||||
server_query_option.ecs_enable_flag = 0;
|
server_query_option.ecs_enable_flag = 0;
|
||||||
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 0, &server_query_option) != 0) {
|
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 0, &server_query_option) != 0) {
|
||||||
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype);
|
tlog(TLOG_ERROR, "prefetch domain %s, qtype %d, failed.", dns_cache->info.domain, dns_cache->info.qtype);
|
||||||
@@ -4861,8 +4886,8 @@ static void _dns_server_prefetch_expired_domain(struct dns_cache *dns_cache)
|
|||||||
dns_cache->info.qtype, dns_cache->info.ttl);
|
dns_cache->info.qtype, dns_cache->info.ttl);
|
||||||
|
|
||||||
struct dns_server_query_option server_query_option;
|
struct dns_server_query_option server_query_option;
|
||||||
server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache->cache_data);
|
server_query_option.dns_group_name = dns_cache_get_dns_group_name(dns_cache);
|
||||||
server_query_option.server_flags = dns_cache_get_query_flag(dns_cache->cache_data);
|
server_query_option.server_flags = dns_cache_get_query_flag(dns_cache);
|
||||||
server_query_option.ecs_enable_flag = 0;
|
server_query_option.ecs_enable_flag = 0;
|
||||||
|
|
||||||
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 1, &server_query_option) != 0) {
|
if (_dns_server_prefetch_request(dns_cache->info.domain, dns_cache->info.qtype, 1, &server_query_option) != 0) {
|
||||||
|
|||||||
@@ -211,9 +211,9 @@ static inline uint32_t hash32_ptr(const void *ptr)
|
|||||||
return (uint32_t)val;
|
return (uint32_t)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t hash_string(const char *s)
|
static inline uint32_t hash_string_initval(const char *s, uint32_t initval)
|
||||||
{
|
{
|
||||||
uint32_t h = 0;
|
uint32_t h = initval;
|
||||||
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
h = h * 31 + *s;
|
h = h * 31 + *s;
|
||||||
@@ -223,6 +223,11 @@ static inline uint32_t hash_string(const char *s)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t hash_string(const char *s)
|
||||||
|
{
|
||||||
|
return hash_string_initval(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t hash_string_array(const char **a)
|
static inline uint32_t hash_string_array(const char **a)
|
||||||
{
|
{
|
||||||
uint32_t h = 0;
|
uint32_t h = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user