From d748b9ed91d13ebdd37910de9e233b7a7d3b58f5 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Sun, 8 Sep 2024 15:44:10 +0800 Subject: [PATCH] dns_server: Optimize ECS compatibility and fix bootstrapdns resolution problem. --- .gitignore | 1 + src/dns_client.c | 56 +++++++++++++++++++++++++----------- src/dns_client.h | 4 +++ src/dns_conf.c | 15 +++++++++- src/dns_conf.h | 4 +++ src/smartdns.c | 2 ++ test/cases/test-bootstrap.cc | 2 +- test/cases/test-subnet.cc | 2 +- 8 files changed, 66 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 60da01cbbd..1126d701ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .vscode *.o +*.a *.pem .DS_Store *.swp. diff --git a/src/dns_client.c b/src/dns_client.c index 770e52e594..557fbacc25 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -1503,11 +1503,27 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type 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; diff --git a/src/dns_client.h b/src/dns_client.h index 8ec4d1c98c..383c335fc8 100644 --- a/src/dns_client.h +++ b/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; diff --git a/src/dns_conf.c b/src/dns_conf.c index c1ef2be866..51a4f03690 100644 --- a/src/dns_conf.c +++ b/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(), diff --git a/src/dns_conf.h b/src/dns_conf.h index b875c7a003..6f427997f0 100644 --- a/src/dns_conf.h +++ b/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; diff --git a/src/smartdns.c b/src/smartdns.c index 79c4864e36..bfc0474b81 100644 --- a/src/smartdns.c +++ b/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) { diff --git a/test/cases/test-bootstrap.cc b/test/cases/test-bootstrap.cc index d1df627bb5..1bc6d9c6b3 100644 --- a/test/cases/test-bootstrap.cc +++ b/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); diff --git a/test/cases/test-subnet.cc b/test/cases/test-subnet.cc index bff1e30313..c36915f3b9 100644 --- a/test/cases/test-subnet.cc +++ b/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 )""");