• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/src/lib/ares_init.c b/src/lib/ares_init.c
2index e8902c6..3a5a5f5 100644
3--- a/src/lib/ares_init.c
4+++ b/src/lib/ares_init.c
5@@ -58,6 +58,65 @@
6 #undef WIN32  /* Redefined in MingW/MSVC headers */
7 #endif
8
9+
10+#if OHOS_DNS_PROXY_BY_NETSYS
11+#include <dlfcn.h>
12+#include <stdio.h>
13+
14+#if DNS_CONFIG_DEBUG
15+#ifndef DNS_CONFIG_PRINT
16+#define DNS_CONFIG_PRINT(fmt, ...) printf("DNS " fmt "\n", ##__VA_ARGS__)
17+#endif
18+#else
19+#define DNS_CONFIG_PRINT(fmt, ...)
20+#endif
21+
22+#define DNS_SO_PATH "libnetsys_client.z.so"
23+#define OHOS_GET_CONFIG_FUNC_NAME "NetSysGetResolvConf"
24+#define MAX_SERVER_NUM 5
25+#define MAX_SERVER_LENGTH 50
26+
27+struct resolv_config {
28+  int32_t error;
29+  int32_t timeout_ms;
30+  uint32_t retry_count;
31+  uint32_t non_public;
32+  char nameservers[MAX_SERVER_NUM][MAX_SERVER_LENGTH + 1];
33+};
34+
35+typedef int32_t (*GetConfig)(uint16_t netId, struct resolv_config *config);
36+
37+static void *open_dns_lib(void)
38+{
39+  static void *lib = NULL;
40+  if (lib != NULL) {
41+    return lib;
42+  }
43+  lib = dlopen(DNS_SO_PATH, RTLD_LAZY);
44+  if (lib == NULL) {
45+    DNS_CONFIG_PRINT("%s: dlopen %s failed: %s",
46+      __func__, DNS_SO_PATH, dlerror());
47+    return NULL;
48+  }
49+  return lib;
50+}
51+
52+static void *load_from_dns_lib(const char *symbol)
53+{
54+  void *lib_handle = open_dns_lib();
55+  if (lib_handle == NULL) {
56+    return NULL;
57+  }
58+
59+  void *sym_addr = dlsym(lib_handle, symbol);
60+  if (sym_addr == NULL) {
61+    DNS_CONFIG_PRINT("%s: loading symbol %s with dlsym failed: %s",
62+      __func__, symbol, dlerror());
63+  }
64+  return sym_addr;
65+}
66+#endif
67+
68 static int init_by_options(ares_channel channel,
69                            const struct ares_options *options,
70                            int optmask);
71@@ -1705,6 +1764,12 @@ static int init_by_resolv_conf(ares_channel channel)
72     int error;
73     int update_domains;
74     const char *resolvconf_path;
75+#if OHOS_DNS_PROXY_BY_NETSYS
76+    int netid = 0;
77+    int ret = 0;
78+    int status_each = -1;
79+    GetConfig func = NULL;
80+#endif
81
82     /* Don't read resolv.conf and friends if we don't have to */
83     if (ARES_CONFIG_CHECK(channel))
84@@ -1720,6 +1785,36 @@ static int init_by_resolv_conf(ares_channel channel)
85       resolvconf_path = PATH_RESOLV_CONF;
86     }
87
88+#if OHOS_DNS_PROXY_BY_NETSYS
89+    *(void **) &func = load_from_dns_lib(OHOS_GET_CONFIG_FUNC_NAME);
90+    if (!func) {
91+      DNS_CONFIG_PRINT("%s: loading %s failed, use %s as a fallback",
92+        __func__, OHOS_GET_CONFIG_FUNC_NAME, DNS_RESOLV_CONF_PATH);
93+      goto etc_resolv_conf;
94+    }
95+    struct resolv_config config = {0};
96+    ret = func(netid, &config);
97+    if (ret < 0) {
98+      DNS_CONFIG_PRINT("__get_resolv_conf OHOS_GET_CONFIG_FUNC_NAME err %d\n", ret);
99+      return ARES_ENONAME;
100+    }
101+
102+    for (int i = 0; i < MAX_SERVER_NUM; ++i) {
103+      if (config.nameservers[i] == NULL || config.nameservers[i][0] == 0) {
104+        continue;
105+      }
106+      status_each = config_nameserver(&servers, &nservers, config.nameservers[i]);
107+      if (status_each == ARES_SUCCESS) {
108+        status = ARES_SUCCESS;
109+      }
110+    }
111+
112+    if (status == ARES_SUCCESS && nservers > 0) {
113+      goto get_conf_ok;
114+    }
115+
116+etc_resolv_conf:
117+#endif
118     fp = fopen(resolvconf_path, "r");
119     if (fp) {
120       while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
121@@ -1866,7 +1961,9 @@ static int init_by_resolv_conf(ares_channel channel)
122         ares_free(sortlist);
123       return status;
124     }
125-
126+#if OHOS_DNS_PROXY_BY_NETSYS
127+get_conf_ok:
128+#endif
129   /* If we got any name server entries, fill them in. */
130   if (servers)
131     {
132