Browse Source

pending: fix pending server resolve issue

Nick Peng 5 năm trước cách đây
mục cha
commit
69ba3f8789
3 tập tin đã thay đổi với 87 bổ sung5 xóa
  1. 1 1
      src/dns_client.c
  2. 85 3
      src/dns_server.c
  3. 1 1
      src/smartdns.c

+ 1 - 1
src/dns_client.c

@@ -862,6 +862,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
 
 		SSL_CTX_set_options(server_info->ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
 		SSL_CTX_set_session_cache_mode(server_info->ssl_ctx, SSL_SESS_CACHE_CLIENT);
+		SSL_CTX_sess_set_cache_size(server_info->ssl_ctx, 64);
 		if (_dns_client_set_trusted_cert(server_info->ssl_ctx) != 0) {
 			tlog(TLOG_WARN, "disable check certificate for %s.", server_info->ip);
 			server_info->skip_check_cert = 1;
@@ -2931,7 +2932,6 @@ static void _dns_client_add_pending_servers(void)
 
 		/* 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]) {
 				dnsserver_ip = pending->ipv4;
 			} else {

+ 85 - 3
src/dns_server.c

@@ -1631,6 +1631,84 @@ static int _dns_server_passthrough_rule_check(struct dns_request *request, char
 	return -1;
 }
 
+static int _dns_server_get_answer(struct dns_request *request, struct dns_packet *packet)
+{
+	int i = 0;
+	int j = 0;
+	int ttl = 0;
+	struct dns_rrs *rrs = NULL;
+	int rr_count = 0;
+	char name[DNS_MAX_CNAME_LEN] = {0};
+
+	for (j = 1; j < DNS_RRS_END; j++) {
+		rrs = dns_get_rrs_start(packet, j, &rr_count);
+		for (i = 0; i < rr_count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
+			switch (rrs->type) {
+			case DNS_T_A: {
+				unsigned char addr[4];
+				char name[DNS_MAX_CNAME_LEN] = {0};
+
+				if (request->qtype != DNS_T_A) {
+					continue;
+				}
+
+				/* get A result */
+				dns_get_A(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
+				memcpy(request->ipv4_addr, addr, DNS_RR_A_LEN);
+				request->ttl_v4 = _dns_server_get_conf_ttl(ttl);
+				request->has_ipv4 = 1;
+				request->rcode = packet->head.rcode;
+			} break;
+			case DNS_T_AAAA: {
+				unsigned char addr[16];
+				char name[DNS_MAX_CNAME_LEN] = {0};
+
+				if (request->qtype != DNS_T_AAAA) {
+					/* ignore non-matched query type */
+					continue;
+				}
+				dns_get_AAAA(rrs, name, DNS_MAX_CNAME_LEN, &ttl, addr);
+				memcpy(request->ipv6_addr, addr, DNS_RR_AAAA_LEN);
+				request->ttl_v6 = _dns_server_get_conf_ttl(ttl);
+				request->has_ipv6 = 1;
+				request->rcode = packet->head.rcode;
+			} break;
+			case DNS_T_NS: {
+				char cname[DNS_MAX_CNAME_LEN];
+				dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
+				tlog(TLOG_DEBUG, "NS: %s ttl:%d cname: %s\n", name, ttl, cname);
+			} break;
+			case DNS_T_CNAME: {
+				char cname[DNS_MAX_CNAME_LEN];
+				dns_get_CNAME(rrs, name, DNS_MAX_CNAME_LEN, &ttl, cname, DNS_MAX_CNAME_LEN);
+				tlog(TLOG_DEBUG, "name:%s ttl: %d cname: %s\n", name, ttl, cname);
+				safe_strncpy(request->cname, cname, DNS_MAX_CNAME_LEN);
+				request->ttl_cname = ttl;
+				request->has_cname = 1;
+			} break;
+			case DNS_T_SOA: {
+				request->has_soa = 1;
+				request->rcode = packet->head.rcode;
+				dns_get_SOA(rrs, name, 128, &ttl, &request->soa);
+				tlog(TLOG_DEBUG,
+					 "domain: %s, qtype: %d, SOA: mname: %s, rname: %s, serial: %d, refresh: %d, retry: %d, expire: "
+					 "%d, minimum: %d",
+					 request->domain, request->qtype, request->soa.mname, request->soa.rname, request->soa.serial,
+					 request->soa.refresh, request->soa.retry, request->soa.expire, request->soa.minimum);
+				if (atomic_inc_return(&request->soa_num) >= (dns_server_num() / 2)) {
+					_dns_server_request_complete(request);
+				}
+			} break;
+			default:
+				tlog(TLOG_DEBUG, "%s, qtype: %d", name, rrs->type);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
 static int _dns_server_reply_passthrouth(struct dns_request *request, struct dns_packet *packet,
 										 unsigned char *inpacket, int inpacket_len)
 {
@@ -1640,6 +1718,11 @@ static int _dns_server_reply_passthrouth(struct dns_request *request, struct dns
 		return 0;
 	}
 
+	if (request->result_callback) {
+		_dns_server_get_answer(request, packet);
+		_dns_result_callback(request);
+	}
+
 	if (request->conn == NULL) {
 		return 0;
 	}
@@ -1673,7 +1756,6 @@ static int dns_server_resolve_callback(char *domain, dns_result_type rtype, unsi
 
 			return _dns_server_reply_passthrouth(request, packet, inpacket, inpacket_len);
 		}
-
 		_dns_server_process_answer(request, domain, packet, result_flag);
 		return 0;
 	} else if (rtype == DNS_QUERY_ERR) {
@@ -2045,7 +2127,7 @@ static int _dns_server_process_cache(struct dns_request *request)
 				if (dns_cache_get_ttl(dns_cache_A) == 0) {
 					_dns_server_prefetch_request(request->domain, request->qtype);
 				}
-				ret =  _dns_server_reply_SOA(DNS_RC_NOERROR, request);
+				ret = _dns_server_reply_SOA(DNS_RC_NOERROR, request);
 				goto out;
 			}
 		}
@@ -3074,7 +3156,7 @@ static int _dns_create_socket(const char *host_ip, int type)
 	setsockopt(fd, IPPROTO_IP, IP_TOS, &ip_tos, sizeof(ip_tos));
 
 	if (bind(fd, gai->ai_addr, gai->ai_addrlen) != 0) {
-		tlog(TLOG_ERROR, "bind service failed, %s\n", strerror(errno));
+		tlog(TLOG_ERROR, "bind service %s failed, %s\n", host_ip, strerror(errno));
 		goto errout;
 	}
 

+ 1 - 1
src/smartdns.c

@@ -439,6 +439,7 @@ int main(int argc, char *argv[])
 		goto errout;
 	}
 
+	signal(SIGPIPE, SIG_IGN);
 	if (dns_server_load_conf(config_file) != 0) {
 		fprintf(stderr, "load config failed.\n");
 		goto errout;
@@ -451,7 +452,6 @@ int main(int argc, char *argv[])
 	}
 
 	signal(SIGINT, _sig_exit);
-	signal(SIGPIPE, SIG_IGN);
 	atexit(_smartdns_exit);
 
 	return _smartdns_run();