Nick Peng 3 роки тому
батько
коміт
7d62226995
4 змінених файлів з 76 додано та 38 видалено
  1. 40 23
      src/dns_client.c
  2. 29 7
      src/dns_server.c
  3. 5 6
      src/fast_ping.c
  4. 2 2
      src/smartdns.c

+ 40 - 23
src/dns_client.c

@@ -133,6 +133,7 @@ struct dns_server_pending_group {
 
 struct dns_server_pending {
 	struct list_head list;
+	struct list_head retry_list;
 	atomic_t refcnt;
 
 	char host[DNS_HOSTNAME_LEN];
@@ -1244,7 +1245,7 @@ void _dns_client_server_pending_get(struct dns_server_pending *pending)
 	}
 }
 
-void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
+void _dns_client_server_pending_release(struct dns_server_pending *pending)
 {
 	struct dns_server_pending_group *group, *tmp;
 
@@ -1258,6 +1259,7 @@ void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
 		return;
 	}
 
+	pthread_mutex_lock(&pending_server_mutex);
 	list_for_each_entry_safe(group, tmp, &pending->group_list, list)
 	{
 		list_del_init(&group->list);
@@ -1265,26 +1267,16 @@ void _dns_client_server_pending_release_lck(struct dns_server_pending *pending)
 	}
 
 	list_del_init(&pending->list);
+	pthread_mutex_unlock(&pending_server_mutex);
 	free(pending);
 }
 
-void _dns_client_server_pending_release(struct dns_server_pending *pending)
+void _dns_client_server_pending_remove(struct dns_server_pending *pending)
 {
-	int refcnt = atomic_dec_return(&pending->refcnt);
-
-	if (refcnt) {
-		if (refcnt < 0) {
-			tlog(TLOG_ERROR, "BUG: pending refcnt is %d", refcnt);
-			abort();
-		}
-		return;
-	}
-
 	pthread_mutex_lock(&pending_server_mutex);
 	list_del_init(&pending->list);
 	pthread_mutex_unlock(&pending_server_mutex);
-
-	free(pending);
+	_dns_client_server_pending_release(pending);
 }
 
 static int _dns_client_server_pending(char *server_ip, int port, dns_server_type_t server_type,
@@ -1310,6 +1302,7 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type
 	pending->has_v6 = 0;
 	_dns_client_server_pending_get(pending);
 	INIT_LIST_HEAD(&pending->group_list);
+	INIT_LIST_HEAD(&pending->retry_list);
 	memcpy(&pending->flags, flags, sizeof(struct client_dns_server_flags));
 
 	pthread_mutex_lock(&pending_server_mutex);
@@ -3227,20 +3220,30 @@ static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip
 static void _dns_client_remove_all_pending_servers(void)
 {
 	struct dns_server_pending *pending, *tmp;
+	LIST_HEAD(remove_list);
 
 	pthread_mutex_lock(&pending_server_mutex);
 	list_for_each_entry_safe(pending, tmp, &pending_servers, list)
 	{
 		list_del_init(&pending->list);
-		_dns_client_server_pending_release_lck(pending);
+		list_add(&pending->retry_list, &remove_list);
+		_dns_client_server_pending_get(pending);
 	}
 	pthread_mutex_unlock(&pending_server_mutex);
+
+	list_for_each_entry_safe(pending, tmp, &remove_list, retry_list)
+	{
+		list_del_init(&pending->retry_list);
+		_dns_client_server_pending_release(pending);
+		_dns_client_server_pending_remove(pending);
+	}
 }
 
 static void _dns_client_add_pending_servers(void)
 {
 	struct dns_server_pending *pending, *tmp;
 	static int dely = 0;
+	LIST_HEAD(retry_list);
 
 	/* add pending server after 3 seconds */
 	if (++dely < 3) {
@@ -3250,6 +3253,13 @@ static void _dns_client_add_pending_servers(void)
 
 	pthread_mutex_lock(&pending_server_mutex);
 	list_for_each_entry_safe(pending, tmp, &pending_servers, list)
+	{
+		list_add(&pending->retry_list, &retry_list);
+		_dns_client_server_pending_get(pending);
+	}
+	pthread_mutex_unlock(&pending_server_mutex);
+
+	list_for_each_entry_safe(pending, tmp, &retry_list, retry_list)
 	{
 		/* send dns type A, AAAA query to bootstrap DNS server */
 		int add_success = 0;
@@ -3259,7 +3269,8 @@ static void _dns_client_add_pending_servers(void)
 			pending->query_v4 = 1;
 			_dns_client_server_pending_get(pending);
 			if (dns_server_query(pending->host, DNS_T_A, 0, _dns_client_pending_server_resolve, pending) != 0) {
-				_dns_client_server_pending_release_lck(pending);
+				_dns_client_server_pending_release(pending);
+				pending->query_v4 = 0;
 			}
 		}
 
@@ -3267,10 +3278,14 @@ static void _dns_client_add_pending_servers(void)
 			pending->query_v6 = 1;
 			_dns_client_server_pending_get(pending);
 			if (dns_server_query(pending->host, DNS_T_AAAA, 0, _dns_client_pending_server_resolve, pending) != 0) {
-				_dns_client_server_pending_release_lck(pending);
+				_dns_client_server_pending_release(pending);
+				pending->query_v4 = 0;
 			}
 		}
 
+		list_del_init(&pending->retry_list);
+		_dns_client_server_pending_release(pending);
+
 		/* if both A, AAAA has query result, select fastest IP address */
 		if (pending->has_v4 && pending->has_v6) {
 			if (pending->ping_time_v4 <= pending->ping_time_v6 && pending->ipv4[0]) {
@@ -3291,14 +3306,17 @@ static void _dns_client_add_pending_servers(void)
 		}
 
 		pending->retry_cnt++;
-		if (pending->retry_cnt >= DNS_PENDING_SERVER_RETRY || add_success) {
+		if (pending->retry_cnt == 1) {
+			continue;
+		}
+
+		if (pending->retry_cnt - 1 > DNS_PENDING_SERVER_RETRY || add_success) {
 			if (add_success == 0) {
 				tlog(TLOG_WARN, "add pending DNS server %s failed.", pending->host);
 			}
-			list_del_init(&pending->list);
-			_dns_client_server_pending_release_lck(pending);
+			_dns_client_server_pending_remove(pending);
 		} else {
-			tlog(TLOG_INFO, "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 - 1);
 			pending->query_v4 = 0;
 			pending->query_v6 = 0;
 		}
@@ -3312,10 +3330,9 @@ static void _dns_client_add_pending_servers(void)
 				return;
 			}
 
-			_dns_client_server_pending_release_lck(pending);
+			_dns_client_server_pending_release(pending);
 		}
 	}
-	pthread_mutex_unlock(&pending_server_mutex);
 }
 
 static void _dns_client_period_run_second(void)

+ 29 - 7
src/dns_server.c

@@ -732,7 +732,7 @@ static int _dns_add_rrs(struct dns_server_post_context *context)
 	}
 
 	if (request->rcode != DNS_RC_NOERROR) {
-		tlog(TLOG_INFO, "result %s, qtype: %d, rc-code: %d", domain, context->qtype, request->rcode);
+		tlog(TLOG_INFO, "result %s, qtype: %d, rccode: %d", domain, context->qtype, request->rcode);
 	}
 
 	return ret;
@@ -2434,6 +2434,7 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
 {
 	int ttl = 0;
 	char name[DNS_MAX_CNAME_LEN] = {0};
+	char cname[DNS_MAX_CNAME_LEN];
 	int rr_count = 0;
 	int i = 0;
 	int j = 0;
@@ -2457,6 +2458,7 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
 			switch (rrs->type) {
 			case DNS_T_A: {
 				unsigned char addr[4];
+				int ttl_tmp;
 				if (request->qtype != DNS_T_A) {
 					/* ignore non-matched query type */
 					if (request->dualstack_selection == 0) {
@@ -2465,9 +2467,15 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
 				}
 				_dns_server_request_get(request);
 				/* get A result */
-				dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
+				dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr);
+
+				/* if domain is not match */
+				if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) {
+					_dns_server_request_release(request);
+					continue;
+				}
 
-				tlog(TLOG_DEBUG, "domain: %s TTL:%d IP: %d.%d.%d.%d", name, ttl, addr[0], addr[1], addr[2], addr[3]);
+				tlog(TLOG_DEBUG, "domain: %s TTL:%d IP: %d.%d.%d.%d", name, ttl_tmp, addr[0], addr[1], addr[2], addr[3]);
 
 				/* ip rule check */
 				ip_check_result = _dns_server_ip_rule_check(request, addr, 4, DNS_T_A, result_flag);
@@ -2480,20 +2488,28 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
 					_dns_server_request_release(request);
 					return 0;
 				}
+				ttl = ttl_tmp;
 				_dns_server_request_release(request);
 			} break;
 			case DNS_T_AAAA: {
 				unsigned char addr[16];
+				int ttl_tmp;
 				if (request->qtype != DNS_T_AAAA) {
 					/* ignore non-matched query type */
 					break;
 				}
 				_dns_server_request_get(request);
-				dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
+				dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl_tmp, addr);
+
+				/* if domain is not match */
+				if (strncmp(name, domain, DNS_MAX_CNAME_LEN) != 0 && strncmp(cname, name, DNS_MAX_CNAME_LEN) != 0) {
+					_dns_server_request_release(request);
+					continue;
+				}
 
 				tlog(TLOG_DEBUG,
 					 "domain: %s TTL: %d IP: %.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
-					 name, ttl, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8],
+					 name, ttl_tmp, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8],
 					 addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
 
 				ip_check_result = _dns_server_ip_rule_check(request, addr, 16, DNS_T_AAAA, result_flag);
@@ -2506,8 +2522,13 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
 					_dns_server_request_release(request);
 					return 0;
 				}
+
+				ttl = ttl_tmp;
 				_dns_server_request_release(request);
 			} break;
+			case DNS_T_CNAME: {
+				dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
+			} break;
 			default:
 				break;
 			}
@@ -2570,7 +2591,7 @@ static int _dns_server_get_answer(struct dns_server_post_context *context)
 				if (_dns_ip_address_check_add(request, name, addr, DNS_T_AAAA) != 0) {
 					continue;
 				}
-				
+
 				context->ip_num++;
 				if (request->has_ip == 1) {
 					continue;
@@ -3412,6 +3433,7 @@ static int _dns_server_process_cache_packet(struct dns_request *request, struct
 	_dns_server_post_context_init(&context, request);
 	context.inpacket = cache_packet->data;
 	context.inpacket_len = cache_packet->head.size;
+	request->ping_time = dns_cache->info.speed;
 
 	if (dns_decode(context.packet, context.packet_maxlen, cache_packet->data, cache_packet->head.size) != 0) {
 		return -1;
@@ -4149,7 +4171,7 @@ int dns_server_query(char *domain, int qtype, uint32_t server_flags, dns_result_
 		goto errout;
 	}
 
-	_dns_server_request_release(request);
+	_dns_server_request_release_complete(request, 0);
 	return ret;
 errout:
 	if (request) {

+ 5 - 6
src/fast_ping.c

@@ -1216,6 +1216,11 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
 		return NULL;
 	}
 
+	if (icmp->icmp_type != ICMP_ECHOREPLY) {
+		tlog(TLOG_DEBUG, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY);
+		return NULL;
+	}
+
 	if (ping.no_unprivileged_ping) {
 		if (ip->ip_p != IPPROTO_ICMP) {
 			tlog(TLOG_ERROR, "ip type faild, %d:%d", ip->ip_p, IPPROTO_ICMP);
@@ -1228,12 +1233,6 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct *
 		}
 	}
 
-	if (icmp->icmp_type != ICMP_ECHOREPLY) {
-		tlog(TLOG_DEBUG, "icmp type faild, %d:%d", icmp->icmp_type, ICMP_ECHOREPLY);
-		return NULL;
-	}
-
-
 	return packet;
 }
 

+ 2 - 2
src/smartdns.c

@@ -397,7 +397,7 @@ static int _smartdns_run(void)
 
 static void _smartdns_exit(void)
 {
-	tlog(TLOG_INFO, "smartdns starting exit...");
+	tlog(TLOG_INFO, "smartdns exit...");
 	dns_server_exit();
 	dns_client_exit();
 	fast_ping_exit();
@@ -408,7 +408,7 @@ static void _smartdns_exit(void)
 
 static void _sig_exit(int signo)
 {
-	tlog(TLOG_INFO, "start stop smartdns");
+	tlog(TLOG_INFO, "stop smartdns by signal %d", signo);
 	dns_server_stop();
 }