1 #include "lookup.h"
2 #include "stdio_impl.h"
3 #include <ctype.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <netinet/in.h>
8 #if OHOS_DNS_PROXY_BY_NETSYS
9 #include <dlfcn.h>
10 #endif
11
__get_resolv_conf(struct resolvconf * conf,char * search,size_t search_sz)12 int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
13 {
14 char line[256];
15 unsigned char _buf[256];
16 FILE *f, _f;
17 int nns = 0;
18
19 conf->ndots = 1;
20 conf->timeout = 5;
21 conf->attempts = 2;
22 if (search) *search = 0;
23
24 #if OHOS_DNS_PROXY_BY_NETSYS
25 void *handle = dlopen(DNS_SO_PATH, RTLD_LAZY);
26 if (handle == NULL) {
27 DNS_CONFIG_PRINT("__get_resolv_conf dlopen err %s\n", dlerror());
28 goto etc_resolv_conf;
29 }
30
31 GetConfig func = dlsym(handle, OHOS_GET_CONFIG_FUNC_NAME);
32 if (func == NULL) {
33 DNS_CONFIG_PRINT("__get_resolv_conf dlsym err %s\n", dlerror());
34 dlclose(handle);
35 goto etc_resolv_conf;
36 }
37
38 struct resolv_config config = {0};
39 int ret = func(0, &config);
40 dlclose(handle);
41 if (ret < 0) {
42 DNS_CONFIG_PRINT("__get_resolv_conf OHOS_GET_CONFIG_FUNC_NAME err %d\n", ret);
43 goto etc_resolv_conf;
44 }
45 int32_t timeout_second = config.timeout_ms / 1000;
46 #endif
47
48 #if OHOS_DNS_PROXY_BY_NETSYS
49 netsys_conf:
50 if (timeout_second > 0) {
51 if (timeout_second >= 60) {
52 conf->timeout = 60;
53 } else {
54 conf->timeout = timeout_second;
55 }
56 }
57 if (config.retry_count > 0) {
58 if (config.retry_count >= 10) {
59 conf->attempts = 10;
60 } else {
61 conf->attempts = config.retry_count;
62 }
63 }
64 for (int i = 0; i < MAX_SERVER_NUM; ++i) {
65 if (config.nameservers[i] == NULL || config.nameservers[i][0] == 0 || nns >= MAXNS) {
66 continue;
67 }
68 if (__lookup_ipliteral(conf->ns + nns, config.nameservers[i], AF_UNSPEC) > 0) {
69 nns++;
70 }
71 }
72
73 etc_resolv_conf:
74 #endif
75 f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
76 if (!f) switch (errno) {
77 case ENOENT:
78 case ENOTDIR:
79 case EACCES:
80 goto no_resolv_conf;
81 default:
82 return -1;
83 }
84
85 while (fgets(line, sizeof line, f)) {
86 char *p, *z;
87 if (!strchr(line, '\n') && !feof(f)) {
88 /* Ignore lines that get truncated rather than
89 * potentially misinterpreting them. */
90 int c;
91 do c = getc(f);
92 while (c != '\n' && c != EOF);
93 continue;
94 }
95 if (!strncmp(line, "options", 7) && isspace(line[7])) {
96 p = strstr(line, "ndots:");
97 if (p && isdigit(p[6])) {
98 p += 6;
99 unsigned long x = strtoul(p, &z, 10);
100 if (z != p) conf->ndots = x > 15 ? 15 : x;
101 }
102 p = strstr(line, "attempts:");
103 if (p && isdigit(p[9])) {
104 p += 9;
105 unsigned long x = strtoul(p, &z, 10);
106 if (z != p) conf->attempts = x > 10 ? 10 : x;
107 }
108 p = strstr(line, "timeout:");
109 if (p && (isdigit(p[8]) || p[8]=='.')) {
110 p += 8;
111 unsigned long x = strtoul(p, &z, 10);
112 if (z != p) conf->timeout = x > 60 ? 60 : x;
113 }
114 continue;
115 }
116 if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
117 if (nns >= MAXNS) continue;
118 for (p=line+11; isspace(*p); p++);
119 for (z=p; *z && !isspace(*z); z++);
120 *z=0;
121 if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
122 nns++;
123 continue;
124 }
125
126 if (!search) continue;
127 if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
128 || !isspace(line[6]))
129 continue;
130 for (p=line+7; isspace(*p); p++);
131 size_t l = strlen(p);
132 /* This can never happen anyway with chosen buffer sizes. */
133 if (l >= search_sz) continue;
134 memcpy(search, p, l+1);
135 }
136
137 __fclose_ca(f);
138
139 no_resolv_conf:
140 if (!nns) {
141 __lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
142 nns = 1;
143 }
144
145 conf->nns = nns;
146
147 return 0;
148 }
149