diff --git a/src/dns_cache.c b/src/dns_cache.c index 4df641f89c..146e2b39f9 100644 --- a/src/dns_cache.c +++ b/src/dns_cache.c @@ -111,11 +111,6 @@ static void _dns_cache_remove(struct dns_cache *dns_cache) dns_cache_release(dns_cache); } -enum CACHE_TYPE dns_cache_data_type(struct dns_cache_data *cache_data) -{ - return cache_data->head.cache_type; -} - uint32_t dns_cache_get_query_flag(struct dns_cache *dns_cache) { return dns_cache->info.query_flag; @@ -126,83 +121,6 @@ const char *dns_cache_get_dns_group_name(struct dns_cache *dns_cache) return dns_cache->info.dns_group_name; } -struct dns_cache_data *dns_cache_new_data_addr(void) -{ - struct dns_cache_addr *cache_addr = malloc(sizeof(struct dns_cache_addr)); - memset(cache_addr, 0, sizeof(struct dns_cache_addr)); - if (cache_addr == NULL) { - return NULL; - } - - cache_addr->head.cache_type = CACHE_TYPE_NONE; - cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head); - cache_addr->head.magic = MAGIC_CACHE_DATA; - atomic_set(&cache_addr->head.ref, 1); - - return (struct dns_cache_data *)cache_addr; -} - -void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, char *cname, int cname_ttl) -{ - if (dns_cache == NULL) { - goto errout; - } - - dns_cache->head.is_soa = 1; - if (dns_cache->head.cache_type == CACHE_TYPE_PACKET) { - return; - } - - struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache; - if (cache_addr == NULL) { - goto errout; - } - - memset(cache_addr->addr_data.addr, 0, sizeof(cache_addr->addr_data.addr)); - - if (cname) { - safe_strncpy(cache_addr->addr_data.cname, cname, DNS_MAX_CNAME_LEN); - cache_addr->addr_data.cname_ttl = cname_ttl; - } - - cache_addr->addr_data.soa = 1; - cache_addr->head.cache_type = CACHE_TYPE_ADDR; - cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head); -errout: - return; -} - -void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, char *cname, int cname_ttl, unsigned char *addr, - int addr_len) -{ - if (dns_cache == NULL) { - goto errout; - } - - struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache; - if (cache_addr == NULL) { - goto errout; - } - - if (addr_len == DNS_RR_A_LEN) { - memcpy(cache_addr->addr_data.addr, addr, DNS_RR_A_LEN); - } else if (addr_len != DNS_RR_AAAA_LEN) { - memcpy(cache_addr->addr_data.addr, addr, DNS_RR_AAAA_LEN); - } else { - goto errout; - } - - if (cname) { - safe_strncpy(cache_addr->addr_data.cname, cname, DNS_MAX_CNAME_LEN); - cache_addr->addr_data.cname_ttl = cname_ttl; - } - - cache_addr->head.cache_type = CACHE_TYPE_ADDR; - cache_addr->head.size = sizeof(struct dns_cache_addr) - sizeof(struct dns_cache_data_head); -errout: - return; -} - struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len) { struct dns_cache_packet *cache_packet = NULL; @@ -220,7 +138,6 @@ struct dns_cache_data *dns_cache_new_data_packet(void *packet, size_t packet_len memcpy(cache_packet->data, packet, packet_len); memset(&cache_packet->head, 0, sizeof(cache_packet->head)); - cache_packet->head.cache_type = CACHE_TYPE_PACKET; cache_packet->head.size = packet_len; cache_packet->head.magic = MAGIC_CACHE_DATA; atomic_set(&cache_packet->head.ref, 1); @@ -254,7 +171,7 @@ static void dns_cache_expired(struct tw_timer_list *timer, void *data, unsigned dns_timer_mod(&dns_cache->timer, 5); } -static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int timeout, int update_time, +static int _dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int ttl, int speed, int timeout, int update_time, struct dns_cache_data *cache_data) { struct dns_cache *dns_cache = NULL; @@ -267,7 +184,7 @@ static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int spee /* lookup existing cache */ dns_cache = dns_cache_lookup(cache_key); if (dns_cache == NULL) { - return dns_cache_insert(cache_key, ttl, speed, timeout, cache_data); + return dns_cache_insert(cache_key, rcode, ttl, speed, timeout, cache_data); } if (ttl < DNS_CACHE_TTL_MIN) { @@ -303,10 +220,10 @@ static int _dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int spee return 0; } -int dns_cache_replace(struct dns_cache_key *cache_key, int ttl, int speed, int timeout, int update_time, +int dns_cache_replace(struct dns_cache_key *cache_key, int rcode, int ttl, int speed, int timeout, int update_time, struct dns_cache_data *cache_data) { - return _dns_cache_replace(cache_key, ttl, speed, timeout, update_time, cache_data); + return _dns_cache_replace(cache_key, rcode, ttl, speed, timeout, update_time, cache_data); } static void _dns_cache_remove_by_domain(struct dns_cache_key *cache_key) @@ -403,7 +320,7 @@ static int _dns_cache_insert(struct dns_cache_info *info, struct dns_cache_data return -1; } -int dns_cache_insert(struct dns_cache_key *cache_key, int ttl, int speed, int timeout, +int dns_cache_insert(struct dns_cache_key *cache_key, int rcode, int ttl, int speed, int timeout, struct dns_cache_data *cache_data) { struct dns_cache_info info; @@ -432,6 +349,7 @@ int dns_cache_insert(struct dns_cache_key *cache_key, int ttl, int speed, int ti info.speed = speed; info.timeout = timeout; info.is_visited = 1; + info.rcode = rcode; time(&info.insert_time); time(&info.replace_time); @@ -502,60 +420,6 @@ int dns_cache_get_ttl(struct dns_cache *dns_cache) return ttl; } -int dns_cache_get_cname_ttl(struct dns_cache *dns_cache) -{ - time_t now = 0; - int ttl = 0; - time(&now); - - struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache_get_data(dns_cache); - if (cache_addr == NULL) { - ttl = 0; - goto out; - } - - if (cache_addr->head.cache_type != CACHE_TYPE_ADDR) { - ttl = 0; - goto out; - } - - ttl = dns_cache->info.insert_time + cache_addr->addr_data.cname_ttl - now; - if (ttl < 0) { - ttl = 0; - goto out; - } - - int addr_ttl = dns_cache_get_ttl(dns_cache); - if (ttl < addr_ttl && ttl < 0) { - return addr_ttl; - } - - if (ttl < 0) { - ttl = 0; - goto out; - } - -out: - if (cache_addr) { - dns_cache_data_put((struct dns_cache_data *)cache_addr); - } - - return ttl; -} - -int dns_cache_is_soa(struct dns_cache *dns_cache) -{ - if (dns_cache == NULL) { - return 0; - } - - if (dns_cache->cache_data->head.is_soa) { - return 1; - } - - return 0; -} - struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache) { struct dns_cache_data *cache_data; @@ -928,6 +792,6 @@ void dns_cache_destroy(void) const char *dns_cache_file_version(void) { - const char *version = "cache ver 1.2"; + const char *version = "cache ver 1.3"; return version; } diff --git a/src/dns_cache.h b/src/dns_cache.h index 8e0dfb8e8a..0b6cf07bb2 100644 --- a/src/dns_cache.h +++ b/src/dns_cache.h @@ -40,16 +40,8 @@ extern "C" { #define MAGIC_CACHE_DATA 0x61546144 #define MAGIC_RECORD 0x64526352 -enum CACHE_TYPE { - CACHE_TYPE_NONE, - CACHE_TYPE_ADDR, - CACHE_TYPE_PACKET, -}; - struct dns_cache_data_head { - enum CACHE_TYPE cache_type; atomic_t ref; - int is_soa; ssize_t size; uint32_t magic; }; @@ -84,6 +76,7 @@ struct dns_cache_info { char dns_group_name[DNS_GROUP_NAME_LEN]; uint32_t query_flag; int ttl; + int rcode; int hitnum; int speed; int timeout; @@ -125,8 +118,6 @@ struct dns_cache_key { uint32_t query_flag; }; -enum CACHE_TYPE dns_cache_data_type(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 *dns_cache); @@ -137,10 +128,11 @@ typedef int (*dns_cache_callback)(struct dns_cache *dns_cache); int dns_cache_init(int size, dns_cache_callback timeout_callback); -int dns_cache_replace(struct dns_cache_key *key, int ttl, int speed, int tiemout, int update_time, +int dns_cache_replace(struct dns_cache_key *key, int rcode, int ttl, int speed, int timeout, int update_time, struct dns_cache_data *cache_data); -int dns_cache_insert(struct dns_cache_key *key, int ttl, int speed, int timeout, struct dns_cache_data *cache_data); +int dns_cache_insert(struct dns_cache_key *key, int rcode, int ttl, int speed, int timeout, + struct dns_cache_data *cache_data); struct dns_cache *dns_cache_lookup(struct dns_cache_key *key); @@ -158,23 +150,12 @@ void dns_cache_update(struct dns_cache *dns_cache); int dns_cache_get_ttl(struct dns_cache *dns_cache); -int dns_cache_get_cname_ttl(struct dns_cache *dns_cache); - -int dns_cache_is_soa(struct dns_cache *dns_cache); - -struct dns_cache_data *dns_cache_new_data_addr(void); - struct dns_cache_data *dns_cache_get_data(struct dns_cache *dns_cache); void dns_cache_data_get(struct dns_cache_data *cache_data); void dns_cache_data_put(struct dns_cache_data *cache_data); -void dns_cache_set_data_addr(struct dns_cache_data *dns_cache, char *cname, int cname_ttl, unsigned char *addr, - int addr_len); - -void dns_cache_set_data_soa(struct dns_cache_data *dns_cache, char *cname, int cname_ttl); - void dns_cache_destroy(void); int dns_cache_load(const char *file); diff --git a/src/dns_server.c b/src/dns_server.c index 20ecf97f37..128441b7a5 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -1261,6 +1261,11 @@ static inline int _dns_server_expired_cache_ttl(struct dns_cache *cache) static int _dns_server_get_cache_timeout(struct dns_request *request, struct dns_cache_key *cache_key, int ttl) { int timeout = 0; + + if (request->rcode != DNS_RC_NOERROR) { + return ttl + 1; + } + if (dns_conf_prefetch) { if (dns_conf_serve_expired) { timeout = dns_conf_serve_expired_prefetch_time; @@ -1300,12 +1305,10 @@ static int _dns_server_get_cache_timeout(struct dns_request *request, struct dns return timeout; } -static int _dns_server_request_update_cache(struct dns_request *request, dns_type_t qtype, - struct dns_cache_data *cache_data, int has_soa, int cache_ttl) +static int _dns_server_request_update_cache(struct dns_request *request, int speed, dns_type_t qtype, + struct dns_cache_data *cache_data, int cache_ttl) { int ttl = 0; - int speed = 0; - if (qtype != DNS_T_A && qtype != DNS_T_AAAA) { goto errout; } @@ -1315,20 +1318,6 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ } else { ttl = _dns_server_get_conf_ttl(request, request->ip_ttl); } - speed = request->ping_time; - - if (has_soa) { - if (request->dualstack_selection && request->has_ip && request->qtype == DNS_T_AAAA) { - ttl = _dns_server_get_conf_ttl(request, request->ip_ttl); - } else { - ttl = dns_conf_rr_ttl; - if (ttl == 0) { - ttl = _dns_server_get_conf_ttl(request, request->ip_ttl); - } - } - - dns_cache_set_data_soa(cache_data, request->cname, request->ttl_cname); - } tlog(TLOG_DEBUG, "cache %s qtype: %d ttl: %d\n", request->domain, qtype, ttl); @@ -1340,14 +1329,15 @@ static int _dns_server_request_update_cache(struct dns_request *request, dns_typ cache_key.query_flag = request->server_flags; if (request->prefetch) { - if (dns_cache_replace(&cache_key, ttl, speed, _dns_server_get_cache_timeout(request, &cache_key, ttl), + if (dns_cache_replace(&cache_key, request->rcode, ttl, speed, + _dns_server_get_cache_timeout(request, &cache_key, ttl), !request->prefetch_expired_domain, cache_data) != 0) { goto errout; } } else { /* insert result to cache */ - if (dns_cache_insert(&cache_key, ttl, speed, _dns_server_get_cache_timeout(request, NULL, ttl), cache_data) != - 0) { + if (dns_cache_insert(&cache_key, request->rcode, ttl, speed, _dns_server_get_cache_timeout(request, NULL, ttl), + cache_data) != 0) { goto errout; } } @@ -1484,14 +1474,15 @@ static int _dns_cache_cname_packet(struct dns_server_post_context *context) cache_key.query_flag = request->server_flags; if (request->prefetch) { - if (dns_cache_replace(&cache_key, ttl, speed, _dns_server_get_cache_timeout(request, &cache_key, ttl), + if (dns_cache_replace(&cache_key, request->rcode, ttl, speed, + _dns_server_get_cache_timeout(request, &cache_key, ttl), !request->prefetch_expired_domain, cache_packet) != 0) { goto errout; } } else { /* insert result to cache */ - if (dns_cache_insert(&cache_key, ttl, speed, _dns_server_get_cache_timeout(request, NULL, ttl), cache_packet) != - 0) { + if (dns_cache_insert(&cache_key, request->rcode, ttl, speed, _dns_server_get_cache_timeout(request, NULL, ttl), + cache_packet) != 0) { goto errout; } } @@ -1523,14 +1514,14 @@ static int _dns_cache_packet(struct dns_server_post_context *context) cache_key.query_flag = request->server_flags; if (request->prefetch) { - if (dns_cache_replace(&cache_key, context->reply_ttl, -1, + if (dns_cache_replace(&cache_key, request->rcode, context->reply_ttl, -1, _dns_server_get_cache_timeout(request, &cache_key, context->reply_ttl), !request->prefetch_expired_domain, cache_packet) != 0) { goto errout; } } else { /* insert result to cache */ - if (dns_cache_insert(&cache_key, context->reply_ttl, -1, + if (dns_cache_insert(&cache_key, request->rcode, context->reply_ttl, -1, _dns_server_get_cache_timeout(request, NULL, context->reply_ttl), cache_packet) != 0) { goto errout; } @@ -1611,7 +1602,7 @@ static int _dns_cache_specify_packet(struct dns_server_post_context *context) static int _dns_cache_reply_packet(struct dns_server_post_context *context) { struct dns_request *request = context->request; - int has_soa = request->has_soa; + int speed = -1; if (context->do_cache == 0 || request->no_cache == 1) { return 0; } @@ -1640,15 +1631,12 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context) return -1; } - if (context->ip_num > 0) { - has_soa = 0; - } - + speed = request->ping_time; if (context->do_force_soa) { - has_soa = 0; + speed = -1; } - if (_dns_server_request_update_cache(request, context->qtype, cache_packet, has_soa, context->cache_ttl) != 0) { + if (_dns_server_request_update_cache(request, speed, context->qtype, cache_packet, context->cache_ttl) != 0) { tlog(TLOG_WARN, "update packet cache failed."); } @@ -4843,58 +4831,6 @@ static int _dns_server_get_expired_ttl_reply(struct dns_cache *dns_cache) return dns_conf_serve_expired_reply_ttl; } -static int _dns_server_get_expired_cname_ttl_reply(struct dns_cache *dns_cache) -{ - int ttl = dns_cache_get_cname_ttl(dns_cache); - if (ttl > 0) { - return ttl; - } - - return _dns_server_get_expired_ttl_reply(dns_cache); -} - -static int _dns_server_process_cache_addr(struct dns_request *request, struct dns_cache *dns_cache) -{ - struct dns_cache_addr *cache_addr = (struct dns_cache_addr *)dns_cache_get_data(dns_cache); - - if (cache_addr->head.cache_type != CACHE_TYPE_ADDR) { - goto errout; - } - /* Cache hits, returning results in the cache */ - switch (request->qtype) { - case DNS_T_A: - memcpy(request->ip_addr, cache_addr->addr_data.ipv4_addr, DNS_RR_A_LEN); - break; - case DNS_T_AAAA: - memcpy(request->ip_addr, cache_addr->addr_data.ipv6_addr, DNS_RR_AAAA_LEN); - break; - default: - goto errout; - break; - } - - request->ip_ttl = _dns_server_get_expired_ttl_reply(dns_cache); - request->has_ip = 1; - if (cache_addr->addr_data.cname[0] != 0) { - safe_strncpy(request->cname, cache_addr->addr_data.cname, DNS_MAX_CNAME_LEN); - request->has_cname = 1; - request->ttl_cname = _dns_server_get_expired_cname_ttl_reply(dns_cache); - } - - request->rcode = DNS_RC_NOERROR; - - struct dns_server_post_context context; - _dns_server_post_context_init(&context, request); - context.do_reply = 1; - context.do_audit = 1; - context.do_ipset = 1; - _dns_request_post(&context); - - return 0; -errout: - return -1; -} - static int _dns_server_process_cache_packet(struct dns_request *request, struct dns_cache *dns_cache) { int ret = -1; @@ -4904,11 +4840,6 @@ static int _dns_server_process_cache_packet(struct dns_request *request, struct } int do_ipset = (dns_cache_get_ttl(dns_cache) == 0); - - if (cache_packet->head.cache_type != CACHE_TYPE_PACKET) { - goto out; - } - if (dns_cache_is_visited(dns_cache) == 0) { do_ipset = 1; } @@ -4945,27 +4876,12 @@ static int _dns_server_process_cache_packet(struct dns_request *request, struct static int _dns_server_process_cache_data(struct dns_request *request, struct dns_cache *dns_cache) { - enum CACHE_TYPE cache_type = CACHE_TYPE_NONE; int ret = -1; - cache_type = dns_cache_data_type(dns_cache->cache_data); request->ping_time = dns_cache->info.speed; - switch (cache_type) { - case CACHE_TYPE_ADDR: - ret = _dns_server_process_cache_addr(request, dns_cache); - if (ret != 0) { - goto out; - } - break; - case CACHE_TYPE_PACKET: - ret = _dns_server_process_cache_packet(request, dns_cache); - if (ret != 0) { - goto out; - } - break; - default: + ret = _dns_server_process_cache_packet(request, dns_cache); + if (ret != 0) { goto out; - break; } return 0; @@ -5019,13 +4935,7 @@ static int _dns_server_process_cache(struct dns_request *request) dualstack_dns_cache = dns_cache_lookup(&cache_key); } - if (dualstack_dns_cache && dns_cache_is_soa(dualstack_dns_cache) == 0 && - (dualstack_dns_cache->info.speed > 0)) { - if (dns_cache_is_soa(dns_cache)) { - ret = _dns_server_process_cache_packet(request, dns_cache); - goto out_update_cache; - } - + if (dualstack_dns_cache && (dualstack_dns_cache->info.speed > 0)) { if ((dualstack_dns_cache->info.speed + (dns_conf_dualstack_ip_selection_threshold * 10)) < dns_cache->info.speed || dns_cache->info.speed < 0) { @@ -5040,13 +4950,6 @@ static int _dns_server_process_cache(struct dns_request *request) } reply_cache: - if (dns_cache_is_soa(dns_cache)) { - if (dns_cache_get_ttl(dns_cache) > 0) { - ret = _dns_server_process_cache_packet(request, dns_cache); - } - goto out; - } - if (dns_cache_get_ttl(dns_cache) <= 0 && request->no_serve_expired == 1) { goto out; } @@ -6560,6 +6463,10 @@ static int _dns_server_prefetch_expired_domain(struct dns_cache *dns_cache) static int _dns_server_cache_expired(struct dns_cache *dns_cache) { + if (dns_cache->info.rcode != DNS_RC_NOERROR) { + return -1; + } + if (dns_conf_prefetch == 1) { if (dns_conf_serve_expired == 1) { return _dns_server_prefetch_expired_domain(dns_cache); diff --git a/src/util.c b/src/util.c index 42e930de26..63d0a36c10 100644 --- a/src/util.c +++ b/src/util.c @@ -188,7 +188,8 @@ int generate_random_addr(unsigned char *addr, int addr_len, int mask) return 0; } -int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_to, unsigned char *addr_out, int addr_len, int mask) +int generate_addr_map(const unsigned char *addr_from, const unsigned char *addr_to, unsigned char *addr_out, + int addr_len, int mask) { if ((mask / 8) >= addr_len) { if (mask % 8 != 0) { @@ -1476,7 +1477,7 @@ void bug_ext(const char *file, int line, const char *func, const char *errfmt, . int write_file(const char *filename, void *data, int data_len) { - int fd = open(filename, O_WRONLY | O_CREAT, 0644); + int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { return -1; } @@ -1524,9 +1525,9 @@ int dns_packet_save(const char *dir, const char *type, const char *from, const v snprintf(time_s, sizeof(time_s) - 1, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.3d", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (int)(tm_val.tv_usec / 1000)); - snprintf(filename, sizeof(filename) - 1, "%s/%s-%.4d%.2d%.2d-%.2d%.2d%.2d%.1d.packet", dir, type, + snprintf(filename, sizeof(filename) - 1, "%s/%s-%.4d%.2d%.2d-%.2d%.2d%.2d%.3d.packet", dir, type, ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, - (int)(tm_val.tv_usec / 100000)); + (int)(tm_val.tv_usec / 1000)); data = malloc(PACKET_BUF_SIZE); if (data == NULL) {