Просмотр исходного кода

dns_client: retry upstream server when discard IP

Nick Peng 1 год назад
Родитель
Сommit
2f57d8d7e7
4 измененных файлов с 21 добавлено и 3 удалено
  1. 10 3
      src/dns_client.c
  2. 1 0
      src/dns_client.h
  3. 9 0
      src/dns_server.c
  4. 1 0
      test/cases/test-ip-rule.cc

+ 10 - 3
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);

+ 1 - 0
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);

+ 9 - 0
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;
 }
 

+ 1 - 0
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;
 	});