1 /*
2 * Copyright (c) 2022-2024 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 "netsys_client.h"
17
18 #include <errno.h>
19 #include <sys/socket.h>
20
21 #include "app_net_client.h"
22 #include "dns_config_client.h"
23 #include "hilog/log_c.h"
24 #include <netdb.h>
25 #include <securec.h>
26 #include <stdbool.h>
27 #include <sys/select.h>
28 #include <sys/un.h>
29 #include <unistd.h>
30 #include <time.h>
31 #include <pthread.h>
32 #include <signal.h>
33 #include <sys/time.h>
34 #include "netnative_log_wrapper.h"
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 static volatile uint8_t g_allowInternet = 1;
41 int64_t g_lastDnsQueryPollSendTime = 0;
42 static uint32_t g_curDnsStoreSize = 0;
43 static struct DnsCacheInfo g_dnsCaches[MAX_DNS_CACHE_SIZE];
44 static int64_t g_dnsReportTime[TOTAL_FAIL_CAUSE_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0};
45 static int64_t g_lastDnsErrorReportTime = 0;
46
47 pthread_spinlock_t g_dnsReportLock;
48 pthread_spinlock_t g_dnsReportTimeLock;
49
DisallowInternet(void)50 void DisallowInternet(void)
51 {
52 g_allowInternet = 0;
53 }
54
IsAllowInternet(void)55 uint8_t IsAllowInternet(void)
56 {
57 return g_allowInternet;
58 }
59
Min(uint32_t a,uint32_t b)60 static inline uint32_t Min(uint32_t a, uint32_t b)
61 {
62 return a < b ? a : b;
63 }
64
CloseSocketReturn(int sock,int ret)65 static inline int CloseSocketReturn(int sock, int ret)
66 {
67 close(sock);
68 return ret;
69 }
70
MakeDefaultDnsServer(char * server,size_t length)71 void MakeDefaultDnsServer(char *server, size_t length)
72 {
73 int ret = memset_s(server, length, 0, DEFAULT_SERVER_LENTH);
74 if (ret < 0) {
75 DNS_CONFIG_PRINT("MakeDefaultDnsServer memset_s failed");
76 return;
77 }
78
79 ret = sprintf_s(server, length, "%d.%d.%d.%d", DEFAULT_SERVER_NAME, DEFAULT_SERVER_NAME, DEFAULT_SERVER_NAME,
80 DEFAULT_SERVER_NAME);
81 if (ret != 0) {
82 DNS_CONFIG_PRINT("MakeDefaultDnsServer sprintf_s failed");
83 }
84 }
85
NonBlockConnect(int sock,struct sockaddr * addr,socklen_t addrLen)86 static bool NonBlockConnect(int sock, struct sockaddr *addr, socklen_t addrLen)
87 {
88 int ret = connect(sock, addr, addrLen);
89 if (ret >= 0) {
90 return true;
91 }
92 if (errno != EINPROGRESS) {
93 return false;
94 }
95
96 fd_set set = {0};
97 FD_ZERO(&set);
98 FD_SET(sock, &set);
99 struct timeval timeout = {
100 .tv_sec = DEFAULT_CONNECT_TIMEOUT,
101 .tv_usec = 0,
102 };
103
104 ret = select(sock + 1, NULL, &set, NULL, &timeout);
105 if (ret < 0) {
106 DNS_CONFIG_PRINT("select error: %s", strerror(errno));
107 return false;
108 } else if (ret == 0) {
109 DNS_CONFIG_PRINT("timeout!");
110 return false;
111 }
112
113 int err = 0;
114 socklen_t optLen = sizeof(err);
115 ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)(&err), &optLen);
116 if (ret < 0 || err != 0) {
117 return false;
118 }
119 return true;
120 }
121
CreateConnectionToNetSys(void)122 static int CreateConnectionToNetSys(void)
123 {
124 int32_t sockFd = socket(AF_UNIX, SOCK_STREAM, 0);
125 if (sockFd < 0) {
126 DNS_CONFIG_PRINT("socket failed %d", errno);
127 return -errno;
128 }
129 if (!MakeNonBlock(sockFd)) {
130 DNS_CONFIG_PRINT("MakeNonBlock failed");
131 return CloseSocketReturn(sockFd, -errno);
132 }
133
134 struct sockaddr_un address = {0};
135 address.sun_family = AF_UNIX;
136
137 if (strcpy_s(address.sun_path, sizeof(address.sun_path), DNS_SOCKET_PATH) != 0) {
138 DNS_CONFIG_PRINT("str copy failed ");
139 return CloseSocketReturn(sockFd, -1);
140 }
141
142 if (!NonBlockConnect(sockFd, (struct sockaddr *)&address, sizeof(address))) {
143 return CloseSocketReturn(sockFd, -errno);
144 }
145
146 return sockFd;
147 }
148
MakeKey(const char * hostName,const char * serv,const struct addrinfo * hints,char key[static MAX_KEY_LENGTH])149 static bool MakeKey(const char *hostName, const char *serv, const struct addrinfo *hints,
150 char key[static MAX_KEY_LENGTH])
151 {
152 if (serv && hints) {
153 return sprintf_s(key, MAX_KEY_LENGTH, "%s %s %d %d %d %d", hostName, serv, hints->ai_family, hints->ai_flags,
154 hints->ai_protocol, hints->ai_socktype) > 0;
155 }
156
157 if (hints) {
158 return sprintf_s(key, MAX_KEY_LENGTH, "%s %d %d %d %d", hostName, hints->ai_family, hints->ai_flags,
159 hints->ai_protocol, hints->ai_socktype) > 0;
160 }
161
162 if (serv) {
163 return sprintf_s(key, MAX_KEY_LENGTH, "%s %s", hostName, serv) > 0;
164 }
165
166 return sprintf_s(key, MAX_KEY_LENGTH, "%s", hostName) > 0;
167 }
168
NetSysGetResolvConfInternal(int sockFd,uint16_t netId,struct ResolvConfig * config)169 static int32_t NetSysGetResolvConfInternal(int sockFd, uint16_t netId, struct ResolvConfig *config)
170 {
171 struct RequestInfo info = {
172 .uid = getuid(),
173 .command = GET_CONFIG,
174 .netId = netId,
175 };
176 if (netId == 0 && GetNetForApp() > 0) {
177 info.netId = (uint32_t)GetNetForApp();
178 }
179 DNS_CONFIG_PRINT("NetSysGetResolvConfInternal begin netid: %d", info.netId);
180 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
181 HILOG_ERROR(LOG_CORE, "send failed %{public}d", errno);
182 return CloseSocketReturn(sockFd, -errno);
183 }
184
185 if (!PollRecvData(sockFd, (char *)(config), sizeof(struct ResolvConfig))) {
186 HILOG_ERROR(LOG_CORE, "receive failed %{public}d", errno);
187 return CloseSocketReturn(sockFd, -errno);
188 }
189
190 if (config->error < 0) {
191 HILOG_ERROR(LOG_CORE, "get Config error: %{public}d", config->error);
192 return CloseSocketReturn(sockFd, config->error);
193 }
194
195 DNS_CONFIG_PRINT("NetSysGetResolvConfInternal end netid: %d", info.netId);
196 return CloseSocketReturn(sockFd, 0);
197 }
198
NetSysGetResolvConfInternalExt(int sockFd,uint16_t netId,struct ResolvConfigExt * config)199 static int32_t NetSysGetResolvConfInternalExt(int sockFd, uint16_t netId, struct ResolvConfigExt *config)
200 {
201 struct RequestInfo info = {
202 .uid = getuid(),
203 .command = GET_CONFIG_EXT,
204 .netId = netId,
205 };
206 if (netId == 0 && GetNetForApp() > 0) {
207 info.netId = (uint32_t)GetNetForApp();
208 }
209 DNS_CONFIG_PRINT("NetSysGetResolvConfInternalExt begin netid: %d", info.netId);
210 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
211 HILOG_ERROR(LOG_CORE, "send failed %{public}d", errno);
212 return CloseSocketReturn(sockFd, -errno);
213 }
214
215 if (!PollRecvData(sockFd, (char *)(config), sizeof(struct ResolvConfigExt))) {
216 HILOG_ERROR(LOG_CORE, "receive failed %{public}d", errno);
217 return CloseSocketReturn(sockFd, -errno);
218 }
219
220 if (config->error < 0) {
221 HILOG_ERROR(LOG_CORE, "get Config error: %{public}d", config->error);
222 return CloseSocketReturn(sockFd, config->error);
223 }
224
225 DNS_CONFIG_PRINT("NetSysGetResolvConfInternalExt end netid: %d", info.netId);
226 return CloseSocketReturn(sockFd, 0);
227 }
228
NetSysGetResolvConf(uint16_t netId,struct ResolvConfig * config)229 int32_t NetSysGetResolvConf(uint16_t netId, struct ResolvConfig *config)
230 {
231 if (config == NULL) {
232 DNS_CONFIG_PRINT("Invalid Param");
233 return -EINVAL;
234 }
235
236 int sockFd = CreateConnectionToNetSys();
237 if (sockFd < 0) {
238 DNS_CONFIG_PRINT("NetSysGetResolvConf CreateConnectionToNetSys connect to netsys err: %d", errno);
239 return -errno;
240 }
241
242 int32_t err = NetSysGetResolvConfInternal(sockFd, netId, config);
243 if (err < 0) {
244 DNS_CONFIG_PRINT("NetSysGetResolvConf NetSysGetResolvConfInternal err: %d", errno);
245 return err;
246 }
247
248 if (strlen(config->nameservers[0]) == 0) {
249 return -1;
250 }
251 return 0;
252 }
253
NetSysGetResolvConfExt(uint16_t netId,struct ResolvConfigExt * config)254 int32_t NetSysGetResolvConfExt(uint16_t netId, struct ResolvConfigExt *config)
255 {
256 if (config == NULL) {
257 DNS_CONFIG_PRINT("NetSysGetResolvConfExt Invalid Param");
258 return -EINVAL;
259 }
260
261 int sockFd = CreateConnectionToNetSys();
262 if (sockFd < 0) {
263 DNS_CONFIG_PRINT("NetSysGetResolvConfExt CreateConnectionToNetSys connect to netsys err: %d", errno);
264 return -errno;
265 }
266
267 int32_t err = NetSysGetResolvConfInternalExt(sockFd, netId, config);
268 if (err < 0) {
269 DNS_CONFIG_PRINT("NetSysGetResolvConfExt NetSysGetResolvConfInternal err: %d", errno);
270 return err;
271 }
272
273 if (strlen(config->nameservers[0]) == 0) {
274 return -1;
275 }
276 return 0;
277 }
278
NetsysSendKeyForCache(int sockFd,struct ParamWrapper param,struct RequestInfo info)279 static int32_t NetsysSendKeyForCache(int sockFd, struct ParamWrapper param, struct RequestInfo info)
280 {
281 char key[MAX_KEY_LENGTH] = {0};
282 if (!MakeKey(param.host, param.serv, param.hint, key)) {
283 return CloseSocketReturn(sockFd, -1);
284 }
285
286 DNS_CONFIG_PRINT("NetSysSetResolvCacheInternal begin netid: %d", info.netId);
287 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
288 DNS_CONFIG_PRINT("send failed %d", errno);
289 return CloseSocketReturn(sockFd, -errno);
290 }
291
292 uint32_t nameLen = strlen(key) + 1;
293 if (!PollSendData(sockFd, (const char *)&nameLen, sizeof(nameLen))) {
294 DNS_CONFIG_PRINT("send failed %d", errno);
295 return CloseSocketReturn(sockFd, -errno);
296 }
297
298 if (!PollSendData(sockFd, key, nameLen)) {
299 DNS_CONFIG_PRINT("send failed %d", errno);
300 return CloseSocketReturn(sockFd, -errno);
301 }
302 return 0;
303 };
304
IsAbnormalAddress(uint32_t addr)305 static bool IsAbnormalAddress(uint32_t addr)
306 {
307 uint32_t address1 = 0; // 0.0.0.0
308 uint32_t address2 = 2130706433; // 127.0.0.1
309 if (addr == address1 || addr == address2) {
310 return true;
311 }
312 return false;
313 }
314
NetSysGetResolvCacheInternal(int sockFd,uint16_t netId,const struct ParamWrapper param,struct AddrInfo addrInfo[static MAX_RESULTS],uint32_t * num)315 static int32_t NetSysGetResolvCacheInternal(int sockFd, uint16_t netId, const struct ParamWrapper param,
316 struct AddrInfo addrInfo[static MAX_RESULTS], uint32_t *num)
317 {
318 struct RequestInfo info = {
319 .uid = getuid(),
320 .command = GET_CACHE,
321 .netId = netId,
322 };
323 if (netId == 0 && GetNetForApp() > 0) {
324 info.netId = (uint32_t)GetNetForApp();
325 }
326 int32_t res = NetsysSendKeyForCache(sockFd, param, info);
327 if (res < 0) {
328 return res;
329 }
330
331 if (!PollRecvData(sockFd, (char *)num, sizeof(uint32_t))) {
332 DNS_CONFIG_PRINT("read failed %d", errno);
333 return CloseSocketReturn(sockFd, -errno);
334 }
335
336 *num = Min(*num, MAX_RESULTS);
337 if (*num == 0) {
338 return CloseSocketReturn(sockFd, 0);
339 }
340
341 if (!PollRecvData(sockFd, (char *)addrInfo, sizeof(struct AddrInfo) * (*num))) {
342 DNS_CONFIG_PRINT("read failed %d", errno);
343 return CloseSocketReturn(sockFd, -errno);
344 }
345
346 uint32_t validNum = 0;
347 for (uint32_t resNum = 0; resNum < *num; resNum++) {
348 if (addrInfo[resNum].aiFamily == AF_INET) {
349 uint32_t addr = addrInfo[resNum].aiAddr.sin.sin_addr.s_addr;
350 if (IsAbnormalAddress(addr)) {
351 HILOG_ERROR(LOG_CORE,
352 "GetResolvCache get abnormal zero[%{public}d] netId[%{public}u]", (addr == 0), netId);
353 }
354 if (addr == 0) {
355 continue;
356 }
357 }
358 addrInfo[validNum] = addrInfo[resNum];
359 validNum++;
360 }
361 *num = validNum;
362
363 DNS_CONFIG_PRINT("NetSysGetResolvCacheInternal end netid: %d", info.netId);
364 return CloseSocketReturn(sockFd, 0);
365 }
366
NetSysGetResolvCache(uint16_t netId,const struct ParamWrapper param,struct AddrInfo addrInfo[static MAX_RESULTS],uint32_t * num)367 int32_t NetSysGetResolvCache(uint16_t netId, const struct ParamWrapper param,
368 struct AddrInfo addrInfo[static MAX_RESULTS], uint32_t *num)
369 {
370 char *hostName = param.host;
371 if (hostName == NULL || strlen(hostName) == 0 || num == NULL) {
372 DNS_CONFIG_PRINT("Invalid Param");
373 return -EINVAL;
374 }
375
376 int sockFd = CreateConnectionToNetSys();
377 if (sockFd < 0) {
378 DNS_CONFIG_PRINT("NetSysGetResolvCache CreateConnectionToNetSys connect to netsys err: %d", errno);
379 return sockFd;
380 }
381
382 int err = NetSysGetResolvCacheInternal(sockFd, netId, param, addrInfo, num);
383 if (err < 0) {
384 DNS_CONFIG_PRINT("NetSysGetResolvCache NetSysGetResolvCacheInternal err: %d", errno);
385 return err;
386 }
387
388 return 0;
389 }
390
FillAddrInfo(struct AddrInfo addrInfo[static MAX_RESULTS],struct addrinfo * res)391 static int32_t FillAddrInfo(struct AddrInfo addrInfo[static MAX_RESULTS], struct addrinfo *res)
392 {
393 if (memset_s(addrInfo, sizeof(struct AddrInfo) * MAX_RESULTS, 0, sizeof(struct AddrInfo) * MAX_RESULTS) != 0) {
394 return -1;
395 }
396
397 int32_t resNum = 0;
398 for (struct addrinfo *tmp = res; tmp != NULL; tmp = tmp->ai_next) {
399 addrInfo[resNum].aiFlags = tmp->ai_flags;
400 addrInfo[resNum].aiFamily = tmp->ai_family;
401 addrInfo[resNum].aiSockType = (uint32_t)(tmp->ai_socktype);
402 addrInfo[resNum].aiProtocol = tmp->ai_protocol;
403 addrInfo[resNum].aiAddrLen = tmp->ai_addrlen;
404 if (memcpy_s(&addrInfo[resNum].aiAddr, sizeof(addrInfo[resNum].aiAddr), tmp->ai_addr, tmp->ai_addrlen) != 0) {
405 DNS_CONFIG_PRINT("memcpy_s failed");
406 return -1;
407 }
408 if (tmp->ai_canonname &&
409 strcpy_s(addrInfo[resNum].aiCanonName, sizeof(addrInfo[resNum].aiCanonName), tmp->ai_canonname) != 0) {
410 DNS_CONFIG_PRINT("strcpy_s failed");
411 return -1;
412 }
413 if (addrInfo[resNum].aiFamily == AF_INET) {
414 uint32_t addr = addrInfo[resNum].aiAddr.sin.sin_addr.s_addr;
415 if (IsAbnormalAddress(addr)) {
416 HILOG_ERROR(LOG_CORE, "SetDnsCache set abnormal zero[%{public}d]", (addr == 0));
417 }
418 }
419
420 ++resNum;
421 if (resNum >= MAX_RESULTS) {
422 break;
423 }
424 }
425
426 return resNum;
427 }
428
FillQueryParam(struct queryparam * orig,struct QueryParam * dest)429 static int32_t FillQueryParam(struct queryparam *orig, struct QueryParam *dest)
430 {
431 dest->type = orig->qp_type;
432 dest->netId = orig->qp_netid;
433 dest->mark = orig->qp_mark;
434 dest->flags = orig->qp_flag;
435 dest->qHook = NULL;
436 return 0;
437 }
438
NetSysSetResolvCacheInternal(int sockFd,uint16_t netId,const struct ParamWrapper param,struct addrinfo * res)439 static int32_t NetSysSetResolvCacheInternal(int sockFd, uint16_t netId, const struct ParamWrapper param,
440 struct addrinfo *res)
441 {
442 struct RequestInfo info = {
443 .uid = getuid(),
444 .command = SET_CACHE,
445 .netId = netId,
446 };
447 if (netId == 0 && GetNetForApp() > 0) {
448 info.netId = (uint32_t)GetNetForApp();
449 }
450 int32_t result = NetsysSendKeyForCache(sockFd, param, info);
451 if (result < 0) {
452 return result;
453 }
454
455 struct AddrInfo addrInfo[MAX_RESULTS] = {};
456 int32_t resNum = FillAddrInfo(addrInfo, res);
457 if (resNum < 0) {
458 return CloseSocketReturn(sockFd, -1);
459 }
460
461 if (!PollSendData(sockFd, (char *)&resNum, sizeof(resNum))) {
462 DNS_CONFIG_PRINT("send failed %d", errno);
463 return CloseSocketReturn(sockFd, -errno);
464 }
465
466 if (resNum == 0) {
467 return CloseSocketReturn(sockFd, 0);
468 }
469
470 if (!PollSendData(sockFd, (char *)addrInfo, sizeof(struct AddrInfo) * resNum)) {
471 DNS_CONFIG_PRINT("send failed %d", errno);
472 return CloseSocketReturn(sockFd, -errno);
473 }
474
475 return CloseSocketReturn(sockFd, 0);
476 }
477
NetSysSetResolvCache(uint16_t netId,const struct ParamWrapper param,struct addrinfo * res)478 int32_t NetSysSetResolvCache(uint16_t netId, const struct ParamWrapper param, struct addrinfo *res)
479 {
480 char *hostName = param.host;
481 if (hostName == NULL || strlen(hostName) == 0 || res == NULL) {
482 DNS_CONFIG_PRINT("Invalid Param");
483 return -EINVAL;
484 }
485
486 int sockFd = CreateConnectionToNetSys();
487 if (sockFd < 0) {
488 DNS_CONFIG_PRINT("NetSysSetResolvCache CreateConnectionToNetSys connect to netsys err: %d", errno);
489 return sockFd;
490 }
491
492 int err = NetSysSetResolvCacheInternal(sockFd, netId, param, res);
493 if (err < 0) {
494 DNS_CONFIG_PRINT("NetSysSetResolvCache NetSysSetResolvCacheInternal err: %d", errno);
495 return err;
496 }
497
498 return 0;
499 }
500
NetSysIsIpv6EnableInternal(int sockFd,uint16_t netId,int * enable)501 static int32_t NetSysIsIpv6EnableInternal(int sockFd, uint16_t netId, int *enable)
502 {
503 struct RequestInfo info = {
504 .uid = getuid(),
505 .command = JUDGE_IPV6,
506 .netId = netId,
507 };
508 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
509 DNS_CONFIG_PRINT("send failed %d", errno);
510 return CloseSocketReturn(sockFd, -errno);
511 }
512
513 if (!PollRecvData(sockFd, (char *)enable, sizeof(int))) {
514 DNS_CONFIG_PRINT("read failed %d", errno);
515 return CloseSocketReturn(sockFd, -errno);
516 }
517
518 return CloseSocketReturn(sockFd, 0);
519 }
520
NetSysIsIpv6Enable(uint16_t netId)521 int NetSysIsIpv6Enable(uint16_t netId)
522 {
523 int sockFd = CreateConnectionToNetSys();
524 if (sockFd < 0) {
525 DNS_CONFIG_PRINT("NetSysIsIpv6Enable CreateConnectionToNetSys connect to netsys err: %d", errno);
526 return sockFd;
527 }
528 int enable = 0;
529 int err = NetSysIsIpv6EnableInternal(sockFd, netId, &enable);
530 if (err < 0) {
531 return 0;
532 }
533
534 return enable;
535 }
536
NetSysPostDnsResultPollSendData(int sockFd,int queryret,int32_t resNum,struct QueryParam * param,struct AddrInfo addrInfo[static MAX_RESULTS])537 static int32_t NetSysPostDnsResultPollSendData(int sockFd, int queryret, int32_t resNum, struct QueryParam *param,
538 struct AddrInfo addrInfo[static MAX_RESULTS])
539 {
540 if (!PollSendData(sockFd, (char *)&queryret, sizeof(int))) {
541 DNS_CONFIG_PRINT("send failed %d", errno);
542 return CloseSocketReturn(sockFd, -errno);
543 }
544
545 if (!PollSendData(sockFd, (char *)&resNum, sizeof(int32_t))) {
546 DNS_CONFIG_PRINT("send failed %d", errno);
547 return CloseSocketReturn(sockFd, -errno);
548 }
549
550 if (!PollSendData(sockFd, (char *)param, sizeof(struct QueryParam))) {
551 DNS_CONFIG_PRINT("send failed %d", errno);
552 return CloseSocketReturn(sockFd, -errno);
553 }
554
555 if (resNum > 0) {
556 if (!PollSendData(sockFd, (char *)addrInfo, sizeof(struct AddrInfo) * resNum)) {
557 DNS_CONFIG_PRINT("send failed %d", errno);
558 return CloseSocketReturn(sockFd, -errno);
559 }
560 }
561 return CloseSocketReturn(sockFd, 0);
562 }
563
NetSysPostDnsResultInternal(int sockFd,uint16_t netId,char * name,int usedtime,int queryret,struct addrinfo * res,struct queryparam * param)564 static int32_t NetSysPostDnsResultInternal(int sockFd, uint16_t netId, char* name, int usedtime, int queryret,
565 struct addrinfo *res, struct queryparam *param)
566 {
567 struct RequestInfo info = {
568 .uid = getuid(),
569 .command = POST_DNS_RESULT,
570 .netId = netId,
571 };
572
573 int32_t uid = (int32_t)(getuid());
574 int32_t pid = getpid();
575 uint32_t nameLen = strlen(name) + 1;
576 NETSYS_CLIENT_PRINT("NetSysPostDnsResultInternal uid %d, pid %d, netid %d pkg", uid, pid, netId);
577
578 struct AddrInfo addrInfo[MAX_RESULTS] = {};
579 struct QueryParam netparam = {};
580 int32_t resNum = 0;
581 if (queryret == 0) {
582 resNum = FillAddrInfo(addrInfo, res);
583 }
584 if (resNum < 0) {
585 return CloseSocketReturn(sockFd, -1);
586 }
587 FillQueryParam(param, &netparam);
588
589 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
590 DNS_CONFIG_PRINT("send failed %d", errno);
591 return CloseSocketReturn(sockFd, -errno);
592 }
593
594 if (!PollSendData(sockFd, (char *)&uid, sizeof(int32_t))) {
595 DNS_CONFIG_PRINT("send failed %d", errno);
596 return CloseSocketReturn(sockFd, -errno);
597 }
598
599 if (!PollSendData(sockFd, (char *)&pid, sizeof(int32_t))) {
600 DNS_CONFIG_PRINT("send failed %d", errno);
601 return CloseSocketReturn(sockFd, -errno);
602 }
603
604 if (!PollSendData(sockFd, (char *)&nameLen, sizeof(uint32_t))) {
605 DNS_CONFIG_PRINT("send failed %d", errno);
606 return CloseSocketReturn(sockFd, -errno);
607 }
608
609 if (!PollSendData(sockFd, name, (sizeof(char) * nameLen))) {
610 DNS_CONFIG_PRINT("send failed %d", errno);
611 return CloseSocketReturn(sockFd, -errno);
612 }
613
614 if (!PollSendData(sockFd, (char *)&usedtime, sizeof(int))) {
615 DNS_CONFIG_PRINT("send failed %d", errno);
616 return CloseSocketReturn(sockFd, -errno);
617 }
618
619 return NetSysPostDnsResultPollSendData(sockFd, queryret, resNum, &netparam, addrInfo);
620 }
621
NetSysPostDnsResult(int netid,char * name,int usedtime,int queryret,struct addrinfo * res,struct queryparam * param)622 int32_t NetSysPostDnsResult(int netid, char* name, int usedtime, int queryret,
623 struct addrinfo *res, struct queryparam *param)
624 {
625 if (name == NULL) {
626 return -1;
627 }
628
629 int sockFd = CreateConnectionToNetSys();
630 if (sockFd < 0) {
631 DNS_CONFIG_PRINT("NetSysPostDnsResult CreateConnectionToNetSys connect to netsys err: %d", errno);
632 return sockFd;
633 }
634 int err = NetSysPostDnsResultInternal(sockFd, netid, name, usedtime, queryret, res, param);
635 if (err < 0) {
636 return -1;
637 }
638
639 return 0;
640 }
641
NetSysGetDefaultNetworkInternal(int sockFd,uint16_t netId,int32_t * currentNetId)642 static int32_t NetSysGetDefaultNetworkInternal(int sockFd, uint16_t netId, int32_t *currentNetId)
643 {
644 struct RequestInfo info = {
645 .uid = getuid(),
646 .command = GET_DEFAULT_NETWORK,
647 .netId = netId,
648 };
649 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
650 DNS_CONFIG_PRINT("send failed %d", errno);
651 return CloseSocketReturn(sockFd, -errno);
652 }
653
654 if (!PollRecvData(sockFd, (char *)currentNetId, sizeof(int))) {
655 DNS_CONFIG_PRINT("read failed %d", errno);
656 return CloseSocketReturn(sockFd, -errno);
657 }
658 DNS_CONFIG_PRINT("currentNetId %d", *currentNetId);
659 return CloseSocketReturn(sockFd, 0);
660 }
661
NetSysGetDefaultNetwork(uint16_t netId,int32_t * currentNetId)662 int32_t NetSysGetDefaultNetwork(uint16_t netId, int32_t* currentNetId)
663 {
664 int sockFd = CreateConnectionToNetSys();
665 int err = NetSysGetDefaultNetworkInternal(sockFd, netId, currentNetId);
666 if (err < 0) {
667 return -1;
668 }
669
670 return 0;
671 }
672
NetSysBindSocketInternal(int sockFd,uint16_t netId,int32_t fd)673 static int32_t NetSysBindSocketInternal(int sockFd, uint16_t netId, int32_t fd)
674 {
675 struct RequestInfo info = {
676 .uid = getuid(),
677 .command = BIND_SOCKET,
678 .netId = netId,
679 };
680 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
681 DNS_CONFIG_PRINT("send failed %d", errno);
682 return CloseSocketReturn(sockFd, -errno);
683 }
684
685 if (!PollSendData(sockFd, (const char *)(&fd), sizeof(int32_t))) {
686 DNS_CONFIG_PRINT("send failed %d", errno);
687 return CloseSocketReturn(sockFd, -errno);
688 }
689
690 return CloseSocketReturn(sockFd, 0);
691 }
692
NetSysBindSocket(int32_t fd,uint32_t netId)693 int32_t NetSysBindSocket(int32_t fd, uint32_t netId)
694 {
695 int sockFd = CreateConnectionToNetSys();
696 DNS_CONFIG_PRINT("NetSysBindSocket %d", fd);
697 int err = NetSysBindSocketInternal(sockFd, netId, fd);
698 if (err < 0) {
699 return -1;
700 }
701
702 return 0;
703 }
704
FillFamilyQueryInfo(struct FamilyQueryInfoExt * extInfo,struct FamilyQueryInfo * info)705 static void FillFamilyQueryInfo(struct FamilyQueryInfoExt *extInfo, struct FamilyQueryInfo *info)
706 {
707 extInfo->retCode = info->retCode;
708 extInfo->isNoAnswer = info->isNoAnswer;
709 extInfo->cname = info->cname;
710 if (info->serverAddr && memcpy_s(extInfo->serverAddr, sizeof(extInfo->serverAddr),
711 info->serverAddr, strlen(info->serverAddr) + 1) != 0) {
712 HILOG_ERROR(LOG_CORE, "copy server error");
713 }
714 }
715
FillDnsProcessInfo(char * srcAddr,struct DnsProcessInfo * processInfo,struct DnsProcessInfoExt * processInfoExt)716 static void FillDnsProcessInfo(char *srcAddr, struct DnsProcessInfo *processInfo,
717 struct DnsProcessInfoExt *processInfoExt)
718 {
719 processInfoExt->queryTime = processInfo->queryTime;
720 processInfoExt->retCode = processInfo->retCode;
721 processInfoExt->firstQueryEnd2AppDuration = processInfo->firstQueryEnd2AppDuration;
722 processInfoExt->firstQueryEndDuration = processInfo->firstQueryEndDuration;
723 processInfoExt->firstReturnType = processInfo->firstReturnType;
724 processInfoExt->isFromCache = processInfo->isFromCache;
725 processInfoExt->sourceFrom = processInfo->sourceFrom;
726 if (memcpy_s(processInfoExt->hostname, sizeof(processInfoExt->hostname),
727 processInfo->hostname, strlen(processInfo->hostname) + 1) != 0) {
728 HILOG_ERROR(LOG_CORE, "copy hostname error");
729 }
730 if (srcAddr) {
731 if (memcpy_s(processInfoExt->srcAddr, sizeof(processInfoExt->srcAddr),
732 srcAddr, strlen(srcAddr) + 1) != 0) {
733 HILOG_ERROR(LOG_CORE, "copy srcAddr error");
734 }
735 }
736 FillFamilyQueryInfo(&(processInfoExt->ipv4QueryInfo), &(processInfo->ipv4QueryInfo));
737 FillFamilyQueryInfo(&(processInfoExt->ipv6QueryInfo), &(processInfo->ipv6QueryInfo));
738 }
739
GetDnsCacheSize(void)740 static int32_t GetDnsCacheSize(void)
741 {
742 uint32_t size = 0;
743 for (uint32_t i = 0; i < g_curDnsStoreSize; i++) {
744 uint8_t addrSize = g_dnsCaches[i].addrSize;
745 size += (sizeof(uint8_t) + sizeof(struct DnsProcessInfoExt) + addrSize * sizeof(struct AddrInfo));
746 }
747 return size;
748 }
749
NetSysPostDnsQueryForOne(int sockFd,struct DnsCacheInfo dnsInfo)750 static int32_t NetSysPostDnsQueryForOne(int sockFd, struct DnsCacheInfo dnsInfo)
751 {
752 uint8_t addrSize = dnsInfo.addrSize;
753 if (!PollSendData(sockFd, (char *)&addrSize, sizeof(uint8_t))) {
754 return -errno;
755 }
756
757 if (!PollSendData(sockFd, (char *)&dnsInfo.dnsProcessInfo, sizeof(struct DnsProcessInfoExt))) {
758 return -errno;
759 }
760
761 if (addrSize > 0) {
762 if (!PollSendData(sockFd, (char *)dnsInfo.addrInfo, sizeof(struct AddrInfo) * addrSize)) {
763 return -errno;
764 }
765 }
766 return 0;
767 }
768
NetSysPostDnsQueryResultInternal(void)769 static int32_t NetSysPostDnsQueryResultInternal(void)
770 {
771 int sockFd = CreateConnectionToNetSys();
772 if (sockFd < 0) {
773 return sockFd;
774 }
775 int32_t uid = (int32_t)(getuid());
776 int32_t pid = getpid();
777 struct RequestInfo info = {
778 .uid = uid,
779 .command = POST_DNS_QUERY_RESULT,
780 .netId = 0,
781 };
782 uint32_t allDnsCacheSize = GetDnsCacheSize();
783 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
784 return CloseSocketReturn(sockFd, -errno);
785 }
786
787 if (!PollSendData(sockFd, (char *)&uid, sizeof(int32_t))) {
788 return CloseSocketReturn(sockFd, -errno);
789 }
790
791 if (!PollSendData(sockFd, (char *)&pid, sizeof(int32_t))) {
792 return CloseSocketReturn(sockFd, -errno);
793 }
794 if (!PollSendData(sockFd, (char *)&g_curDnsStoreSize, sizeof(int32_t))) {
795 return CloseSocketReturn(sockFd, -errno);
796 }
797 if (!PollSendData(sockFd, (char *)&allDnsCacheSize, sizeof(int32_t))) {
798 return CloseSocketReturn(sockFd, -errno);
799 }
800 for (uint32_t i = 0; i < g_curDnsStoreSize; i++) {
801 int32_t ret = NetSysPostDnsQueryForOne(sockFd, g_dnsCaches[i]);
802 if (ret < 0) {
803 return CloseSocketReturn(sockFd, ret);
804 }
805 }
806 CloseSocketReturn(sockFd, 0);
807 pthread_spin_lock(&g_dnsReportLock);
808 memset_s(&g_dnsCaches, sizeof(struct DnsCacheInfo) * MAX_DNS_CACHE_SIZE, 0,
809 sizeof(struct DnsCacheInfo) * MAX_DNS_CACHE_SIZE);
810 g_curDnsStoreSize = 0;
811 pthread_spin_unlock(&g_dnsReportLock);
812 return 0;
813 }
814
addr_to_string(const AlignedSockAddr * addr,char * buf,size_t len)815 char *addr_to_string(const AlignedSockAddr *addr, char *buf, size_t len)
816 {
817 switch (addr->sa.sa_family) {
818 case AF_INET:
819 if (inet_ntop(AF_INET, &addr->sin.sin_addr, buf, len) == NULL) {
820 return NULL;
821 }
822 break;
823 case AF_INET6:
824 if (inet_ntop(AF_INET6, &addr->sin6.sin6_addr, buf, len) == NULL) {
825 return NULL;
826 }
827 break;
828 default:
829 return NULL;
830 }
831 return buf;
832 }
833
IsSystemUid(void)834 bool IsSystemUid(void)
835 {
836 int32_t uid = (int32_t)(getuid());
837 if (uid == UID_PUSH || uid == UID_ACCOUNT) {
838 return false;
839 }
840 return uid < MIN_APP_UID;
841 }
842
IsLoopbackAddr(struct AddrInfo addrInfo[static MAX_RESULTS],int32_t addrSize)843 bool IsLoopbackAddr(struct AddrInfo addrInfo[static MAX_RESULTS], int32_t addrSize)
844 {
845 if (addrSize == 0) {
846 return false;
847 }
848 struct AddrInfo firstAddr = addrInfo[0];
849 char addrBuf[INET6_ADDRSTRLEN];
850 if (addr_to_string(&firstAddr.aiAddr, addrBuf, sizeof(addrBuf)) == NULL) {
851 return false;
852 }
853 if (!strcmp(addrBuf, LOOP_BACK_ADDR1) || !strcmp(addrBuf, LOOP_BACK_ADDR2)) {
854 return true;
855 }
856 return false;
857 }
858
IsAllCname(struct DnsProcessInfoExt * dnsProcessInfo)859 bool IsAllCname(struct DnsProcessInfoExt *dnsProcessInfo)
860 {
861 if (dnsProcessInfo->isFromCache) {
862 return false;
863 }
864 return dnsProcessInfo->ipv4QueryInfo.cname && dnsProcessInfo->ipv6QueryInfo.cname;
865 }
866
IsAllNoAnswer(struct DnsProcessInfoExt * dnsProcessInfo)867 bool IsAllNoAnswer(struct DnsProcessInfoExt *dnsProcessInfo)
868 {
869 if (dnsProcessInfo->isFromCache || dnsProcessInfo->retCode != 0) {
870 return false;
871 }
872 return dnsProcessInfo->ipv4QueryInfo.isNoAnswer && dnsProcessInfo->ipv6QueryInfo.isNoAnswer;
873 }
874
IsFailCauseAllowedReport(int failcause)875 bool IsFailCauseAllowedReport(int failcause)
876 {
877 if (failcause <= FAIL_CAUSE_NONE) {
878 return false;
879 }
880 int index = failcause - 1;
881 int64_t now = (int64_t)(time(NULL));
882 return now - g_dnsReportTime[index] > FAIL_CAUSE_REPORT_INTERVAL;
883 }
884
GetQueryFailCause(struct DnsProcessInfoExt * dnsProcessInfo,struct AddrInfo addrInfo[static MAX_RESULTS],int32_t addrSize)885 int32_t GetQueryFailCause(struct DnsProcessInfoExt *dnsProcessInfo,
886 struct AddrInfo addrInfo[static MAX_RESULTS], int32_t addrSize)
887 {
888 if (dnsProcessInfo == NULL) {
889 return FAIL_CAUSE_NONE;
890 }
891 if (dnsProcessInfo->retCode != 0
892 && IsFailCauseAllowedReport(FAIL_CAUSE_QUERY_FAIL)) {
893 return FAIL_CAUSE_QUERY_FAIL;
894 }
895 if (dnsProcessInfo->firstQueryEndDuration > FIRST_RETURN_SLOW_THRESHOLD
896 && IsFailCauseAllowedReport(FAIL_CAUSE_FIRST_RETURN_SLOW)) {
897 return FAIL_CAUSE_FIRST_RETURN_SLOW;
898 }
899 if (dnsProcessInfo->firstQueryEnd2AppDuration > QUERY_CALLBACK_RETURN_SLOW_THRESHOLD
900 && IsFailCauseAllowedReport(FAIL_CAUSE_CALLBACK_RETURN_SLOW)) {
901 return FAIL_CAUSE_CALLBACK_RETURN_SLOW;
902 }
903 if (IsLoopbackAddr(addrInfo, addrSize)
904 && IsFailCauseAllowedReport(FAIL_CAUSE_RETURN_LOOPBACK_ADDR)) {
905 return FAIL_CAUSE_RETURN_LOOPBACK_ADDR;
906 }
907 if (IsAllCname(dnsProcessInfo)
908 && IsFailCauseAllowedReport(FAIL_CAUSE_RETURN_CNAME)) {
909 return FAIL_CAUSE_RETURN_CNAME;
910 }
911 if (IsAllNoAnswer(dnsProcessInfo)
912 && IsFailCauseAllowedReport(FAIL_CAUSE_RETURN_NO_ANSWER)) {
913 return FAIL_CAUSE_RETURN_NO_ANSWER;
914 }
915 return FAIL_CAUSE_NONE;
916 }
917
NetsysPostDnsAbnormal(int32_t failcause,struct DnsCacheInfo dnsInfo)918 int32_t NetsysPostDnsAbnormal(int32_t failcause, struct DnsCacheInfo dnsInfo)
919 {
920 int sockFd = CreateConnectionToNetSys();
921 if (sockFd < 0) {
922 return sockFd;
923 }
924 int32_t uid = (int32_t)(getuid());
925 int32_t pid = getpid();
926 struct RequestInfo info = {
927 .uid = uid,
928 .command = POST_DNS_ABNORMAL_RESULT,
929 .netId = 0,
930 };
931 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) {
932 return CloseSocketReturn(sockFd, -errno);
933 }
934 if (!PollSendData(sockFd, (char *)&uid, sizeof(int32_t))) {
935 return CloseSocketReturn(sockFd, -errno);
936 }
937 if (!PollSendData(sockFd, (char *)&pid, sizeof(int32_t))) {
938 return CloseSocketReturn(sockFd, -errno);
939 }
940 if (!PollSendData(sockFd, (char *)&failcause, sizeof(int32_t))) {
941 return CloseSocketReturn(sockFd, -errno);
942 }
943 int32_t ret = NetSysPostDnsQueryForOne(sockFd, dnsInfo);
944 return CloseSocketReturn(sockFd, ret);
945 }
946
HandleQueryAbnormalReport(struct DnsProcessInfoExt dnsProcessInfo,struct AddrInfo addrInfo[static MAX_RESULTS],int32_t addrSize)947 void HandleQueryAbnormalReport(struct DnsProcessInfoExt dnsProcessInfo,
948 struct AddrInfo addrInfo[static MAX_RESULTS], int32_t addrSize)
949 {
950 if (IsSystemUid()) {
951 return;
952 }
953 pthread_spin_lock(&g_dnsReportTimeLock);
954 int64_t timeNow = (int64_t)(time(NULL));
955 if (timeNow - g_lastDnsErrorReportTime < MIN_REPORT_INTERVAL) {
956 pthread_spin_unlock(&g_dnsReportTimeLock);
957 return;
958 }
959 int32_t failcause = GetQueryFailCause(&dnsProcessInfo, addrInfo, addrSize);
960 if (failcause > FAIL_CAUSE_NONE) {
961 g_dnsReportTime[failcause - 1] = timeNow;
962 g_lastDnsErrorReportTime = timeNow;
963 pthread_spin_unlock(&g_dnsReportTimeLock);
964 struct DnsCacheInfo dnsInfo;
965 dnsInfo.addrSize = addrSize;
966 dnsInfo.dnsProcessInfo = dnsProcessInfo;
967 if (memcpy_s(dnsInfo.addrInfo, sizeof(struct AddrInfo) * MAX_RESULTS,
968 addrInfo, sizeof(struct AddrInfo) * MAX_RESULTS) != 0) {
969 return;
970 }
971 NetsysPostDnsAbnormal(failcause, dnsInfo);
972 } else {
973 pthread_spin_unlock(&g_dnsReportTimeLock);
974 }
975 }
976
NetSysPostDnsQueryResult(int netid,struct addrinfo * addr,char * srcAddr,struct DnsProcessInfo * processInfo)977 int32_t NetSysPostDnsQueryResult(int netid, struct addrinfo *addr, char *srcAddr,
978 struct DnsProcessInfo *processInfo)
979 {
980 if (processInfo == NULL) {
981 return -1;
982 }
983 if (processInfo->hostname == NULL) {
984 return -1;
985 }
986 struct AddrInfo addrInfo[MAX_RESULTS] = {};
987 int32_t resNum = 0;
988 if (processInfo->retCode == 0) {
989 resNum = FillAddrInfo(addrInfo, addr);
990 }
991 if (resNum < 0) {
992 return -1;
993 }
994 struct DnsProcessInfoExt dnsProcessInfo;
995 FillDnsProcessInfo(srcAddr, processInfo, &dnsProcessInfo);
996 HandleQueryAbnormalReport(dnsProcessInfo, addrInfo, resNum);
997 pthread_spin_lock(&g_dnsReportLock);
998 if (g_curDnsStoreSize >= MAX_DNS_CACHE_SIZE) {
999 pthread_spin_unlock(&g_dnsReportLock);
1000 return -1;
1001 }
1002 if (memcpy_s(g_dnsCaches[g_curDnsStoreSize].addrInfo, sizeof(struct AddrInfo) * MAX_RESULTS,
1003 addrInfo, sizeof(struct AddrInfo) * MAX_RESULTS) != 0) {
1004 pthread_spin_unlock(&g_dnsReportLock);
1005 return -1;
1006 }
1007 g_dnsCaches[g_curDnsStoreSize].addrSize = (uint8_t)resNum;
1008 g_dnsCaches[g_curDnsStoreSize].dnsProcessInfo = dnsProcessInfo;
1009 g_curDnsStoreSize++;
1010 int64_t timeNow = (int64_t)(time(NULL));
1011 if (g_lastDnsQueryPollSendTime == 0) {
1012 g_lastDnsQueryPollSendTime = timeNow;
1013 pthread_spin_unlock(&g_dnsReportLock);
1014 return 0;
1015 }
1016 if (timeNow - g_lastDnsQueryPollSendTime < MIN_QUERY_REPORT_INTERVAL) {
1017 pthread_spin_unlock(&g_dnsReportLock);
1018 return 0;
1019 }
1020 g_lastDnsQueryPollSendTime = timeNow;
1021 pthread_spin_unlock(&g_dnsReportLock);
1022 NetSysPostDnsQueryResultInternal();
1023 return 0;
1024 }
1025
1026 #ifdef __cplusplus
1027 }
1028 #endif
1029