From 6e1363dca4291f3b54c4afcef3cb2939ba9e116d Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Sun, 10 Apr 2022 19:47:00 +0800 Subject: [PATCH] Feature: select all best ip --- src/dns_server.c | 611 ++++++++++++++++++++++++++--------------------- 1 file changed, 343 insertions(+), 268 deletions(-) diff --git a/src/dns_server.c b/src/dns_server.c index e07a00c..a84f19e 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -126,6 +126,7 @@ struct dns_ip_address { struct hlist_node node; int hitnum; unsigned long recv_tick; + int ping_ttl; dns_type_t addr_type; union { unsigned char ipv4_addr[DNS_RR_A_LEN]; @@ -397,15 +398,15 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request) /* add A record */ if (request->has_ipv4 && request->qtype == DNS_T_A) { - ret |= dns_add_A(packet, DNS_RRS_AN, domain, request->ttl_v4, request->ipv4_addr); + ret |= dns_add_A(packet, DNS_RRS_AN, domain, 3, request->ipv4_addr); } /* add AAAA record */ if (request->has_ipv6 && request->qtype == DNS_T_AAAA) { if (request->has_ipv4) { - ret |= dns_add_A(packet, DNS_RRS_AN, domain, request->ttl_v4, request->ipv4_addr); + ret |= dns_add_A(packet, DNS_RRS_AN, domain, 3, request->ipv4_addr); } - ret |= dns_add_AAAA(packet, DNS_RRS_AN, domain, request->ttl_v6, request->ipv6_addr); + ret |= dns_add_AAAA(packet, DNS_RRS_AN, domain, 3, request->ipv6_addr); } /* add SOA record */ @@ -536,7 +537,69 @@ static int _dns_reply_inpacket(struct dns_request *request, unsigned char *inpac return ret; } -static int _dns_reply(struct dns_request *request) +static int _dns_server_request_update_cache(struct dns_request *request, dns_type_t qtype, + struct dns_cache_data *cache_data) +{ + int ttl; + int speed = 0; + + if (qtype == DNS_T_A) { + ttl = _dns_server_get_conf_ttl(request->ttl_v4); + speed = request->ping_ttl_v4; + } else if (qtype == DNS_T_AAAA) { + ttl = _dns_server_get_conf_ttl(request->ttl_v6); + speed = request->ping_ttl_v6; + } else { + goto errout; + } + + if (request->has_soa) { + ttl = dns_conf_rr_ttl; + } + + /* if doing prefetch, update cache only */ + if (request->prefetch) { + if (dns_cache_replace(request->domain, ttl, qtype, speed, cache_data) != 0) { + goto errout; + } + } else { + /* insert result to cache */ + if (dns_cache_insert(request->domain, ttl, qtype, speed, cache_data) != 0) { + goto errout; + } + } + + return 0; +errout: + if (cache_data) { + dns_cache_data_free(cache_data); + } + return -1; +} + +static int _dns_cache_reply_packet(struct dns_request *request, unsigned char *inpacket, int inpacket_len) +{ + if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) == 0) { + return 0; + } + + if (request->qtype != DNS_T_AAAA && request->qtype != DNS_T_A) { + return 0; + } + + struct dns_cache_data *cache_packet = dns_cache_new_data_packet(request->server_flags, inpacket, inpacket_len); + if (cache_packet == NULL) { + return -1; + } + + if (_dns_server_request_update_cache(request, request->qtype, cache_packet) != 0) { + tlog(TLOG_WARN, "update packet cache failed."); + } + + return 0; +} + +static int _dns_reply(struct dns_request *request, int docache) { unsigned char inpacket[DNS_IN_PACKSIZE]; unsigned char packet_buff[DNS_PACKSIZE]; @@ -587,6 +650,14 @@ static int _dns_reply(struct dns_request *request) /* send request */ atomic_inc_return(&request->notified); + + if (docache) { + ret = _dns_cache_reply_packet(request, inpacket, encode_len); + if (ret != 0) { + tlog(TLOG_WARN, "cache packet for %s failed.", request->domain); + } + } + return _dns_reply_inpacket(request, inpacket, encode_len); } @@ -674,7 +745,7 @@ static int _dns_server_reply_SOA(int rcode, struct dns_request *request) _dns_result_callback(request); - _dns_reply(request); + _dns_reply(request, 1); return 0; } @@ -745,63 +816,13 @@ static int _dns_setup_ipset(struct dns_request *request) return ret; } -static int _dns_server_request_update_cache(struct dns_request *request, dns_type_t qtype, - struct dns_cache_data *cache_data) +static int _dns_server_request_complete(struct dns_request *request) { - int ttl; - int speed = 0; - - if (qtype == DNS_T_A) { - ttl = _dns_server_get_conf_ttl(request->ttl_v4); - speed = request->ping_ttl_v4; - } else if (qtype == DNS_T_AAAA) { - ttl = _dns_server_get_conf_ttl(request->ttl_v6); - speed = request->ping_ttl_v6; - } else { - goto errout; + if (atomic_inc_return(&request->notified) != 1) { + return 0; } - if (request->has_soa) { - ttl = dns_conf_rr_ttl; - } - - /* if doing prefetch, update cache only */ - if (request->prefetch) { - if (dns_cache_replace(request->domain, ttl, qtype, speed, cache_data) != 0) { - goto errout; - } - } else { - /* insert result to cache */ - if (dns_cache_insert(request->domain, ttl, qtype, speed, cache_data) != 0) { - goto errout; - } - } - - return 0; -errout: - if (cache_data) { - dns_cache_data_free(cache_data); - } - return -1; -} - -static int _dns_server_request_complete_A(struct dns_request *request) -{ - char *cname = NULL; - int cname_ttl = dns_conf_rr_ttl; - struct dns_cache_data *cache_data = NULL; - - if (request->has_cname) { - cname = request->cname; - cname_ttl = request->ttl_cname; - } - - cache_data = dns_cache_new_data(); - if (cache_data == NULL) { - goto errout; - } - - if (request->has_ipv4 != 0) { + if (request->qtype == DNS_T_A && request->has_ipv4 != 0) { tlog(TLOG_INFO, "result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2], request->ipv4_addr[3]); @@ -809,148 +830,42 @@ static int _dns_server_request_complete_A(struct dns_request *request) if (request->has_ping_result == 0 && request->ttl_v4 > DNS_SERVER_TMOUT_TTL) { request->ttl_v4 = DNS_SERVER_TMOUT_TTL; } - dns_cache_set_data_addr(cache_data, request->server_flags, cname, cname_ttl, request->ipv4_addr, DNS_RR_A_LEN); - } else if (request->has_soa) { - dns_cache_set_data_soa(cache_data, request->server_flags, cname, cname_ttl); - } - - if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) == 0) { - dns_cache_data_free(cache_data); - return 0; - } - - if (_dns_server_request_update_cache(request, DNS_T_A, cache_data) != 0) { - goto errout; - } - - return 0; - -errout: - if (cache_data) { - dns_cache_data_free(cache_data); - cache_data = NULL; - } - - return -1; -} - -static int _dns_server_request_complete_AAAA(struct dns_request *request) -{ - int ret = -1; - char *cname = NULL; - int cname_ttl = dns_conf_rr_ttl; - struct dns_cache_data *cache_data = NULL; - - if (request->has_cname) { - cname = request->cname; - cname_ttl = request->ttl_cname; - } - - cache_data = dns_cache_new_data(); - if (cache_data == NULL) { - goto errout; - } - - if (request->has_ipv6) { - 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[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]); - - if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) { - request->ttl_v6 = DNS_SERVER_TMOUT_TTL; - } - - /* if doing prefetch, update cache only */ - dns_cache_set_data_addr(cache_data, request->server_flags, cname, cname_ttl, request->ipv6_addr, DNS_T_AAAA); - - request->has_soa = 0; - } else if (request->has_soa) { - dns_cache_set_data_soa(cache_data, request->server_flags, cname, cname_ttl); - } - - if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) != 0) { - if (_dns_server_request_update_cache(request, DNS_T_AAAA, cache_data) != 0) { - goto errout; - } - cache_data = NULL; - } else { - dns_cache_data_free(cache_data); - cache_data = NULL; - } - - if (request->has_ipv4 && (request->ping_ttl_v4 > 0)) { - tlog(TLOG_INFO, "result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, request->ipv4_addr[0], - request->ipv4_addr[1], request->ipv4_addr[2], request->ipv4_addr[3]); - - /* if ipv4 is fasting than ipv6, add ipv4 to cache, and return SOA for AAAA request */ - if ((request->ping_ttl_v4 + (dns_conf_dualstack_ip_selection_threshold * 10)) < request->ping_ttl_v6 || - request->ping_ttl_v6 < 0) { - tlog(TLOG_DEBUG, "Force IPV4 perfered."); - if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) != 0) { - cache_data = dns_cache_new_data(); - if (cache_data == NULL) { - goto errout; - } - - dns_cache_set_data_addr(cache_data, request->server_flags, cname, cname_ttl, request->ipv4_addr, - DNS_T_A); - if (_dns_server_request_update_cache(request, DNS_T_A, cache_data) != 0) { - goto errout; - } - cache_data = NULL; - } - - if (request->dualstack_selection) { - if (_dns_server_reply_SOA(DNS_RC_NOERROR, request) != 0) { - ret = -1; - goto errout; - } - - ret = 1; - goto errout; - } - } - } - - request->has_ipv4 = 0; - - return 0; - -errout: - if (cache_data != NULL) { - dns_cache_data_free(cache_data); - cache_data = NULL; - } - - return ret; -} - -static int _dns_server_request_complete(struct dns_request *request) -{ - int ret = 0; - - if (atomic_inc_return(&request->notified) != 1) { - return 0; - } - - if (request->qtype == DNS_T_A) { - if (_dns_server_request_complete_A(request) != 0) { - tlog(TLOG_ERROR, "complete DNS A failed."); - return -1; - } } else if (request->qtype == DNS_T_AAAA) { - ret = _dns_server_request_complete_AAAA(request); - if (ret != 0) { - if (ret == 1) { - return 0; + if (request->has_ipv6) { + 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[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]); + + if (request->has_ping_result == 0 && request->ttl_v6 > DNS_SERVER_TMOUT_TTL) { + request->ttl_v6 = DNS_SERVER_TMOUT_TTL; } - tlog(TLOG_ERROR, "complete DNS A failed."); - return -1; + + request->has_soa = 0; } + + if (request->has_ipv4 && (request->ping_ttl_v4 > 0)) { + tlog(TLOG_INFO, "result: %s, rcode: %d, %d.%d.%d.%d\n", request->domain, request->rcode, + request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2], request->ipv4_addr[3]); + + /* if ipv4 is fasting than ipv6, add ipv4 to cache, and return SOA for AAAA request */ + if ((request->ping_ttl_v4 + (dns_conf_dualstack_ip_selection_threshold * 10)) < request->ping_ttl_v6 || + request->ping_ttl_v6 < 0) { + tlog(TLOG_DEBUG, "Force IPV4 perfered."); + // TODO cache ipv4 result + + if (request->dualstack_selection) { + if (_dns_server_reply_SOA(DNS_RC_NOERROR, request) == 0) { + return 0; + } + } + } + } + + request->has_ipv4 = 0; } if (request->has_soa) { @@ -967,7 +882,99 @@ static int _dns_server_request_complete(struct dns_request *request) } /* return result to client */ - _dns_reply(request); + _dns_reply(request, 1); + + return 0; +} + +struct dns_ip_address *_dns_ip_address_get(struct dns_request *request, unsigned char *addr, dns_type_t addr_type) +{ + uint32_t key = 0; + struct dns_ip_address *addr_map = NULL; + struct dns_ip_address *addr_tmp = NULL; + int addr_len = 0; + + if (addr_type == DNS_T_A) { + addr_len = DNS_RR_A_LEN; + } else if (addr_type == DNS_T_AAAA) { + addr_len = DNS_RR_AAAA_LEN; + } else { + return NULL; + } + + /* store the ip address and the number of hits */ + key = jhash(addr, addr_len, 0); + pthread_mutex_lock(&request->ip_map_lock); + hash_for_each_possible(request->ip_map, addr_tmp, node, key) + { + if (addr_type == DNS_T_A) { + if (memcmp(addr_tmp->ipv4_addr, addr, addr_len) == 0) { + addr_map = addr_tmp; + break; + } + } else if (addr_type == DNS_T_AAAA) { + if (memcmp(addr_tmp->ipv6_addr, addr, addr_len) == 0) { + addr_map = addr_tmp; + break; + } + } + } + pthread_mutex_unlock(&request->ip_map_lock); + + return addr_map; +} + +static int _dns_ip_address_check_add(struct dns_request *request, unsigned char *addr, dns_type_t addr_type) +{ + uint32_t key = 0; + struct dns_ip_address *addr_map = NULL; + int addr_len = 0; + + if (addr_type == DNS_T_A) { + addr_len = DNS_RR_A_LEN; + } else if (addr_type == DNS_T_AAAA) { + addr_len = DNS_RR_AAAA_LEN; + } else { + return -1; + } + + /* store the ip address and the number of hits */ + key = jhash(addr, addr_len, 0); + pthread_mutex_lock(&request->ip_map_lock); + hash_for_each_possible(request->ip_map, addr_map, node, key) + { + if (addr_type == DNS_T_A) { + if (memcmp(addr_map->ipv4_addr, addr, addr_len) == 0) { + addr_map->hitnum++; + addr_map->recv_tick = get_tick_count(); + pthread_mutex_unlock(&request->ip_map_lock); + return -1; + } + } else if (addr_type == DNS_T_AAAA) { + if (memcmp(addr_map->ipv6_addr, addr, addr_len) == 0) { + addr_map->hitnum++; + addr_map->recv_tick = get_tick_count(); + pthread_mutex_unlock(&request->ip_map_lock); + return -1; + } + } + } + request->ip_map_num++; + + addr_map = malloc(sizeof(*addr_map)); + if (addr_map == NULL) { + pthread_mutex_unlock(&request->ip_map_lock); + tlog(TLOG_ERROR, "malloc failed"); + return -1; + } + + addr_map->addr_type = addr_type; + addr_map->hitnum = 1; + addr_map->recv_tick = get_tick_count(); + addr_map->ping_ttl = -1; + memcpy(addr_map->addr, addr, addr_len); + hash_add(request->ip_map, &addr_map->node, key); + pthread_mutex_unlock(&request->ip_map_lock); return 0; } @@ -1068,6 +1075,115 @@ static void _dns_server_delete_request(struct dns_request *request) free(request); } +static void _dns_server_setup_multi_ip_cache(struct dns_request *request) +{ + struct dns_ip_address *addr_map; + struct hlist_node *tmp; + int bucket = 0; + + unsigned char inpacket[DNS_IN_PACKSIZE]; + unsigned char packet_buff[DNS_PACKSIZE]; + char *domain; + struct dns_packet *packet = (struct dns_packet *)packet_buff; + struct dns_head head; + int ret = 0; + int encode_len = 0; + int ip_num = 0; + int ignore_speed = 0; + int maxhit = 0; + + memset(&head, 0, sizeof(head)); + head.id = request->id; + head.qr = DNS_QR_ANSWER; + head.opcode = DNS_OP_QUERY; + head.rd = 1; + head.ra = 1; + head.aa = 0; + head.tc = 0; + head.rcode = request->rcode; + + /* init a new DNS packet */ + ret = dns_packet_init(packet, DNS_PACKSIZE, &head); + if (ret != 0) { + return; + } + domain = request->domain; + + /* add request domain */ + ret = dns_add_domain(packet, request->domain, request->qtype, DNS_C_IN); + if (ret != 0) { + return; + } + + /* add CNAME record */ + if (request->has_cname) { + ret |= dns_add_CNAME(packet, DNS_RRS_AN, request->domain, request->ttl_cname, request->cname); + domain = request->cname; + } + + while (true) { + pthread_mutex_lock(&request->ip_map_lock); + hash_for_each_safe(request->ip_map, bucket, tmp, addr_map, node) + { + if (request->qtype != addr_map->addr_type) { + continue; + } + + if (addr_map->hitnum > maxhit) { + maxhit = addr_map->hitnum; + } + + if (addr_map->ping_ttl < 0 && ignore_speed == 0) { + continue; + } + + if (addr_map->hitnum < maxhit && ignore_speed == 1) { + continue; + } + + if (addr_map->addr_type == DNS_T_A) { + int ttl_range = request->ping_ttl_v4 + request->ping_ttl_v4 / 10; + if ((ttl_range < addr_map->ping_ttl) && addr_map->ping_ttl >= 100 && ignore_speed == 0) { + continue; + } + ret |= dns_add_A(packet, DNS_RRS_AN, domain, request->ttl_v4, addr_map->ipv4_addr); + ip_num++; + } else if (addr_map->addr_type == DNS_T_AAAA) { + int ttl_range = request->ping_ttl_v6 + request->ping_ttl_v6 / 10; + if (ttl_range < addr_map->ping_ttl && addr_map->ping_ttl >= 100 && ignore_speed == 0) { + continue; + } + ret |= dns_add_AAAA(packet, DNS_RRS_AN, domain, request->ttl_v6, addr_map->ipv6_addr); + ip_num++; + } + } + pthread_mutex_unlock(&request->ip_map_lock); + + if (ip_num <= 0 && ignore_speed == 0) { + ignore_speed = 1; + } else { + break; + } + } + + if (ret || ip_num <= 0) { + return; + } + + /* encode to binary data */ + encode_len = dns_encode(inpacket, DNS_IN_PACKSIZE, packet); + if (encode_len <= 0) { + return; + } + + ret = _dns_cache_reply_packet(request, inpacket, encode_len); + if (ret != 0) { + tlog(TLOG_WARN, "cache packet for %s failed.", request->domain); + } + + return; +} + static void _dns_server_request_release_complete(struct dns_request *request, int do_complete) { struct dns_ip_address *addr_map; @@ -1093,6 +1209,7 @@ static void _dns_server_request_release_complete(struct dns_request *request, in _dns_server_request_complete(request); } + _dns_server_setup_multi_ip_cache(request); pthread_mutex_lock(&request->ip_map_lock); hash_for_each_safe(request->ip_map, bucket, tmp, addr_map, node) { @@ -1158,6 +1275,7 @@ static void _dns_server_ping_result(struct ping_host_struct *ping_host, const ch struct dns_request *request = userptr; int may_complete = 0; int threshold = 100; + struct dns_ip_address *addr_map = NULL; if (request == NULL) { return; @@ -1183,6 +1301,11 @@ static void _dns_server_ping_result(struct ping_host_struct *ping_host, const ch memcpy(request->ipv4_addr, &addr_in->sin_addr.s_addr, 4); } + addr_map = _dns_ip_address_get(request, (unsigned char *)&addr_in->sin_addr.s_addr, DNS_T_A); + if (addr_map) { + addr_map->ping_ttl = rtt; + } + if (request->qtype == DNS_T_AAAA && request->dualstack_selection) { if (request->ping_ttl_v6 < 0 && request->has_soa == 0) { return; @@ -1197,12 +1320,20 @@ static void _dns_server_ping_result(struct ping_host_struct *ping_host, const ch request->ping_ttl_v4 = rtt; request->has_ipv4 = 1; memcpy(request->ipv4_addr, addr_in6->sin6_addr.s6_addr + 12, 4); + addr_map = _dns_ip_address_get(request, addr_in6->sin6_addr.s6_addr + 12, DNS_T_A); + if (addr_map) { + addr_map->ping_ttl = rtt; + } } } else { if (request->ping_ttl_v6 > rtt) { request->ping_ttl_v6 = rtt; request->has_ipv6 = 1; memcpy(request->ipv6_addr, addr_in6->sin6_addr.s6_addr, 16); + addr_map = _dns_ip_address_get(request, addr_in6->sin6_addr.s6_addr, DNS_T_AAAA); + if (addr_map) { + addr_map->ping_ttl = rtt; + } } } } break; @@ -1267,60 +1398,6 @@ static int _dns_server_check_speed(struct dns_request *request, char *ip, int mo return -1; } -static int _dns_ip_address_check_add(struct dns_request *request, unsigned char *addr, dns_type_t addr_type) -{ - uint32_t key = 0; - struct dns_ip_address *addr_map = NULL; - int addr_len = 0; - - if (addr_type == DNS_T_A) { - addr_len = DNS_RR_A_LEN; - } else if (addr_type == DNS_T_AAAA) { - addr_len = DNS_RR_AAAA_LEN; - } else { - return -1; - } - - /* store the ip address and the number of hits */ - key = jhash(addr, addr_len, 0); - pthread_mutex_lock(&request->ip_map_lock); - hash_for_each_possible(request->ip_map, addr_map, node, key) - { - if (addr_type == DNS_T_A) { - if (memcmp(addr_map->ipv4_addr, addr, addr_len) == 0) { - addr_map->hitnum++; - addr_map->recv_tick = get_tick_count(); - pthread_mutex_unlock(&request->ip_map_lock); - return -1; - } - } else if (addr_type == DNS_T_AAAA) { - if (memcmp(addr_map->ipv6_addr, addr, addr_len) == 0) { - addr_map->hitnum++; - addr_map->recv_tick = get_tick_count(); - pthread_mutex_unlock(&request->ip_map_lock); - return -1; - } - } - } - request->ip_map_num++; - - addr_map = malloc(sizeof(*addr_map)); - if (addr_map == NULL) { - pthread_mutex_unlock(&request->ip_map_lock); - tlog(TLOG_ERROR, "malloc failed"); - return -1; - } - - addr_map->addr_type = addr_type; - addr_map->hitnum = 1; - addr_map->recv_tick = get_tick_count(); - memcpy(addr_map->addr, addr, addr_len); - hash_add(request->ip_map, &addr_map->node, key); - pthread_mutex_unlock(&request->ip_map_lock); - - return 0; -} - static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char *addr, int addr_len, dns_type_t addr_type, int result_flag) { @@ -1950,17 +2027,7 @@ static int _dns_server_reply_passthrouth(struct dns_request *request, struct dns return ret; } - if (_dns_server_has_bind_flag(request, BIND_FLAG_NO_CACHE) != 0 && - (request->qtype == DNS_T_AAAA || request->qtype == DNS_T_A)) { - struct dns_cache_data *cache_packet = dns_cache_new_data_packet(request->server_flags, inpacket, inpacket_len); - if (cache_packet == NULL) { - return ret; - } - - if (_dns_server_request_update_cache(request, request->qtype, cache_packet) != 0) { - tlog(TLOG_WARN, "update packet cache failed."); - } - } + _dns_cache_reply_packet(request, inpacket, inpacket_len); if (_dns_server_setup_ipset_packet(request, packet) != 0) { tlog(TLOG_DEBUG, "setup ipset failed."); @@ -2093,7 +2160,7 @@ static int _dns_server_process_ptr(struct dns_request *request) request->rcode = DNS_RC_NOERROR; request->has_ptr = 1; - _dns_reply(request); + _dns_reply(request, 0); freeifaddrs(ifaddr); return 0; @@ -2330,7 +2397,7 @@ static int _dns_server_process_address(struct dns_request *request) } request->rcode = DNS_RC_NOERROR; - _dns_reply(request); + _dns_reply(request, 0); return 0; errout: @@ -2424,7 +2491,7 @@ static int _dns_server_process_cache_addr(struct dns_request *request, struct dn _dns_result_callback(request); if (request->prefetch == 0) { - _dns_reply(request); + _dns_reply(request, 1); } return 0; @@ -2467,7 +2534,15 @@ static int _dns_server_process_cache_packet(struct dns_request *request, struct } /* When passthrough, modify the id to be the id of the client request. */ - dns_server_update_reply_packet_id(request, cache_packet->data, cache_packet->head.size); + struct dns_update_param param; + param.id = request->id; + param.cname_ttl = _dns_server_get_expired_ttl_reply(dns_cache); + param.ip_ttl = _dns_server_get_expired_ttl_reply(dns_cache); + if (dns_packet_update(cache_packet->data, cache_packet->head.size, ¶m) != 0) { + tlog(TLOG_ERROR, "update cache info failed."); + goto errout; + } + return _dns_reply_inpacket(request, cache_packet->data, cache_packet->head.size); errout: return -1;