Feature: select all best ip

This commit is contained in:
Nick Peng
2022-04-10 19:47:00 +08:00
parent 23e9021d30
commit 6e1363dca4

View File

@@ -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, &param) != 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;