• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "lookup.h"
22 #include <dlfcn.h>
23 
24 #if OHOS_DNS_PROXY_BY_NETSYS
25 
26 void
dns_set_addr_info_to_netsys_cache(const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo * res)27 dns_set_addr_info_to_netsys_cache(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict
28 hint, struct addrinfo *res) {
29 	void *handle = dlopen(DNS_SO_PATH, RTLD_LAZY);
30 	if (handle == NULL) {
31 		DNS_CONFIG_PRINT("dns_set_addr_info_to_netsys_cache dlopen err %s\n", dlerror());
32 		return;
33 	}
34 
35 	SetCache func = dlsym(handle, OHOS_SET_CACHE_FUNC_NAME);
36 	if (func == NULL) {
37 		DNS_CONFIG_PRINT("dns_set_addr_info_to_netsys_cache dlsym err %s\n", dlerror());
38 		dlclose(handle);
39 		return;
40 	}
41 
42 	struct param_wrapper param = {(char *) host, (char *) serv, (struct addrinfo *) hint};
43 	int ret = func(0, param, res);
44 	dlclose(handle);
45 	if (ret < 0) {
46 		DNS_CONFIG_PRINT("dns_set_addr_info_to_netsys_cache OHOS_SET_CACHE_FUNC_NAME err %d\n", ret);
47 		return;
48 	}
49 
50 	DNS_CONFIG_PRINT("set to netsys cache OK\n");
51 }
52 
dns_get_addr_info_from_netsys_cache(const char * restrict host,const char * restrict serv,const struct addrinfo * restrict hint,struct addrinfo ** restrict res)53 int dns_get_addr_info_from_netsys_cache(const char *restrict host, const char *restrict serv,
54 										const struct addrinfo *restrict hint, struct addrinfo **restrict res) {
55 	void *handle = dlopen(DNS_SO_PATH, RTLD_LAZY);
56 	if (handle == NULL) {
57 		DNS_CONFIG_PRINT("dns_get_addr_info_from_netsys_cache dlopen err %s\n", dlerror());
58 		return -1;
59 	}
60 
61 	GetCache func = dlsym(handle, OHOS_GET_CACHE_FUNC_NAME);
62 	if (func == NULL) {
63 		DNS_CONFIG_PRINT("dns_get_addr_info_from_netsys_cache dlsym err %s\n", dlerror());
64 		dlclose(handle);
65 		return -1;
66 	}
67 
68 	struct addr_info_wrapper addr_info[MAX_RESULTS] = {0};
69 	uint32_t num = 0;
70 	struct param_wrapper param = {(char *) host, (char *) serv, (struct addrinfo *) hint};
71 	int ret = func(0, param, addr_info, &num);
72 	dlclose(handle);
73 	if (ret < 0) {
74 		DNS_CONFIG_PRINT("dns_get_addr_info_from_netsys_cache OHOS_GET_CACHE_FUNC_NAME err %d\n", ret);
75 		return -1;
76 	}
77 
78 	num = MACRO_MIN(num, MACRO_MIN(MAX_RESULTS, MAXADDRS));
79 	if (num == 0) {
80 		DNS_CONFIG_PRINT("dns_get_addr_info_from_netsys_cache num is invalid err %u", num);
81 		return -1;
82 	}
83 
84 	int canon_len = (int) strlen(addr_info[0].ai_canonName);
85 	struct aibuf *out = calloc(1, num * sizeof(*out) + canon_len + 1);
86 	if (!out) {
87 		return -1;
88 	}
89 	char *outcanon = NULL;
90 	if (canon_len) {
91 		outcanon = (char *) &out[num];
92 		memcpy(outcanon, addr_info[0].ai_canonName, canon_len + 1);
93 	}
94 
95 	for (int i = 0; i < num; i++) {
96 		out[i].slot = (short) i;
97 		out[i].ai = (struct addrinfo) {
98 				.ai_flags = (int) addr_info[i].ai_flags,
99 				.ai_family = (int) addr_info[i].ai_family,
100 				.ai_socktype = (int) addr_info[i].ai_sockType,
101 				.ai_protocol = (int) addr_info[i].ai_protocol,
102 				.ai_addrlen = (socklen_t) addr_info[i].ai_addrLen,
103 				.ai_addr = (void *) &out[i].sa,
104 				.ai_canonname = outcanon,
105 		};
106 		memcpy(&out[i].sa, &addr_info[i].ai_addr, addr_info[i].ai_addrLen);
107 		if (i > 0) {
108 			out[i - 1].ai.ai_next = &out[i].ai;
109 		}
110 	}
111 
112 	out[0].ref = (short) num;
113 	*res = &out->ai;
114 
115 	DNS_CONFIG_PRINT("dns_get_addr_info_from_netsys_cache end\n");
116 	return 0;
117 }
118 
119 #endif
120