diff --git a/0001-ADD-OHOS-DNS-PROXY-BY-NETSYS.patch b/0001-ADD-OHOS-DNS-PROXY-BY-NETSYS.patch index 5f6f46da27a8022e0117b834cc7ae31073780a19..1bbb12e86722309560920561b7d971bc72ef8922 100644 --- a/0001-ADD-OHOS-DNS-PROXY-BY-NETSYS.patch +++ b/0001-ADD-OHOS-DNS-PROXY-BY-NETSYS.patch @@ -1,8 +1,203 @@ +diff --git a/src/lib/ares_getaddrinfo.c b/src/lib/ares_getaddrinfo.c +index 0a0225a..3c9d022 100644 +--- a/src/lib/ares_getaddrinfo.c ++++ b/src/lib/ares_getaddrinfo.c +@@ -57,6 +57,7 @@ + # include "ares_platform.h" + #endif + ++ + struct host_query + { + ares_channel channel; +@@ -113,6 +114,153 @@ static int as_is_first(const struct host_query *hquery); + static int as_is_only(const struct host_query* hquery); + static int next_dns_lookup(struct host_query *hquery); + ++#if OHOS_DNS_PROXY_BY_NETSYS ++struct queryparam; ++typedef int (*PostDnsResult)(int netid, char* name, int usedtime, int queryfail, ++ struct addrinfo *res, struct queryparam *param); ++ ++static int getaddrinfor_from_netsys(const char* name, const char* service, ++ const struct ares_addrinfo_hints* hints, ++ ares_addrinfo_callback callback, void* arg) ++{ ++ struct addrinfo hint; ++ struct addrinfo *res = NULL; ++ struct addrinfo *res_each = NULL; ++ struct sockaddr_in *addr4 = NULL; ++ struct sockaddr_in6 *addr6 = NULL; ++ struct ares_addrinfo *ai_by_netsys = NULL; ++ unsigned short port = 0; ++ int status = ARES_ENODATA; ++ ++ memset(&hint, 0, sizeof(hint)); ++ hint.ai_family = hints->ai_family; ++ hint.ai_socktype = hints->ai_socktype; ++ port = (unsigned short)strtoul(service, NULL, 0); ++ ++ if (getaddrinfo(name, service, &hint, &res) == 0) { ++ ai_by_netsys = ares__malloc_addrinfo(); ++ if (!ai_by_netsys) { ++ freeaddrinfo(res); ++ return status; ++ } ++ for (res_each = res; res_each; res_each = res_each->ai_next) { ++ if (res_each->ai_family == AF_INET) { ++ addr4 = (struct sockaddr_in *)res_each->ai_addr; ++ if (ares_append_ai_node(AF_INET, port, 0, &addr4->sin_addr, &ai_by_netsys->nodes) == ARES_SUCCESS) { ++ status = ARES_SUCCESS; ++ } ++ } ++ if (res_each->ai_family == AF_INET6) { ++ addr6 = (struct sockaddr_in6 *)res_each->ai_addr; ++ if (ares_append_ai_node(AF_INET6, port, 0, &addr6->sin6_addr, &ai_by_netsys->nodes) == ARES_SUCCESS) { ++ status = ARES_SUCCESS; ++ } ++ } ++ } ++ if (status != ARES_SUCCESS) { ++ ares_freeaddrinfo(ai_by_netsys); ++ freeaddrinfo(res); ++ return status; ++ } ++ callback(arg, status, 0, ai_by_netsys); ++ freeaddrinfo(res); ++ return status; ++ } ++ return status; ++} ++ ++static int cares_dns_post_result_to_netsys_cache(char* name, int usedtime, int queryret, ++ struct addrinfo *res, struct queryparam *param) ++{ ++ int ret; ++ PostDnsResult func = NULL; ++ ++ *(void **) &func = cares_load_from_dns_lib(OHOS_POST_DNS_RESULT_FUNC_NAME); ++ if (!func) { ++ return -1; ++ } ++ ret = func(0, name, usedtime, queryret, res, param); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int cares_dns_post(struct host_query *hquery, char* name, ++ int queryret) ++{ ++ struct queryparam param = {0, 0, 0, 0, NULL}; ++ struct addrinfo *res = NULL; ++ struct ares_addrinfo *ai = NULL; ++ struct ares_addrinfo_node *nodes = NULL; ++ struct ares_addrinfo_node *next = NULL; ++ struct ares_addrinfo_hints *hints = NULL; ++ int n = 0; ++ int i = 0; ++ int tm = 0; ++ ++ if (hquery != NULL && hquery->channel != NULL) { ++ ai = hquery->ai; ++ hints = &hquery->hints; ++ if (hquery->channel->timeout != -1) { ++ tm = (hquery->channel->timeout) / 1000; ++ } ++ } ++ if (queryret == DNS_QUERY_COMMOM_FAIL || ai == NULL) { ++ cares_dns_post_result_to_netsys_cache(name, tm, DNS_QUERY_COMMOM_FAIL, NULL, ¶m); ++ return 0; ++ } ++ nodes = ai->nodes; ++ for (next = nodes; next; next = next->ai_next) { ++ n++; ++ } ++ ++ if (n == 0) { ++ cares_dns_post_result_to_netsys_cache(name, tm, DNS_QUERY_COMMOM_FAIL, NULL, ¶m); ++ return 0; ++ } ++ res = malloc(n * sizeof(struct addrinfo)); ++ if (res == NULL) { ++ cares_dns_post_result_to_netsys_cache(name, tm, DNS_QUERY_COMMOM_FAIL, NULL, ¶m); ++ return 0; ++ } ++ memset(res, 0, n * sizeof(struct addrinfo)); ++ ++ for (next = nodes, i = 0; next; next = next->ai_next, i++) { ++ res[i].ai_flags = next->ai_flags; ++ res[i].ai_family = next->ai_family; ++ res[i].ai_socktype = next->ai_socktype; ++ res[i].ai_protocol = next->ai_protocol; ++ res[i].ai_addrlen = next->ai_addrlen; ++ res[i].ai_canonname = name; ++ if (i) { ++ res[i-1].ai_next = &res[i]; ++ } ++ if (res[i].ai_addrlen > 0) { ++ res[i].ai_addr = malloc(res[i].ai_addrlen); ++ } ++ if (res[i].ai_addr == NULL) { ++ continue; ++ } ++ memcpy(res[i].ai_addr, next->ai_addr, res[i].ai_addrlen); ++ } ++ ++ cares_dns_post_result_to_netsys_cache(name, tm, queryret, res, ¶m); ++ if (res != NULL) { ++ for (i = 0; i < n ; i++) { ++ if (res[i].ai_addr != NULL) { ++ free(res[i].ai_addr); ++ res[i].ai_addr = NULL; ++ } ++ } ++ free(res); ++ } ++ return 0; ++} ++ ++#endif ++ + struct ares_addrinfo_cname *ares__malloc_addrinfo_cname() + { + struct ares_addrinfo_cname *cname = ares_malloc(sizeof(struct ares_addrinfo_cname)); +@@ -398,8 +546,11 @@ static void end_hquery(struct host_query *hquery, int status) + ares_freeaddrinfo(hquery->ai); + hquery->ai = NULL; + } +- ++#if OHOS_DNS_PROXY_BY_NETSYS ++ cares_dns_post(hquery, hquery->name, DNS_QUERY_SUCCESS); ++#endif + hquery->callback(hquery->arg, status, hquery->timeouts, hquery->ai); ++ + ares_free(hquery->name); + ares_free(hquery); + } +@@ -585,6 +736,15 @@ void ares_getaddrinfo(ares_channel channel, + char *alias_name = NULL; + int status; + ++#if OHOS_DNS_PROXY_BY_NETSYS ++ if (channel->set_specific_dns_server == 0) { ++ status = getaddrinfor_from_netsys(name, service, hints, callback, arg); ++ if (status == ARES_SUCCESS) { ++ return; ++ } ++ } ++#endif ++ + if (!hints) + { + hints = &default_hints; diff --git a/src/lib/ares_init.c b/src/lib/ares_init.c -index e8902c6..3a5a5f5 100644 +index e8902c6..18834b7 100644 --- a/src/lib/ares_init.c +++ b/src/lib/ares_init.c -@@ -58,6 +58,64 @@ +@@ -58,6 +58,50 @@ #undef WIN32 /* Redefined in MingW/MSVC headers */ #endif @@ -11,29 +206,15 @@ index e8902c6..3a5a5f5 100644 +#include +#include + -+#if DNS_CONFIG_DEBUG -+#ifndef DNS_CONFIG_PRINT -+#define DNS_CONFIG_PRINT(fmt, ...) printf("DNS " fmt "\n", ##__VA_ARGS__) -+#endif -+#else -+#define DNS_CONFIG_PRINT(fmt, ...) -+#endif -+ -+#define DNS_SO_PATH "libnetsys_client.z.so" -+#define OHOS_GET_CONFIG_FUNC_NAME "NetSysGetResolvConf" -+#define MAX_SERVER_NUM 4 -+#define MAX_SERVER_LENGTH 50 -+ +struct resolv_config { + int32_t error; + int32_t timeout_ms; + uint32_t retry_count; + char nameservers[MAX_SERVER_NUM][MAX_SERVER_LENGTH + 1]; +}; -+ +typedef int32_t (*GetConfig)(uint16_t netId, struct resolv_config *config); + -+static void *open_dns_lib(void) ++static void *cares_open_dns_lib(void) +{ + static void *lib = NULL; + if (lib != NULL) { @@ -48,9 +229,9 @@ index e8902c6..3a5a5f5 100644 + return lib; +} + -+static void *load_from_dns_lib(const char *symbol) ++void *cares_load_from_dns_lib(const char *symbol) +{ -+ void *lib_handle = open_dns_lib(); ++ void *lib_handle = cares_open_dns_lib(); + if (lib_handle == NULL) { + return NULL; + } @@ -67,7 +248,18 @@ index e8902c6..3a5a5f5 100644 static int init_by_options(ares_channel channel, const struct ares_options *options, int optmask); -@@ -1705,6 +1763,12 @@ static int init_by_resolv_conf(ares_channel channel) +@@ -149,7 +193,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, + channel->sock_func_cb_data = NULL; + channel->resolvconf_path = NULL; + channel->rand_state = NULL; +- ++#if OHOS_DNS_PROXY_BY_NETSYS ++ channel->set_specific_dns_server = 0; ++#endif + channel->last_server = 0; + channel->last_timeout_processed = (time_t)now.tv_sec; + +@@ -1705,6 +1751,12 @@ static int init_by_resolv_conf(ares_channel channel) int error; int update_domains; const char *resolvconf_path; @@ -80,12 +272,12 @@ index e8902c6..3a5a5f5 100644 /* Don't read resolv.conf and friends if we don't have to */ if (ARES_CONFIG_CHECK(channel)) -@@ -1720,6 +1784,36 @@ static int init_by_resolv_conf(ares_channel channel) +@@ -1720,6 +1772,36 @@ static int init_by_resolv_conf(ares_channel channel) resolvconf_path = PATH_RESOLV_CONF; } +#if OHOS_DNS_PROXY_BY_NETSYS -+ *(void **) &func = load_from_dns_lib(OHOS_GET_CONFIG_FUNC_NAME); ++ *(void **) &func = cares_load_from_dns_lib(OHOS_GET_CONFIG_FUNC_NAME); + if (!func) { + DNS_CONFIG_PRINT("%s: loading %s failed, use %s as a fallback", + __func__, OHOS_GET_CONFIG_FUNC_NAME, DNS_RESOLV_CONF_PATH); @@ -117,7 +309,7 @@ index e8902c6..3a5a5f5 100644 fp = fopen(resolvconf_path, "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) -@@ -1866,7 +1960,9 @@ static int init_by_resolv_conf(ares_channel channel) +@@ -1866,7 +1948,9 @@ static int init_by_resolv_conf(ares_channel channel) ares_free(sortlist); return status; } @@ -128,3 +320,81 @@ index e8902c6..3a5a5f5 100644 /* If we got any name server entries, fill them in. */ if (servers) { +diff --git a/src/lib/ares_options.c b/src/lib/ares_options.c +index de49de4..26c56a6 100644 +--- a/src/lib/ares_options.c ++++ b/src/lib/ares_options.c +@@ -379,7 +379,11 @@ static int set_servers_csv(ares_channel channel, + } + + rv = ares_set_servers_ports(channel, servers); +- ++#if OHOS_DNS_PROXY_BY_NETSYS ++ if(rv == ARES_SUCCESS){ ++ channel->set_specific_dns_server = 1; ++ } ++#endif + out: + if (csv) + ares_free(csv); +diff --git a/src/lib/ares_private.h b/src/lib/ares_private.h +index 518b5c3..4edefea 100644 +--- a/src/lib/ares_private.h ++++ b/src/lib/ares_private.h +@@ -127,6 +127,27 @@ W32_FUNC const char *_w32_GetHostsFile (void); + # define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) + #endif + ++#if OHOS_DNS_PROXY_BY_NETSYS ++#include ++ ++#if DNS_CONFIG_DEBUG ++#ifndef DNS_CONFIG_PRINT ++#define DNS_CONFIG_PRINT(fmt, ...) printf("DNS " fmt "\n", ##__VA_ARGS__) ++#endif ++#else ++#define DNS_CONFIG_PRINT(fmt, ...) ++#endif ++ ++#define DNS_SO_PATH "libnetsys_client.z.so" ++#define OHOS_GET_CONFIG_FUNC_NAME "NetSysGetResolvConf" ++#define OHOS_POST_DNS_RESULT_FUNC_NAME "NetSysPostDnsResult" ++#define DNS_QUERY_SUCCESS 0 ++#define DNS_QUERY_COMMOM_FAIL (-1) ++#define MAX_SERVER_NUM 4 ++#define MAX_SERVER_LENGTH 50 ++ ++#endif ++ + /********* EDNS defines section ******/ + #define EDNSPACKETSZ 1280 /* Reasonable UDP payload size, as suggested + in RFC2671 */ +@@ -333,7 +354,28 @@ struct ares_channeldata { + + /* Path for resolv.conf file, configurable via ares_options */ + char *resolvconf_path; ++#if OHOS_DNS_PROXY_BY_NETSYS ++ int set_specific_dns_server; ++#endif ++}; ++ ++#if OHOS_DNS_PROXY_BY_NETSYS ++/* ++typedef int (*net_dnsquery_hook)(int, int, int); //待解决,在本地不需要加这个能够编译成功,功能正常。 ++ //在CI门禁不加,报错unknown type name。 ++ //本地加上被报错会报错,重定义。 ++struct queryparam { //待解决,在本地不需要加这个能够编译成功,功能正常。 ++ //在CI门禁不加,报错be visible outside of this function(不会在函数外部可见)。 ++ //本地加上不会报错。 ++ int qp_type; ++ int qp_netid; ++ int qp_mark; ++ int qp_flag; ++ net_dnsquery_hook qhook; + }; ++*/ ++void *cares_load_from_dns_lib(const char *symbol); ++#endif + + /* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ + int ares__is_onion_domain(const char *name);