Jelajahi Sumber

dns_server:
Optimize ECS compatibility and fix bootstrapdns resolution problem.

Nick Peng 1 tahun lalu
induk
melakukan
d748b9ed91
8 mengubah file dengan 66 tambahan dan 20 penghapusan
  1. 1 0
      .gitignore
  2. 39 17
      src/dns_client.c
  3. 4 0
      src/dns_client.h
  4. 14 1
      src/dns_conf.c
  5. 4 0
      src/dns_conf.h
  6. 2 0
      src/smartdns.c
  7. 1 1
      test/cases/test-bootstrap.cc
  8. 1 1
      test/cases/test-subnet.cc

+ 1 - 0
.gitignore

@@ -1,5 +1,6 @@
 .vscode
 *.o
+*.a
 *.pem
 .DS_Store
 *.swp.

+ 39 - 17
src/dns_client.c

@@ -1503,11 +1503,27 @@ errout:
 	return -1;
 }
 
+static int _dns_client_resolv_ip_by_host(const char *host, char *ip, int ip_len)
+{
+	struct addrinfo *gai = NULL;
+	gai = _dns_client_getaddr(host, NULL, SOCK_STREAM, 0);
+	if (gai == NULL) {
+		return -1;
+	}
+
+	if (get_host_by_addr(ip, ip_len, gai->ai_addr) == NULL) {
+		freeaddrinfo(gai);
+		return -1;
+	}
+
+	freeaddrinfo(gai);
+	return 0;
+}
+
 static int _dns_client_add_server_pending(char *server_ip, char *server_host, int port, dns_server_type_t server_type,
 										  struct client_dns_server_flags *flags, int is_pending)
 {
 	int ret = 0;
-	struct addrinfo *gai = NULL;
 	char server_ip_tmp[DNS_HOSTNAME_LEN] = {0};
 
 	if (server_type >= DNS_SERVER_TYPE_END) {
@@ -1522,21 +1538,13 @@ static int _dns_client_add_server_pending(char *server_ip, char *server_host, in
 			return 0;
 		}
 	} else if (check_is_ipaddr(server_ip) && is_pending == 0) {
-		gai = _dns_client_getaddr(server_ip, NULL, SOCK_STREAM, 0);
-		if (gai == NULL) {
+		if (_dns_client_resolv_ip_by_host(server_ip, server_ip_tmp, sizeof(server_ip_tmp)) != 0) {
+			tlog(TLOG_ERROR, "resolve %s failed.", server_ip);
 			return -1;
 		}
 
-		if (get_host_by_addr(server_ip_tmp, sizeof(server_ip_tmp), gai->ai_addr) != NULL) {
-			tlog(TLOG_INFO, "resolve %s to %s.", server_ip, server_ip_tmp);
-			server_ip = server_ip_tmp;
-		} else {
-			tlog(TLOG_INFO, "resolve %s failed.", server_ip);
-			freeaddrinfo(gai);
-			return -1;
-		}
-
-		freeaddrinfo(gai);
+		tlog(TLOG_INFO, "resolve %s to %s.", server_ip, server_ip_tmp);
+		server_ip = server_ip_tmp;
 	}
 
 	/* add server */
@@ -1545,7 +1553,9 @@ static int _dns_client_add_server_pending(char *server_ip, char *server_host, in
 		goto errout;
 	}
 
-	dns_client_has_bootstrap_dns = 1;
+	if ((flags->server_flag & SERVER_FLAG_EXCLUDE_DEFAULT) == 0 || dns_conf_exist_bootstrap_dns) {
+		dns_client_has_bootstrap_dns = 1;
+	}
 
 	return 0;
 errout:
@@ -3765,15 +3775,15 @@ static int _dns_client_setup_server_packet(struct dns_server_info *server_info,
 		dns_set_OPT_option(packet, DNS_OPT_FLAG_DO);
 	}
 
-	if (server_info->type != DNS_SERVER_UDP && server_info->type != DNS_SERVER_MDNS) {
-		dns_add_OPT_TCP_KEEPALIVE(packet, 6000);
+	if (server_info->flags.tcp_keepalive > 0) {
+		dns_add_OPT_TCP_KEEPALIVE(packet, server_info->flags.tcp_keepalive);
 	}
 
 	if ((query->qtype == DNS_T_A && server_info->ecs_ipv4.enable)) {
 		dns_add_OPT_ECS(packet, &server_info->ecs_ipv4.ecs);
 	} else if ((query->qtype == DNS_T_AAAA && server_info->ecs_ipv6.enable)) {
 		dns_add_OPT_ECS(packet, &server_info->ecs_ipv6.ecs);
-	} else {
+	} else if (query->qtype == DNS_T_AAAA || query->qtype == DNS_T_A || server_info->flags.subnet_all_query_types) {
 		if (server_info->ecs_ipv6.enable) {
 			dns_add_OPT_ECS(packet, &server_info->ecs_ipv6.ecs);
 		} else if (server_info->ecs_ipv4.enable) {
@@ -4339,6 +4349,18 @@ static int _dns_client_add_pendings(struct dns_server_pending *pending, char *ip
 {
 	struct dns_server_pending_group *group = NULL;
 	struct dns_server_pending_group *tmp = NULL;
+	char ip_tmp[DNS_HOSTNAME_LEN] = {0};
+
+	if (check_is_ipaddr(ip) != 0) {
+		if (_dns_client_resolv_ip_by_host(ip, ip_tmp, sizeof(ip_tmp)) != 0) {
+			tlog(TLOG_WARN, "resolv %s failed.", ip);
+			return -1;
+		}
+
+		tlog(TLOG_INFO, "resolv %s to %s.", ip, ip_tmp);
+
+		ip = ip_tmp;
+	}
 
 	if (_dns_client_add_server_pending(ip, pending->host, pending->port, pending->type, &pending->flags, 0) != 0) {
 		return -1;

+ 4 - 0
src/dns_client.h

@@ -141,9 +141,13 @@ struct client_dns_server_flags {
 	unsigned int server_flag;
 	unsigned int result_flag;
 	long long set_mark;
+	int tcp_keepalive;
 	int drop_packet_latency_ms;
+
 	char proxyname[DNS_MAX_CNAME_LEN];
 	char ifname[DNS_SERVER_IFNAME_LEN];
+
+	int subnet_all_query_types;
 	struct client_dns_server_flag_ecs ipv4_ecs;
 	struct client_dns_server_flag_ecs ipv6_ecs;
 

+ 14 - 1
src/dns_conf.c

@@ -92,7 +92,7 @@ struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
 char dns_conf_server_name[DNS_MAX_SERVER_NAME_LEN];
 int dns_conf_server_num;
 static int dns_conf_resolv_hostname = 1;
-static char dns_conf_exist_bootstrap_dns;
+char dns_conf_exist_bootstrap_dns;
 
 int dns_conf_has_icmp_check;
 int dns_conf_has_tcp_check;
@@ -909,6 +909,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
 	unsigned int server_flag = 0;
 	unsigned char *spki = NULL;
 	int drop_packet_latency_ms = 0;
+	int tcp_keepalive = -1;
 	int is_bootstrap_dns = 0;
 	char host_ip[DNS_MAX_IPLEN] = {0};
 	int no_tls_host_name = 0;
@@ -939,6 +940,8 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
 		{"host-name", required_argument, NULL, 260}, /* host name */
 		{"http-host", required_argument, NULL, 261}, /* http host */
 		{"tls-host-verify", required_argument, NULL, 262 }, /* verify tls hostname */
+		{"tcp-keepalive", required_argument, NULL, 263}, /* tcp keepalive */
+		{"subnet-all-query-types", no_argument, NULL, 264}, /* send subnent for all query types.*/
 		{NULL, no_argument, NULL, 0}
 	};
 	/* clang-format on */
@@ -962,6 +965,8 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
 	server->proxyname[0] = '\0';
 	server->set_mark = -1;
 	server->drop_packet_latency_ms = drop_packet_latency_ms;
+	server->tcp_keepalive = tcp_keepalive;
+	server->subnet_all_query_types = 0;
 
 	if (parse_uri(ip, scheme, server->server, &port, server->path) != 0) {
 		return -1;
@@ -1100,6 +1105,14 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
 			}
 			break;
 		}
+		case 263: {
+			server->tcp_keepalive = atoi(optarg);
+			break;
+		}
+		case 264: {
+			server->subnet_all_query_types = 1;
+			break;
+		}
 		default:
 			if (optind > optind_last) {
 				tlog(TLOG_WARN, "unknown server option: %s at '%s:%d'.", argv[optind - 1], conf_get_conf_file(),

+ 4 - 0
src/dns_conf.h

@@ -386,6 +386,8 @@ struct dns_servers {
 	dns_server_type_t type;
 	long long set_mark;
 	unsigned int drop_packet_latency_ms;
+	int tcp_keepalive;
+	int subnet_all_query_types;
 	char skip_check_cert;
 	char spki[DNS_MAX_SPKI_LEN];
 	char hostname[DNS_MAX_CNAME_LEN];
@@ -674,6 +676,8 @@ extern ssize_t dns_conf_cache_max_memsize;
 extern struct dns_servers dns_conf_servers[DNS_MAX_SERVERS];
 extern int dns_conf_server_num;
 
+extern char dns_conf_exist_bootstrap_dns;
+
 /* proxy servers */
 extern struct dns_proxy_servers dns_conf_proxy_servers[PROXY_MAX_SERVERS];
 extern int dns_conf_proxy_server_num;

+ 2 - 0
src/smartdns.c

@@ -232,6 +232,8 @@ static int _smartdns_prepare_server_flags(struct client_dns_server_flags *flags,
 	flags->result_flag = server->result_flag;
 	flags->set_mark = server->set_mark;
 	flags->drop_packet_latency_ms = server->drop_packet_latency_ms;
+	flags->tcp_keepalive = server->tcp_keepalive;
+	flags->subnet_all_query_types = server->subnet_all_query_types;
 	safe_strncpy(flags->proxyname, server->proxyname, sizeof(flags->proxyname));
 	safe_strncpy(flags->ifname, server->ifname, sizeof(flags->ifname));
 	if (server->ipv4_ecs.enable) {

+ 1 - 1
test/cases/test-bootstrap.cc

@@ -55,7 +55,7 @@ TEST_F(BootStrap, bootstrap)
 
 	server.Start(R"""(bind [::]:60053
 server udp://127.0.0.1:62053 -bootstrap-dns
-server udp://example.com:61053
+server udp://example.com:61053 -group test
 )""");
 	smartdns::Client client;
 	usleep(2500000);

+ 1 - 1
test/cases/test-subnet.cc

@@ -289,7 +289,7 @@ TEST_F(SubNet, v4_server_subnet_txt)
 	});
 
 	server.Start(R"""(bind [::]:60053
-server 127.0.0.1:61053 -subnet 8.8.8.8/24
+server 127.0.0.1:61053 -subnet 8.8.8.8/24 -subnet-all-query-types
 dualstack-ip-selection no
 rr-ttl-min 0
 )""");