dns_server: fix dns cache issue & supress ping log

This commit is contained in:
Nick Peng
2022-05-30 23:22:03 +08:00
parent c7db5b2667
commit 848c9e6cf2
3 changed files with 140 additions and 160 deletions

View File

@@ -1352,6 +1352,8 @@ static void _dns_client_query_release(struct dns_query_struct *query)
/* notify caller query end */ /* notify caller query end */
if (query->callback) { if (query->callback) {
tlog(TLOG_INFO, "result %s, qtype: %d, rcode: %d, id %d", query->domain, query->qtype, query->has_result,
query->sid);
query->callback(query->domain, DNS_QUERY_END, 0, NULL, NULL, 0, query->user_ptr); query->callback(query->domain, DNS_QUERY_END, 0, NULL, NULL, 0, query->user_ptr);
} }
@@ -3239,7 +3241,7 @@ static void _dns_client_add_pending_servers(void)
list_del_init(&pending->list); list_del_init(&pending->list);
_dns_client_server_pending_release_lck(pending); _dns_client_server_pending_release_lck(pending);
} else { } else {
tlog(TLOG_DEBUG, "add pending DNS server %s failed, retry %d...", pending->host, pending->retry_cnt); tlog(TLOG_INFO, "add pending DNS server %s failed, retry %d...", pending->host, pending->retry_cnt);
pending->query_v4 = 0; pending->query_v4 = 0;
pending->query_v6 = 0; pending->query_v6 = 0;
} }
@@ -3294,8 +3296,9 @@ static void _dns_client_period_run(void)
_dns_client_check_udp_nat(query); _dns_client_check_udp_nat(query);
if (atomic_dec_and_test(&query->retry_count) || (query->has_result != 0)) { if (atomic_dec_and_test(&query->retry_count) || (query->has_result != 0)) {
_dns_client_query_remove(query); _dns_client_query_remove(query);
tlog(TLOG_INFO, "retry query %s, type: %d, id: %d failed", query->domain, query->qtype, query->sid);
} else { } else {
tlog(TLOG_DEBUG, "retry query %s", query->domain); tlog(TLOG_INFO, "retry query %s, type: %d, id: %d", query->domain, query->qtype, query->sid);
_dns_client_send_query(query, query->domain); _dns_client_send_query(query, query->domain);
} }
_dns_client_query_release(query); _dns_client_query_release(query);

View File

@@ -178,6 +178,7 @@ struct dns_request {
unsigned short id; unsigned short id;
unsigned short rcode; unsigned short rcode;
unsigned short ss_family; unsigned short ss_family;
char remote_server_fail;
socklen_t addr_len; socklen_t addr_len;
union { union {
struct sockaddr_in in; struct sockaddr_in in;
@@ -223,6 +224,7 @@ struct dns_request {
int request_wait; int request_wait;
int prefetch; int prefetch;
int dualstack_selection; int dualstack_selection;
int dualstack_selection_force_A;
pthread_mutex_t ip_map_lock; pthread_mutex_t ip_map_lock;
@@ -258,8 +260,11 @@ static int is_ipv6_ready;
static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags, static int _dns_server_prefetch_request(char *domain, dns_type_t qtype, uint32_t server_flags,
struct dns_query_options *options); struct dns_query_options *options);
static int _dns_server_get_answer(struct dns_server_post_context *context); static int _dns_server_get_answer(struct dns_server_post_context *context);
static void _dns_server_request_release(struct dns_request *request);
static void _dns_server_request_release_complete(struct dns_request *request, int do_complete);
static int _dns_server_reply_passthrouth(struct dns_server_post_context *context);
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len) static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
{ {
@@ -603,7 +608,7 @@ static int _dns_rrs_add_all_best_ip(struct dns_server_post_context *context)
ret |= dns_add_AAAA(context->packet, DNS_RRS_AN, domain, request->ttl_v6, addr_map->ipv6_addr); ret |= dns_add_AAAA(context->packet, DNS_RRS_AN, domain, request->ttl_v6, addr_map->ipv6_addr);
context->ip_num++; context->ip_num++;
tlog(TLOG_INFO, tlog(TLOG_INFO,
"result: %s, rcode: %d, index: %d, rtt: %d" "result: %s, rcode: %d, index: %d, rtt: %d, "
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
request->domain, request->rcode, context->ip_num, addr_map->ping_ttl, request->ipv6_addr[0], request->domain, request->rcode, context->ip_num, addr_map->ping_ttl, request->ipv6_addr[0],
addr_map->ipv6_addr[1], addr_map->ipv6_addr[2], addr_map->ipv6_addr[3], addr_map->ipv6_addr[4], addr_map->ipv6_addr[1], addr_map->ipv6_addr[2], addr_map->ipv6_addr[3], addr_map->ipv6_addr[4],
@@ -650,7 +655,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
} }
/* add CNAME record */ /* add CNAME record */
if (request->has_cname) { if (request->has_cname && context->do_force_soa == 0) {
ret |= dns_add_CNAME(context->packet, DNS_RRS_AN, request->domain, request->ttl_cname, request->cname); ret |= dns_add_CNAME(context->packet, DNS_RRS_AN, request->domain, request->ttl_cname, request->cname);
domain = request->cname; domain = request->cname;
} }
@@ -678,7 +683,9 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]); request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
} }
ret |= _dns_rrs_add_all_best_ip(context); if (context->do_force_soa == 0) {
ret |= _dns_rrs_add_all_best_ip(context);
}
if (context->qtype == DNS_T_A || context->qtype == DNS_T_AAAA) { if (context->qtype == DNS_T_A || context->qtype == DNS_T_AAAA) {
if (context->ip_num > 0) { if (context->ip_num > 0) {
@@ -688,7 +695,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
/* add SOA record */ /* add SOA record */
if (has_soa) { if (has_soa) {
ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa); ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa);
tlog(TLOG_INFO, "result: %s, return SOA", request->domain); tlog(TLOG_INFO, "result: %s, qtype: %d, return SOA", request->domain, context->qtype);
} else if (context->do_force_soa == 1) { } else if (context->do_force_soa == 1) {
_dns_server_setup_soa(request); _dns_server_setup_soa(request);
ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa); ret |= dns_add_SOA(context->packet, DNS_RRS_NS, domain, 0, &request->soa);
@@ -699,7 +706,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
} }
if (request->rcode != DNS_RC_NOERROR) { if (request->rcode != DNS_RC_NOERROR) {
tlog(TLOG_INFO, "result %s, rc-code: %d", domain, request->rcode); tlog(TLOG_INFO, "result %s, qtype: %d, rc-code: %d", domain, context->qtype, request->rcode);
} }
return ret; return ret;
@@ -1082,6 +1089,72 @@ errout:
return -1; return -1;
} }
static int _dns_result_callback_nxdomain(struct dns_request *request)
{
char ip[DNS_MAX_CNAME_LEN];
unsigned int ping_time = -1;
ip[0] = 0;
if (request->result_callback == NULL) {
return 0;
}
return request->result_callback(request->domain, DNS_RC_NXDOMAIN, request->qtype, ip, ping_time, request->user_ptr);
}
static int _dns_result_callback(struct dns_server_post_context *context)
{
char ip[DNS_MAX_CNAME_LEN];
unsigned int ping_time = -1;
struct dns_request *request = context->request;
if (request->result_callback == NULL) {
return 0;
}
if (atomic_inc_return(&request->do_callback) != 1) {
return 0;
}
if (request->has_soa || context->do_force_soa || context->ip_num == 0) {
goto out;
}
ip[0] = 0;
if (request->qtype == DNS_T_A) {
if (request->has_ipv4 == 0) {
goto out;
}
sprintf(ip, "%d.%d.%d.%d", request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2],
request->ipv4_addr[3]);
ping_time = request->ping_ttl_v4;
return request->result_callback(request->domain, request->rcode, request->qtype, ip, ping_time,
request->user_ptr);
} else if (request->qtype == DNS_T_AAAA) {
if (request->has_ipv6 == 0) {
goto out;
}
sprintf(ip, "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", 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]);
ping_time = request->ping_ttl_v6;
return request->result_callback(request->domain, request->rcode, request->qtype, ip, ping_time,
request->user_ptr);
}
_dns_result_callback_nxdomain(request);
return 0;
out:
_dns_result_callback_nxdomain(request);
return 0;
}
static int _dns_cache_specify_packet(struct dns_server_post_context *context) static int _dns_cache_specify_packet(struct dns_server_post_context *context)
{ {
switch (context->qtype) { switch (context->qtype) {
@@ -1108,6 +1181,10 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
if (context->packet->head.rcode == DNS_RC_SERVFAIL || context->packet->head.rcode == DNS_RC_NXDOMAIN) { if (context->packet->head.rcode == DNS_RC_SERVFAIL || context->packet->head.rcode == DNS_RC_NXDOMAIN) {
context->reply_ttl = DNS_SERVER_FAIL_TTL; context->reply_ttl = DNS_SERVER_FAIL_TTL;
/* Do not cache record if cannot connect to remote */
if (request->remote_server_fail == 0 && context->packet->head.rcode == DNS_RC_SERVFAIL) {
return 0;
}
return _dns_cache_packet(context); return _dns_cache_packet(context);
} }
@@ -1115,10 +1192,6 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
return _dns_cache_specify_packet(context); return _dns_cache_specify_packet(context);
} }
if (context->ip_num == 0 && request->has_soa == 0) {
return 0;
}
struct dns_cache_data *cache_packet = struct dns_cache_data *cache_packet =
dns_cache_new_data_packet(request->server_flags, context->inpacket, context->inpacket_len); dns_cache_new_data_packet(request->server_flags, context->inpacket, context->inpacket_len);
if (cache_packet == NULL) { if (cache_packet == NULL) {
@@ -1129,6 +1202,10 @@ static int _dns_cache_reply_packet(struct dns_server_post_context *context)
has_soa = 0; has_soa = 0;
} }
if (context->do_force_soa) {
has_soa = 0;
}
if (_dns_server_request_update_cache(request, context->qtype, cache_packet, has_soa) != 0) { if (_dns_server_request_update_cache(request, context->qtype, cache_packet, has_soa) != 0) {
tlog(TLOG_WARN, "update packet cache failed."); tlog(TLOG_WARN, "update packet cache failed.");
} }
@@ -1237,10 +1314,6 @@ static int _dns_request_post(struct dns_server_post_context *context)
tlog(TLOG_DEBUG, "reply %s qtype: %d, rcode: %d, reply: %d", request->domain, request->qtype, tlog(TLOG_DEBUG, "reply %s qtype: %d, rcode: %d, reply: %d", request->domain, request->qtype,
context->packet->head.rcode, context->do_reply); context->packet->head.rcode, context->do_reply);
if (request->conn == NULL) {
context->do_reply = 0;
}
/* init a new DNS packet */ /* init a new DNS packet */
ret = _dns_setup_dns_packet(context); ret = _dns_setup_dns_packet(context);
if (ret != 0) { if (ret != 0) {
@@ -1275,9 +1348,15 @@ static int _dns_request_post(struct dns_server_post_context *context)
_dns_server_setup_ipset_packet(context); _dns_server_setup_ipset_packet(context);
/* log audit log */ /* log audit log */
_dns_server_audit_log(context); _dns_server_audit_log(context);
/* reply API callback */
_dns_result_callback(context);
if (request->conn == NULL) {
return 0;
}
if (context->reply_ttl > 0) { if (context->reply_ttl > 0) {
struct dns_update_param param; struct dns_update_param param;
param.id = request->id; param.id = request->id;
@@ -1298,73 +1377,11 @@ static int _dns_request_post(struct dns_server_post_context *context)
return 0; return 0;
} }
static int _dns_result_callback_nxdomain(struct dns_request *request)
{
char ip[DNS_MAX_CNAME_LEN];
unsigned int ping_time = -1;
ip[0] = 0;
if (request->result_callback == NULL) {
return 0;
}
return request->result_callback(request->domain, DNS_RC_NXDOMAIN, request->qtype, ip, ping_time, request->user_ptr);
}
static int _dns_result_callback(struct dns_request *request)
{
char ip[DNS_MAX_CNAME_LEN];
unsigned int ping_time = -1;
if (request->result_callback == NULL) {
return 0;
}
if (atomic_inc_return(&request->do_callback) != 1) {
return 0;
}
ip[0] = 0;
if (request->qtype == DNS_T_A) {
if (request->has_ipv4 == 0) {
goto out;
}
sprintf(ip, "%d.%d.%d.%d", request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2],
request->ipv4_addr[3]);
ping_time = request->ping_ttl_v4;
return request->result_callback(request->domain, request->rcode, request->qtype, ip, ping_time,
request->user_ptr);
} else if (request->qtype == DNS_T_AAAA) {
if (request->has_ipv6 == 0) {
goto out;
}
sprintf(ip, "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", 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]);
ping_time = request->ping_ttl_v6;
return request->result_callback(request->domain, request->rcode, request->qtype, ip, ping_time,
request->user_ptr);
}
_dns_result_callback_nxdomain(request);
return 0;
out:
_dns_result_callback_nxdomain(request);
return 0;
}
static int _dns_server_reply_SOA(int rcode, struct dns_request *request) static int _dns_server_reply_SOA(int rcode, struct dns_request *request)
{ {
/* return SOA record */ /* return SOA record */
request->rcode = rcode; request->rcode = rcode;
_dns_server_setup_soa(request); _dns_server_setup_soa(request);
_dns_result_callback(request);
struct dns_server_post_context context; struct dns_server_post_context context;
_dns_server_post_context_init(&context, request); _dns_server_post_context_init(&context, request);
@@ -1396,23 +1413,6 @@ static void _dns_server_dualstack_selection_cache_A(struct dns_request *request)
_dns_request_post(&context); _dns_request_post(&context);
} }
static int dns_server_update_reply_packet_id(struct dns_request *request, unsigned char *inpacket, int inpacket_len)
{
struct dns_head *dns_head = (struct dns_head *)inpacket;
unsigned short id = request->id;
if (inpacket_len < sizeof(*dns_head)) {
return -1;
}
dns_head->id = htons(id);
return 0;
}
static void _dns_server_request_release(struct dns_request *request);
static void _dns_server_request_release_complete(struct dns_request *request, int do_complete);
int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context) int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_server_post_context *context)
{ {
struct dns_request_pending_list *pending_list; struct dns_request_pending_list *pending_list;
@@ -1438,22 +1438,12 @@ int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_s
_dns_server_post_context_init_from(&context_pending, req, context->packet, context->inpacket, _dns_server_post_context_init_from(&context_pending, req, context->packet, context->inpacket,
context->inpacket_len); context->inpacket_len);
context_pending.do_cache = 0; context_pending.do_cache = 0;
context_pending.do_audit = 0; context_pending.do_audit = context->do_audit;
context_pending.do_reply = 0; context_pending.do_reply = context->do_reply;
context_pending.do_force_soa = context->do_force_soa;
context_pending.do_ipset = 0; context_pending.do_ipset = 0;
_dns_server_get_answer(&context_pending); _dns_server_get_answer(&context_pending);
if (req->result_callback) { _dns_server_reply_passthrouth(&context_pending);
_dns_result_callback(req);
}
if (req->conn) {
if (atomic_inc_return(&req->notified) != 1) {
return 0;
}
/* When passthrough, modify the id to be the id of the client request. */
dns_server_update_reply_packet_id(req, context->inpacket, context->inpacket_len);
ret = _dns_reply_inpacket(req, context->inpacket, context->inpacket_len);
}
req->request_pending_list = NULL; req->request_pending_list = NULL;
_dns_server_request_release_complete(req, 0); _dns_server_request_release_complete(req, 0);
@@ -1467,7 +1457,6 @@ int _dns_server_reply_all_pending_list(struct dns_request *request, struct dns_s
static int _dns_server_request_complete(struct dns_request *request) static int _dns_server_request_complete(struct dns_request *request)
{ {
int force_A = 0;
int ttl = DNS_SERVER_TMOUT_TTL; int ttl = DNS_SERVER_TMOUT_TTL;
if (request->rcode == DNS_RC_SERVFAIL || request->rcode == DNS_RC_NXDOMAIN) { if (request->rcode == DNS_RC_SERVFAIL || request->rcode == DNS_RC_NXDOMAIN) {
@@ -1504,7 +1493,7 @@ static int _dns_server_request_complete(struct dns_request *request)
request->ping_ttl_v6 < 0) { request->ping_ttl_v6 < 0) {
if (request->dualstack_selection) { if (request->dualstack_selection) {
tlog(TLOG_DEBUG, "Force IPV4 perfered."); tlog(TLOG_DEBUG, "Force IPV4 perfered.");
force_A = 1; request->dualstack_selection_force_A = 1;
goto out; goto out;
} }
} }
@@ -1515,8 +1504,6 @@ static int _dns_server_request_complete(struct dns_request *request)
tlog(TLOG_INFO, "result: %s, qtype: %d, SOA", request->domain, request->qtype); tlog(TLOG_INFO, "result: %s, qtype: %d, SOA", request->domain, request->qtype);
} }
_dns_result_callback(request);
out: out:
_dns_server_dualstack_selection_cache_A(request); _dns_server_dualstack_selection_cache_A(request);
@@ -1530,7 +1517,7 @@ out:
_dns_server_post_context_init(&context, request); _dns_server_post_context_init(&context, request);
context.do_cache = 1; context.do_cache = 1;
context.do_ipset = 1; context.do_ipset = 1;
context.do_force_soa = force_A; context.do_force_soa = request->dualstack_selection_force_A;
context.do_audit = 1; context.do_audit = 1;
context.do_reply = 1; context.do_reply = 1;
context.reply_ttl = ttl; context.reply_ttl = ttl;
@@ -1696,10 +1683,11 @@ static void _dns_server_select_possible_ipaddress(struct dns_request *request)
static void _dns_server_delete_request(struct dns_request *request) static void _dns_server_delete_request(struct dns_request *request)
{ {
if (atomic_read(&request->notified) == 0) {
_dns_server_request_complete(request);
}
if (request->conn) { if (request->conn) {
if (atomic_read(&request->notified) == 0) {
_dns_server_request_complete(request);
}
_dns_server_conn_release(request->conn); _dns_server_conn_release(request->conn);
} }
pthread_mutex_destroy(&request->ip_map_lock); pthread_mutex_destroy(&request->ip_map_lock);
@@ -1721,10 +1709,10 @@ static void _dns_server_complete_with_multi_ipaddress(struct dns_request *reques
context.do_reply = do_reply; context.do_reply = do_reply;
context.select_all_best_ip = 1; context.select_all_best_ip = 1;
context.skip_notify_count = 1; context.skip_notify_count = 1;
context.do_force_soa = request->dualstack_selection_force_A;
_dns_request_post(&context); _dns_request_post(&context);
_dns_result_callback(request);
if (request->dualstack_selection == 1 && request->qtype == DNS_T_AAAA) { if (request->dualstack_selection == 1 && request->qtype == DNS_T_AAAA && request->has_ipv4) {
_dns_server_post_context_init(&context, request); _dns_server_post_context_init(&context, request);
context.qtype = DNS_T_A; context.qtype = DNS_T_A;
context.do_cache = 1; context.do_cache = 1;
@@ -1823,6 +1811,7 @@ int _dns_server_set_to_pending_list(struct dns_request *request)
pending_list->qtype = request->qtype; pending_list->qtype = request->qtype;
safe_strncpy(pending_list->domain, request->domain, DNS_MAX_CNAME_LEN); safe_strncpy(pending_list->domain, request->domain, DNS_MAX_CNAME_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;
} else { } else {
ret = 0; ret = 0;
} }
@@ -1835,7 +1824,6 @@ out:
_dns_server_request_get(request); _dns_server_request_get(request);
} }
list_add_tail(&request->pending_list, &pending_list->request_list); list_add_tail(&request->pending_list, &pending_list->request_list);
request->request_pending_list = pending_list;
pthread_mutex_unlock(&pending_list->request_list_lock); pthread_mutex_unlock(&pending_list->request_list_lock);
return ret; return ret;
} }
@@ -2323,12 +2311,14 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) { if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) {
if (request->rcode == DNS_RC_SERVFAIL) { if (request->rcode == DNS_RC_SERVFAIL) {
request->rcode = packet->head.rcode; request->rcode = packet->head.rcode;
request->remote_server_fail = 1;
} }
tlog(TLOG_DEBUG, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id); tlog(TLOG_DEBUG, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id);
return -1; return -1;
} }
request->remote_server_fail = 0;
for (j = 1; j < DNS_RRS_END; j++) { for (j = 1; j < DNS_RRS_END; j++) {
rrs = dns_get_rrs_start(packet, j, &rr_count); rrs = dns_get_rrs_start(packet, j, &rr_count);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
@@ -2369,7 +2359,8 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
"%d, minimum: %d", "%d, minimum: %d",
domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial, domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial,
request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum); request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
if (atomic_inc_return(&request->soa_num) >= (dns_server_num() / 2)) { int soa_num = atomic_inc_return(&request->soa_num);
if (soa_num >= (dns_server_num() / 3) + 1 || soa_num > 4) {
_dns_server_request_complete(request); _dns_server_request_complete(request);
} }
} break; } break;
@@ -2398,12 +2389,14 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) { if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) {
if (request->rcode == DNS_RC_SERVFAIL) { if (request->rcode == DNS_RC_SERVFAIL) {
request->rcode = packet->head.rcode; request->rcode = packet->head.rcode;
request->remote_server_fail = 1;
} }
tlog(TLOG_DEBUG, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id); tlog(TLOG_DEBUG, "inquery failed, %s, rcode = %d, id = %d\n", domain, packet->head.rcode, packet->head.id);
return 0; return 0;
} }
request->remote_server_fail = 0;
for (j = 1; j < DNS_RRS_END; j++) { for (j = 1; j < DNS_RRS_END; j++) {
rrs = dns_get_rrs_start(packet, j, &rr_count); rrs = dns_get_rrs_start(packet, j, &rr_count);
for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) { for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
@@ -2569,7 +2562,6 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
static int _dns_server_reply_passthrouth(struct dns_server_post_context *context) static int _dns_server_reply_passthrouth(struct dns_server_post_context *context)
{ {
int ret = 0;
struct dns_request *request = context->request; struct dns_request *request = context->request;
if (atomic_inc_return(&request->notified) != 1) { if (atomic_inc_return(&request->notified) != 1) {
@@ -2577,18 +2569,8 @@ static int _dns_server_reply_passthrouth(struct dns_server_post_context *context
} }
_dns_server_get_answer(context); _dns_server_get_answer(context);
if (request->result_callback) {
_dns_result_callback(request);
}
if (context->packet->head.rcode != DNS_RC_NOERROR && context->packet->head.rcode != DNS_RC_NXDOMAIN) { _dns_result_callback(context);
if (request->conn && context->do_reply == 1) {
/* When passthrough, modify the id to be the id of the client request. */
dns_server_update_reply_packet_id(request, context->inpacket, context->inpacket_len);
ret = _dns_reply_inpacket(request, context->inpacket, context->inpacket_len);
}
return ret;
}
_dns_cache_reply_packet(context); _dns_cache_reply_packet(context);
@@ -2607,7 +2589,7 @@ static int _dns_server_reply_passthrouth(struct dns_server_post_context *context
tlog(TLOG_ERROR, "update cache info failed."); tlog(TLOG_ERROR, "update cache info failed.");
return -1; return -1;
} }
ret = _dns_reply_inpacket(request, context->inpacket, context->inpacket_len); _dns_reply_inpacket(request, context->inpacket, context->inpacket_len);
} }
return _dns_server_reply_all_pending_list(request, context); return _dns_server_reply_all_pending_list(request, context);
@@ -2651,7 +2633,7 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, unsi
_dns_server_process_answer(request, domain, packet, result_flag); _dns_server_process_answer(request, domain, packet, result_flag);
return 0; return 0;
} else if (rtype == DNS_QUERY_ERR) { } else if (rtype == DNS_QUERY_ERR) {
tlog(TLOG_ERROR, "request faield, %s", domain); tlog(TLOG_ERROR, "request failed, %s", domain);
return -1; return -1;
} else { } else {
pthread_mutex_lock(&request->ip_map_lock); pthread_mutex_lock(&request->ip_map_lock);
@@ -3309,15 +3291,12 @@ static int _dns_server_process_cache_addr(struct dns_request *request, struct dn
request->rcode = DNS_RC_NOERROR; request->rcode = DNS_RC_NOERROR;
_dns_result_callback(request); struct dns_server_post_context context;
_dns_server_post_context_init(&context, request);
if (request->prefetch == 0) { context.do_reply = 1;
struct dns_server_post_context context; context.do_audit = 1;
_dns_server_post_context_init(&context, request); context.do_ipset = 1;
context.do_reply = 1; _dns_request_post(&context);
context.do_audit = 1;
_dns_request_post(&context);
}
return 0; return 0;
errout: errout:
@@ -3345,6 +3324,7 @@ static int _dns_server_process_cache_packet(struct dns_request *request, struct
return -1; return -1;
} }
request->rcode = context.packet->head.rcode;
context.do_cache = 0; context.do_cache = 0;
context.do_ipset = 0; context.do_ipset = 0;
context.do_audit = 1; context.do_audit = 1;
@@ -3414,6 +3394,7 @@ static int _dns_server_process_cache(struct dns_request *request)
if ((dns_cache_A->info.speed + (dns_conf_dualstack_ip_selection_threshold * 10)) < dns_cache->info.speed || if ((dns_cache_A->info.speed + (dns_conf_dualstack_ip_selection_threshold * 10)) < dns_cache->info.speed ||
dns_cache->info.speed < 0) { dns_cache->info.speed < 0) {
tlog(TLOG_DEBUG, "Force IPV4 perfered."); tlog(TLOG_DEBUG, "Force IPV4 perfered.");
request->dualstack_selection_force_A = 1;
ret = _dns_server_reply_SOA(DNS_RC_NOERROR, request); ret = _dns_server_reply_SOA(DNS_RC_NOERROR, request);
goto out_update_cache; goto out_update_cache;
} }
@@ -4422,13 +4403,6 @@ static void _dns_server_tcp_idle_check(void)
} }
} }
int testfunc(char *domain, dns_rtcode_t rtcode, dns_type_t addr_type, char *ip,
unsigned int ping_time, void *user_ptr)
{
tlog(TLOG_ERROR, "Result: %s, %d -> %s %d", domain, rtcode, ip, ping_time);
return 0;
}
static void _dns_server_period_run_second(void) static void _dns_server_period_run_second(void)
{ {
static unsigned int sec = 0; static unsigned int sec = 0;
@@ -4488,6 +4462,10 @@ static void _dns_server_period_run(void)
{ {
/* Need to use tcping detection speed */ /* Need to use tcping detection speed */
int check_order = request->check_order + 1; int check_order = request->check_order + 1;
if (request->ip_map_num == 0) {
continue;
}
if (request->send_tick < now - (check_order * DNS_PING_CHECK_INTERVAL) && request->has_ping_result == 0) { if (request->send_tick < now - (check_order * DNS_PING_CHECK_INTERVAL) && request->has_ping_result == 0) {
_dns_server_request_get(request); _dns_server_request_get(request);
list_add_tail(&request->check_list, &check_list); list_add_tail(&request->check_list, &check_list);

View File

@@ -494,7 +494,7 @@ static int _fast_ping_sendping_v4(struct ping_host_struct *ping_host)
ping_host->addr_len); ping_host->addr_len);
if (len < 0 || len != sizeof(struct fast_ping_packet)) { if (len < 0 || len != sizeof(struct fast_ping_packet)) {
int err = errno; int err = errno;
if (errno == ENETUNREACH || errno == EINVAL) { if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
goto errout; goto errout;
} }
char ping_host_name[PING_MAX_HOSTLEN]; char ping_host_name[PING_MAX_HOSTLEN];
@@ -541,7 +541,7 @@ static int _fast_ping_sendping_udp(struct ping_host_struct *ping_host)
len = sendto(fd, &dns_head, sizeof(dns_head), 0, (struct sockaddr *)&ping_host->addr, ping_host->addr_len); len = sendto(fd, &dns_head, sizeof(dns_head), 0, (struct sockaddr *)&ping_host->addr, ping_host->addr_len);
if (len < 0 || len != sizeof(dns_head)) { if (len < 0 || len != sizeof(dns_head)) {
int err = errno; int err = errno;
if (errno == ENETUNREACH || errno == EINVAL) { if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
goto errout; goto errout;
} }
char ping_host_name[PING_MAX_HOSTLEN]; char ping_host_name[PING_MAX_HOSTLEN];
@@ -588,7 +588,7 @@ static int _fast_ping_sendping_tcp(struct ping_host_struct *ping_host)
if (connect(fd, (struct sockaddr *)&ping_host->addr, ping_host->addr_len) != 0) { if (connect(fd, (struct sockaddr *)&ping_host->addr, ping_host->addr_len) != 0) {
if (errno != EINPROGRESS) { if (errno != EINPROGRESS) {
char ping_host_name[PING_MAX_HOSTLEN]; char ping_host_name[PING_MAX_HOSTLEN];
if (errno == ENETUNREACH || errno == EINVAL) { if (errno == ENETUNREACH || errno == EINVAL || errno == EADDRNOTAVAIL) {
goto errout; goto errout;
} }
@@ -1099,9 +1099,8 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
_fast_ping_host_put(ping_host); _fast_ping_host_put(ping_host);
return ping_host; return ping_host;
errout_remove: errout_remove:
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_ERROR, &ping_host->addr, ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_ERROR, &ping_host->addr, ping_host->addr_len,
ping_host->addr_len, ping_host->seq, ping_host->ttl, 0, ping_host->seq, ping_host->ttl, 0, ping_host->error, ping_host->userptr);
ping_host->error, ping_host->userptr);
fast_ping_stop(ping_host); fast_ping_stop(ping_host);
_fast_ping_host_put(ping_host); _fast_ping_host_put(ping_host);
ping_host = NULL; ping_host = NULL;
@@ -1559,8 +1558,8 @@ static void _fast_ping_period_run(void)
millisecond = interval.tv_sec * 1000 + interval.tv_usec / 1000; millisecond = interval.tv_sec * 1000 + interval.tv_usec / 1000;
if (millisecond >= ping_host->timeout && ping_host->send == 1) { if (millisecond >= ping_host->timeout && ping_host->send == 1) {
ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_TIMEOUT, &ping_host->addr, ping_host->ping_callback(ping_host, ping_host->host, PING_RESULT_TIMEOUT, &ping_host->addr,
ping_host->addr_len, ping_host->seq, ping_host->ttl, &interval, ping_host->addr_len, ping_host->seq, ping_host->ttl, &interval, ping_host->error,
ping_host->error, ping_host->userptr); ping_host->userptr);
ping_host->send = 0; ping_host->send = 0;
} }