• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *	 http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdlib.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <netdb.h>
20 #include <string.h>
21 #include <dlfcn.h>
22 #include "lookup.h"
23 
24 #if OHOS_DNS_PROXY_BY_NETSYS
25 
26 #include "atomic.h"
27 
28 #define GETADDRINFO_PRINT_DEBUG(...)
29 #define MAX_SOCKET_ADDR_LEN sizeof(aligned_sockAddr)
30 
load_cache_getter(void)31 static GetCache load_cache_getter(void)
32 {
33 	static GetCache cache_getter = NULL;
34 	resolve_dns_sym((void **) &cache_getter, OHOS_GET_CACHE_FUNC_NAME);
35 	return cache_getter;
36 }
37 
load_cache_setter(void)38 static SetCache load_cache_setter(void)
39 {
40 	static SetCache cache_setter = NULL;
41 	resolve_dns_sym((void **) &cache_setter, OHOS_SET_CACHE_FUNC_NAME);
42 	return cache_setter;
43 }
44 
load_result_poster(void)45 static PostDnsResult load_result_poster(void)
46 {
47 	static PostDnsResult result_poster = NULL;
48 	resolve_dns_sym((void **) &result_poster, OHOS_POST_DNS_RESULT_FUNC_NAME);
49 	return result_poster;
50 }
51 
52 void
dns_set_addr_info_to_netsys_cache2(const int netid,const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo * res)53 dns_set_addr_info_to_netsys_cache2(const int netid, const char *restrict host, const char *restrict serv,
54 								   const struct addrinfo *restrict hint, struct addrinfo *res)
55 {
56 	SetCache func = load_cache_setter();
57 	if (!func) {
58 		DNS_CONFIG_PRINT("%s: loading %s failed", __func__, OHOS_SET_CACHE_FUNC_NAME);
59 		return;
60 	}
61 
62 	struct param_wrapper param = {(char *) host, (char *) serv, (struct addrinfo *) hint};
63 	int ret = func(netid, param, res);
64 	if (ret < 0) {
65 		GETADDRINFO_PRINT_DEBUG("dns_set_addr_info_to_netsys_cache OHOS_SET_CACHE_FUNC_NAME err %d\n", ret);
66 		return;
67 	}
68 
69 	GETADDRINFO_PRINT_DEBUG("set to netsys cache OK\n");
70 }
71 
IsIpv6Enable(int netid)72 static int IsIpv6Enable(int netid)
73 {
74 	int ret = 0;
75 #if OHOS_DNS_PROXY_BY_NETSYS
76     JudgeIpv6 ipv6_judger = NULL;
77 	resolve_dns_sym((void **) &ipv6_judger, OHOS_JUDGE_IPV6_FUNC_NAME);
78 	if (!ipv6_judger) {
79 		return -1;
80 	}
81 
82 	ret = ipv6_judger(netid);
83 	if (ret < 0) {
84 		return -1;
85 	}
86 #endif
87     return ret;
88 }
89 
dns_set_addr_info_to_netsys_cache(const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo * res)90 void dns_set_addr_info_to_netsys_cache(const char *restrict host, const char *restrict serv,
91 									   const struct addrinfo *restrict hint, struct addrinfo *res)
92 {
93 	dns_set_addr_info_to_netsys_cache2(0, host, serv, hint, res);
94 }
95 
dns_get_addr_info_from_netsys_cache2(const int netid,const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo ** restrict res)96 int dns_get_addr_info_from_netsys_cache2(const int netid, const char *restrict host, const char *restrict serv,
97 										 const struct addrinfo *restrict hint, struct addrinfo **restrict res)
98 {
99 	GetCache func = load_cache_getter();
100 	if (!func) {
101 		DNS_CONFIG_PRINT("%s: loading %s failed", __func__, OHOS_GET_CACHE_FUNC_NAME);
102 		return -1;
103 	}
104 
105 	struct addr_info_wrapper addr_info[MAX_RESULTS] = {0};
106 	uint32_t num = 0;
107 	struct param_wrapper param = {(char *) host, (char *) serv, (struct addrinfo *) hint};
108 	struct addrinfo hintTemp;
109 	if (hint != NULL) {
110 		hintTemp = *hint;
111         if (hint->ai_family == 0 && (IsIpv6Enable(netid) == 0)) {
112             hintTemp.ai_family = AF_INET;
113 			param.hint = &hintTemp;
114 		}
115 	}
116 	int ret = func(netid, param, addr_info, &num);
117 	if (ret < 0) {
118 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache OHOS_GET_CACHE_FUNC_NAME err %d\n", ret);
119 		return -1;
120 	}
121 
122 	num = MACRO_MIN(num, MACRO_MIN(MAX_RESULTS, MAXADDRS));
123 	if (num == 0) {
124 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache num is invalid err %u", num);
125 		return -1;
126 	}
127 
128 	int canon_len = (int) strlen(addr_info[0].ai_canonName);
129 	struct aibuf *out = calloc(1, num * sizeof(*out) + canon_len + 1);
130 	if (!out) {
131 		return -1;
132 	}
133 	char *outcanon = NULL;
134 	if (canon_len) {
135 		outcanon = (char *) &out[num];
136 		memcpy(outcanon, addr_info[0].ai_canonName, canon_len + 1);
137 	}
138 
139 	for (int i = 0; i < num; i++) {
140 		out[i].slot = (short) i;
141         if (addr_info[i].ai_addrLen > MAX_SOCKET_ADDR_LEN) {
142 #ifndef __LITEOS__
143             MUSL_LOGW("%{public}s: %{public}d: ai_addrLen illegal, len = %{public}d",
144                 __func__, __LINE__, addr_info[i].ai_addrLen);
145 #endif
146             addr_info[i].ai_addrLen = ((addr_info[i].ai_family == AF_INET)
147                 ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
148         }
149 		out[i].ai = (struct addrinfo) {
150 				.ai_flags = (int) addr_info[i].ai_flags,
151 				.ai_family = (int) addr_info[i].ai_family,
152 				.ai_socktype = (int) addr_info[i].ai_sockType,
153 				.ai_protocol = (int) addr_info[i].ai_protocol,
154 				.ai_addrlen = (socklen_t) addr_info[i].ai_addrLen,
155 				.ai_addr = (void *) &out[i].sa,
156 				.ai_canonname = outcanon,
157 		};
158 		memcpy(&out[i].sa, &addr_info[i].ai_addr, addr_info[i].ai_addrLen);
159 		if (i > 0) {
160 			out[i - 1].ai.ai_next = &out[i].ai;
161 		}
162 	}
163 
164 	out[0].ref = (short) num;
165 	*res = &out->ai;
166 
167 	GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache end\n");
168 	return 0;
169 }
170 
dns_get_addr_info_from_netsys_cache(const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo ** restrict res)171 int dns_get_addr_info_from_netsys_cache(const char *restrict host, const char *restrict serv,
172 										const struct addrinfo *restrict hint, struct addrinfo **restrict res)
173 {
174 	return dns_get_addr_info_from_netsys_cache2(0, host, serv, hint, res);
175 }
176 
dns_post_result_to_netsys_cache(int netid,char * name,int usedtime,int queryret,struct addrinfo * res,struct queryparam * param)177 int dns_post_result_to_netsys_cache(int netid, char* name, int usedtime, int queryret,
178 									struct addrinfo *res, struct queryparam *param)
179 {
180 	PostDnsResult func = load_result_poster();
181 	if (!func) {
182 		GETADDRINFO_PRINT_DEBUG("%s: loading %s failed", __func__, OHOS_POST_DNS_RESULT_FUNC_NAME);
183 		return -1;
184 	}
185 
186 	int ret = func(netid, name, usedtime, queryret, res, param);
187 	if (ret < 0) {
188 		GETADDRINFO_PRINT_DEBUG("dns_set_result_to_netsys_cache OHOS_POST_DNS_RESULT_FUNC_NAME err %d\n", ret);
189 		return -1;
190 	}
191 
192 	GETADDRINFO_PRINT_DEBUG("dns_post_result_to_netsys_cache OK\n");
193 	return 0;
194 }
195 
dns_get_default_network(int * currentnetid)196 int dns_get_default_network(int *currentnetid)
197 {
198 	void *handle = dlopen(DNS_SO_PATH, RTLD_LAZY);
199 	if (handle == NULL) {
200 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache dlopen err %s\n", dlerror());
201 		return -1;
202 	}
203 
204 	GetDefaultNet func = dlsym(handle, OHOS_GET_DEFAULT_NET_FUNC_NAME);
205 	if (func == NULL) {
206 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache dlsym err %s\n", dlerror());
207 		dlclose(handle);
208 		return -1;
209 	}
210 
211 	int ret = func(0, currentnetid);
212 	dlclose(handle);
213 
214 	if (ret < 0) {
215 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache OHOS_GET_DEFAULT_NET_FUNC_NAME err %d\n", ret);
216 		return -1;
217 	}
218 
219 	GETADDRINFO_PRINT_DEBUG("dns_post_result_to_netsys_cache OK %d\n", currentnetid);
220 	return 0;
221 }
222 
223 #endif
224