From 2f57d8d7e77b5aa3c73f72bd6989f0618bc49dfc Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Mon, 29 Apr 2024 23:52:34 +0800 Subject: [PATCH] dns_client: retry upstream server when discard IP --- src/dns_client.c | 13 ++++++++++--- src/dns_client.h | 1 + src/dns_server.c | 9 +++++++++ test/cases/test-ip-rule.cc | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/dns_client.c b/src/dns_client.c index 48c4ea1575..5ae5bd2275 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -1892,7 +1892,12 @@ static int _dns_client_recv(struct dns_server_info *server_info, unsigned char * _dns_client_retry_dns_query(query); } } else { - query->has_result = 1; + if (ret == DNS_CLIENT_ACTION_OK) { + query->has_result = 1; + } else { + tlog(TLOG_DEBUG, "query %s result is invalid, %d", query->domain, ret); + } + if (request_num == 0) { /* if all server replied, or done, stop query, release resource */ _dns_client_query_remove(query); @@ -2595,9 +2600,11 @@ static int _dns_client_process_udp(struct dns_server_info *server_info, struct e } } + int from_port = from.ss_family == AF_INET ? ntohs(((struct sockaddr_in *)&from)->sin_port) + : ntohs(((struct sockaddr_in6 *)&from)->sin6_port); int latency = get_tick_count() - server_info->send_tick; - tlog(TLOG_DEBUG, "recv udp packet from %s, len: %d, ttl: %d, latency: %d", - get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), len, ttl, latency); + tlog(TLOG_DEBUG, "recv udp packet from %s:%d, len: %d, ttl: %d, latency: %d", + get_host_by_addr(from_host, sizeof(from_host), (struct sockaddr *)&from), from_port, len, ttl, latency); /* update recv time */ time(&server_info->last_recv); diff --git a/src/dns_client.h b/src/dns_client.h index 30c877b3a3..0553cdcfe7 100644 --- a/src/dns_client.h +++ b/src/dns_client.h @@ -72,6 +72,7 @@ struct dns_server_info; #define DNS_CLIENT_ACTION_UNDEFINE (-1) #define DNS_CLIENT_ACTION_DROP (-2) #define DNS_CLIENT_ACTION_RETRY (-3) +#define DNS_CLIENT_ACTION_MAY_RETRY (-4) typedef int (*dns_client_callback)(const char *domain, dns_result_type rtype, struct dns_server_info *server_info, struct dns_packet *packet, unsigned char *inpacket, int inpacket_len, void *user_ptr); diff --git a/src/dns_server.c b/src/dns_server.c index 938a9f028a..0c1a019ae3 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -4038,6 +4038,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d int ret = 0; int is_skip = 0; int has_result = 0; + int is_rcode_set = 0; if (packet->head.rcode != DNS_RC_NOERROR && packet->head.rcode != DNS_RC_NXDOMAIN) { if (request->rcode == DNS_RC_SERVFAIL) { @@ -4092,6 +4093,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d return -1; } request->rcode = packet->head.rcode; + is_rcode_set = 1; } break; case DNS_T_AAAA: { ret = _dns_server_process_answer_AAAA(rrs, request, domain, cname, result_flag); @@ -4104,6 +4106,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d return -1; } request->rcode = packet->head.rcode; + is_rcode_set = 1; } break; case DNS_T_NS: { char nsname[DNS_MAX_CNAME_LEN]; @@ -4130,6 +4133,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d continue; } request->rcode = packet->head.rcode; + is_rcode_set = 1; if (request->has_ip == 0) { request->passthrough = 1; _dns_server_request_complete(request); @@ -4147,6 +4151,7 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d request->has_soa = 1; if (request->rcode != DNS_RC_NOERROR) { request->rcode = packet->head.rcode; + is_rcode_set = 1; } dns_get_SOA(rrs, name, 128, &ttl, &request->soa); tlog(TLOG_DEBUG, @@ -4182,6 +4187,10 @@ static int _dns_server_process_answer(struct dns_request *request, const char *d return DNS_CLIENT_ACTION_RETRY; } + if (is_rcode_set == 0 && has_result == 1) { + return DNS_CLIENT_ACTION_MAY_RETRY; + } + return DNS_CLIENT_ACTION_OK; } diff --git a/test/cases/test-ip-rule.cc b/test/cases/test-ip-rule.cc index 6f935bacfb..62607a18de 100644 --- a/test/cases/test-ip-rule.cc +++ b/test/cases/test-ip-rule.cc @@ -120,6 +120,7 @@ TEST_F(IPRule, black_list) return smartdns::SERVER_REQUEST_SOA; } + usleep(800000); smartdns::MockServer::AddIP(request, request->domain.c_str(), "1.2.3.4", 611); return smartdns::SERVER_REQUEST_OK; });