• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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