• 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 
load_cache_getter(void)30 static GetCache load_cache_getter(void)
31 {
32 	static GetCache cache_getter = NULL;
33 	resolve_dns_sym((void **) &cache_getter, OHOS_GET_CACHE_FUNC_NAME);
34 	return cache_getter;
35 }
36 
load_cache_setter(void)37 static SetCache load_cache_setter(void)
38 {
39 	static SetCache cache_setter = NULL;
40 	resolve_dns_sym((void **) &cache_setter, OHOS_SET_CACHE_FUNC_NAME);
41 	return cache_setter;
42 }
43 
load_result_poster(void)44 static PostDnsResult load_result_poster(void)
45 {
46 	static PostDnsResult result_poster = NULL;
47 	resolve_dns_sym((void **) &result_poster, OHOS_POST_DNS_RESULT_FUNC_NAME);
48 	return result_poster;
49 }
50 
51 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)52 dns_set_addr_info_to_netsys_cache2(const int netid, const char *restrict host, const char *restrict serv,
53 								   const struct addrinfo *restrict hint, struct addrinfo *res)
54 {
55 	SetCache func = load_cache_setter();
56 	if (!func) {
57 		DNS_CONFIG_PRINT("%s: loading %s failed", __func__, OHOS_SET_CACHE_FUNC_NAME);
58 		return;
59 	}
60 
61 	struct param_wrapper param = {(char *) host, (char *) serv, (struct addrinfo *) hint};
62 	int ret = func(netid, param, res);
63 	if (ret < 0) {
64 		GETADDRINFO_PRINT_DEBUG("dns_set_addr_info_to_netsys_cache OHOS_SET_CACHE_FUNC_NAME err %d\n", ret);
65 		return;
66 	}
67 
68 	GETADDRINFO_PRINT_DEBUG("set to netsys cache OK\n");
69 }
70 
dns_set_addr_info_to_netsys_cache(const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo * res)71 void dns_set_addr_info_to_netsys_cache(const char *restrict host, const char *restrict serv,
72 									   const struct addrinfo *restrict hint, struct addrinfo *res)
73 {
74 	dns_set_addr_info_to_netsys_cache2(0, host, serv, hint, res);
75 }
76 
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)77 int dns_get_addr_info_from_netsys_cache2(const int netid, const char *restrict host, const char *restrict serv,
78 										 const struct addrinfo *restrict hint, struct addrinfo **restrict res)
79 {
80 	GetCache func = load_cache_getter();
81 	if (!func) {
82 		DNS_CONFIG_PRINT("%s: loading %s failed", __func__, OHOS_GET_CACHE_FUNC_NAME);
83 		return -1;
84 	}
85 
86 	struct addr_info_wrapper addr_info[MAX_RESULTS] = {0};
87 	uint32_t num = 0;
88 	struct param_wrapper param = {(char *) host, (char *) serv, (struct addrinfo *) hint};
89 	int ret = func(netid, param, addr_info, &num);
90 	if (ret < 0) {
91 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache OHOS_GET_CACHE_FUNC_NAME err %d\n", ret);
92 		return -1;
93 	}
94 
95 	num = MACRO_MIN(num, MACRO_MIN(MAX_RESULTS, MAXADDRS));
96 	if (num == 0) {
97 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache num is invalid err %u", num);
98 		return -1;
99 	}
100 
101 	int canon_len = (int) strlen(addr_info[0].ai_canonName);
102 	struct aibuf *out = calloc(1, num * sizeof(*out) + canon_len + 1);
103 	if (!out) {
104 		return -1;
105 	}
106 	char *outcanon = NULL;
107 	if (canon_len) {
108 		outcanon = (char *) &out[num];
109 		memcpy(outcanon, addr_info[0].ai_canonName, canon_len + 1);
110 	}
111 
112 	for (int i = 0; i < num; i++) {
113 		out[i].slot = (short) i;
114 		out[i].ai = (struct addrinfo) {
115 				.ai_flags = (int) addr_info[i].ai_flags,
116 				.ai_family = (int) addr_info[i].ai_family,
117 				.ai_socktype = (int) addr_info[i].ai_sockType,
118 				.ai_protocol = (int) addr_info[i].ai_protocol,
119 				.ai_addrlen = (socklen_t) addr_info[i].ai_addrLen,
120 				.ai_addr = (void *) &out[i].sa,
121 				.ai_canonname = outcanon,
122 		};
123 		memcpy(&out[i].sa, &addr_info[i].ai_addr, addr_info[i].ai_addrLen);
124 		if (i > 0) {
125 			out[i - 1].ai.ai_next = &out[i].ai;
126 		}
127 	}
128 
129 	out[0].ref = (short) num;
130 	*res = &out->ai;
131 
132 	GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache end\n");
133 	return 0;
134 }
135 
dns_get_addr_info_from_netsys_cache(const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo ** restrict res)136 int dns_get_addr_info_from_netsys_cache(const char *restrict host, const char *restrict serv,
137 										const struct addrinfo *restrict hint, struct addrinfo **restrict res)
138 {
139 	return dns_get_addr_info_from_netsys_cache2(0, host, serv, hint, res);
140 }
141 
dns_post_result_to_netsys_cache(int netid,char * name,int usedtime,int queryret,struct addrinfo * res,struct queryparam * param)142 int dns_post_result_to_netsys_cache(int netid, char* name, int usedtime, int queryret,
143 									struct addrinfo *res, struct queryparam *param)
144 {
145 	PostDnsResult func = load_result_poster();
146 	if (!func) {
147 		GETADDRINFO_PRINT_DEBUG("%s: loading %s failed", __func__, OHOS_POST_DNS_RESULT_FUNC_NAME);
148 		return -1;
149 	}
150 
151 	int ret = func(netid, name, usedtime, queryret, res, param);
152 	if (ret < 0) {
153 		GETADDRINFO_PRINT_DEBUG("dns_set_result_to_netsys_cache OHOS_POST_DNS_RESULT_FUNC_NAME err %d\n", ret);
154 		return -1;
155 	}
156 
157 	GETADDRINFO_PRINT_DEBUG("dns_post_result_to_netsys_cache OK\n");
158 	return 0;
159 }
160 
dns_get_default_network(int * currentnetid)161 int dns_get_default_network(int *currentnetid)
162 {
163 	void *handle = dlopen(DNS_SO_PATH, RTLD_LAZY);
164 	if (handle == NULL) {
165 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache dlopen err %s\n", dlerror());
166 		return -1;
167 	}
168 
169 	GetDefaultNet func = dlsym(handle, OHOS_GET_DEFAULT_NET_FUNC_NAME);
170 	if (func == NULL) {
171 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache dlsym err %s\n", dlerror());
172 		dlclose(handle);
173 		return -1;
174 	}
175 
176 	int ret = func(0, currentnetid);
177 	dlclose(handle);
178 
179 	if (ret < 0) {
180 		GETADDRINFO_PRINT_DEBUG("dns_get_addr_info_from_netsys_cache OHOS_GET_DEFAULT_NET_FUNC_NAME err %d\n", ret);
181 		return -1;
182 	}
183 
184 	GETADDRINFO_PRINT_DEBUG("dns_post_result_to_netsys_cache OK %d\n", currentnetid);
185 	return 0;
186 }
187 
188 #endif
189