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 31#undef LOG_TAG 32#ifndef NETMGRNATIVE_LOG_TAG 33#define LOG_TAG "NetsysNativeService" 34#else 35#define LOG_TAG NETMGRNATIVE_LOG_TAG 36#endif 37 38#ifdef __cplusplus 39extern "C" { 40#endif 41 42static volatile uint8_t g_allowInternet = 1; 43 44void DisallowInternet(void) 45{ 46 g_allowInternet = 0; 47} 48 49uint8_t IsAllowInternet(void) 50{ 51 return g_allowInternet; 52} 53 54static inline uint32_t Min(uint32_t a, uint32_t b) 55{ 56 return a < b ? a : b; 57} 58 59static inline int CloseSocketReturn(int sock, int ret) 60{ 61 close(sock); 62 return ret; 63} 64 65void MakeDefaultDnsServer(char *server, size_t length) 66{ 67 int ret = memset_s(server, length, 0, DEFAULT_SERVER_LENTH); 68 if (ret < 0) { 69 DNS_CONFIG_PRINT("MakeDefaultDnsServer memset_s failed"); 70 return; 71 } 72 73 ret = sprintf_s(server, length, "%d.%d.%d.%d", DEFAULT_SERVER_NAME, DEFAULT_SERVER_NAME, DEFAULT_SERVER_NAME, 74 DEFAULT_SERVER_NAME); 75 if (ret != 0) { 76 DNS_CONFIG_PRINT("MakeDefaultDnsServer sprintf_s failed"); 77 } 78} 79 80static bool NonBlockConnect(int sock, struct sockaddr *addr, socklen_t addrLen) 81{ 82 int ret = connect(sock, addr, addrLen); 83 if (ret >= 0) { 84 return true; 85 } 86 if (errno != EINPROGRESS) { 87 return false; 88 } 89 90 fd_set set = {0}; 91 FD_ZERO(&set); 92 FD_SET(sock, &set); 93 struct timeval timeout = { 94 .tv_sec = DEFAULT_CONNECT_TIMEOUT, 95 .tv_usec = 0, 96 }; 97 98 ret = select(sock + 1, NULL, &set, NULL, &timeout); 99 if (ret < 0) { 100 DNS_CONFIG_PRINT("select error: %s", strerror(errno)); 101 return false; 102 } else if (ret == 0) { 103 DNS_CONFIG_PRINT("timeout!"); 104 return false; 105 } 106 107 int err = 0; 108 socklen_t optLen = sizeof(err); 109 ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)(&err), &optLen); 110 if (ret < 0 || err != 0) { 111 return false; 112 } 113 return true; 114} 115 116static int CreateConnectionToNetSys(void) 117{ 118 int32_t sockFd = socket(AF_UNIX, SOCK_STREAM, 0); 119 if (sockFd < 0) { 120 DNS_CONFIG_PRINT("socket failed %d", errno); 121 return -errno; 122 } 123 if (!MakeNonBlock(sockFd)) { 124 DNS_CONFIG_PRINT("MakeNonBlock failed"); 125 return CloseSocketReturn(sockFd, -errno); 126 } 127 128 struct sockaddr_un address = {0}; 129 address.sun_family = AF_UNIX; 130 131 if (strcpy_s(address.sun_path, sizeof(address.sun_path), DNS_SOCKET_PATH) != 0) { 132 DNS_CONFIG_PRINT("str copy failed "); 133 return CloseSocketReturn(sockFd, -1); 134 } 135 136 if (!NonBlockConnect(sockFd, (struct sockaddr *)&address, sizeof(address))) { 137 return CloseSocketReturn(sockFd, -errno); 138 } 139 140 return sockFd; 141} 142 143static bool MakeKey(const char *hostName, const char *serv, const struct addrinfo *hints, 144 char key[static MAX_KEY_LENGTH]) 145{ 146 if (serv && hints) { 147 return sprintf_s(key, MAX_KEY_LENGTH, "%s %s %d %d %d %d", hostName, serv, hints->ai_family, hints->ai_flags, 148 hints->ai_protocol, hints->ai_socktype) > 0; 149 } 150 151 if (hints) { 152 return sprintf_s(key, MAX_KEY_LENGTH, "%s %d %d %d %d", hostName, hints->ai_family, hints->ai_flags, 153 hints->ai_protocol, hints->ai_socktype) > 0; 154 } 155 156 if (serv) { 157 return sprintf_s(key, MAX_KEY_LENGTH, "%s %s", hostName, serv) > 0; 158 } 159 160 return sprintf_s(key, MAX_KEY_LENGTH, "%s", hostName) > 0; 161} 162 163static int32_t NetSysGetResolvConfInternal(int sockFd, uint16_t netId, struct ResolvConfig *config) 164{ 165 struct RequestInfo info = { 166 .uid = getuid(), 167 .command = GET_CONFIG, 168 .netId = netId, 169 }; 170 if (netId == 0 && GetNetForApp() > 0) { 171 info.netId = (uint32_t)GetNetForApp(); 172 } 173 DNS_CONFIG_PRINT("NetSysGetResolvConfInternal begin netid: %d", info.netId); 174 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) { 175 HILOG_ERROR(LOG_CORE, "send failed %{public}d", errno); 176 return CloseSocketReturn(sockFd, -errno); 177 } 178 179 if (!PollRecvData(sockFd, (char *)(config), sizeof(struct ResolvConfig))) { 180 HILOG_ERROR(LOG_CORE, "receive failed %{public}d", errno); 181 return CloseSocketReturn(sockFd, -errno); 182 } 183 184 if (config->error < 0) { 185 HILOG_ERROR(LOG_CORE, "get Config error: %{public}d", config->error); 186 return CloseSocketReturn(sockFd, config->error); 187 } 188 189 DNS_CONFIG_PRINT("NetSysGetResolvConfInternal end netid: %d", info.netId); 190 return CloseSocketReturn(sockFd, 0); 191} 192 193int32_t NetSysGetResolvConf(uint16_t netId, struct ResolvConfig *config) 194{ 195 if (config == NULL) { 196 DNS_CONFIG_PRINT("Invalid Param"); 197 return -EINVAL; 198 } 199 200 int sockFd = CreateConnectionToNetSys(); 201 if (sockFd < 0) { 202 DNS_CONFIG_PRINT("NetSysGetResolvConf CreateConnectionToNetSys connect to netsys err: %d", errno); 203 return -errno; 204 } 205 206 int32_t err = NetSysGetResolvConfInternal(sockFd, netId, config); 207 if (err < 0) { 208 DNS_CONFIG_PRINT("NetSysGetResolvConf NetSysGetResolvConfInternal err: %d", errno); 209 return err; 210 } 211 212 if (strlen(config->nameservers[0]) == 0) { 213 return -1; 214 } 215 return 0; 216} 217 218static int32_t NetsysSendKeyForCache(int sockFd, struct ParamWrapper param, struct RequestInfo info) 219{ 220 char key[MAX_KEY_LENGTH] = {0}; 221 if (!MakeKey(param.host, param.serv, param.hint, key)) { 222 return CloseSocketReturn(sockFd, -1); 223 } 224 225 DNS_CONFIG_PRINT("NetSysSetResolvCacheInternal begin netid: %d", info.netId); 226 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) { 227 DNS_CONFIG_PRINT("send failed %d", errno); 228 return CloseSocketReturn(sockFd, -errno); 229 } 230 231 uint32_t nameLen = strlen(key) + 1; 232 if (!PollSendData(sockFd, (const char *)&nameLen, sizeof(nameLen))) { 233 DNS_CONFIG_PRINT("send failed %d", errno); 234 return CloseSocketReturn(sockFd, -errno); 235 } 236 237 if (!PollSendData(sockFd, key, nameLen)) { 238 DNS_CONFIG_PRINT("send failed %d", errno); 239 return CloseSocketReturn(sockFd, -errno); 240 } 241 return 0; 242}; 243 244static int32_t NetSysGetResolvCacheInternal(int sockFd, uint16_t netId, const struct ParamWrapper param, 245 struct AddrInfo addrInfo[static MAX_RESULTS], uint32_t *num) 246{ 247 struct RequestInfo info = { 248 .uid = getuid(), 249 .command = GET_CACHE, 250 .netId = netId, 251 }; 252 if (netId == 0 && GetNetForApp() > 0) { 253 info.netId = (uint32_t)GetNetForApp(); 254 } 255 int32_t res = NetsysSendKeyForCache(sockFd, param, info); 256 if (res < 0) { 257 return res; 258 } 259 260 if (!PollRecvData(sockFd, (char *)num, sizeof(uint32_t))) { 261 DNS_CONFIG_PRINT("read failed %d", errno); 262 return CloseSocketReturn(sockFd, -errno); 263 } 264 265 *num = Min(*num, MAX_RESULTS); 266 if (*num == 0) { 267 return CloseSocketReturn(sockFd, 0); 268 } 269 270 if (!PollRecvData(sockFd, (char *)addrInfo, sizeof(struct AddrInfo) * (*num))) { 271 DNS_CONFIG_PRINT("read failed %d", errno); 272 return CloseSocketReturn(sockFd, -errno); 273 } 274 275 DNS_CONFIG_PRINT("NetSysGetResolvCacheInternal end netid: %d", info.netId); 276 return CloseSocketReturn(sockFd, 0); 277} 278 279int32_t NetSysGetResolvCache(uint16_t netId, const struct ParamWrapper param, 280 struct AddrInfo addrInfo[static MAX_RESULTS], uint32_t *num) 281{ 282 char *hostName = param.host; 283 if (hostName == NULL || strlen(hostName) == 0 || num == NULL) { 284 DNS_CONFIG_PRINT("Invalid Param"); 285 return -EINVAL; 286 } 287 288 int sockFd = CreateConnectionToNetSys(); 289 if (sockFd < 0) { 290 DNS_CONFIG_PRINT("NetSysGetResolvCache CreateConnectionToNetSys connect to netsys err: %d", errno); 291 return sockFd; 292 } 293 294 int err = NetSysGetResolvCacheInternal(sockFd, netId, param, addrInfo, num); 295 if (err < 0) { 296 DNS_CONFIG_PRINT("NetSysGetResolvCache NetSysGetResolvCacheInternal err: %d", errno); 297 return err; 298 } 299 300 return 0; 301} 302 303static int32_t FillAddrInfo(struct AddrInfo addrInfo[static MAX_RESULTS], struct addrinfo *res) 304{ 305 if (memset_s(addrInfo, sizeof(struct AddrInfo) * MAX_RESULTS, 0, sizeof(struct AddrInfo) * MAX_RESULTS) != 0) { 306 return -1; 307 } 308 309 int32_t resNum = 0; 310 for (struct addrinfo *tmp = res; tmp != NULL; tmp = tmp->ai_next) { 311 addrInfo[resNum].aiFlags = tmp->ai_flags; 312 addrInfo[resNum].aiFamily = tmp->ai_family; 313 addrInfo[resNum].aiSockType = (uint32_t)(tmp->ai_socktype); 314 addrInfo[resNum].aiProtocol = tmp->ai_protocol; 315 addrInfo[resNum].aiAddrLen = tmp->ai_addrlen; 316 if (memcpy_s(&addrInfo[resNum].aiAddr, sizeof(addrInfo[resNum].aiAddr), tmp->ai_addr, tmp->ai_addrlen) != 0) { 317 DNS_CONFIG_PRINT("memcpy_s failed"); 318 return -1; 319 } 320 if (strcpy_s(addrInfo[resNum].aiCanonName, sizeof(addrInfo[resNum].aiCanonName), tmp->ai_canonname) != 0) { 321 DNS_CONFIG_PRINT("strcpy_s failed"); 322 return -1; 323 } 324 325 ++resNum; 326 if (resNum >= MAX_RESULTS) { 327 break; 328 } 329 } 330 331 return resNum; 332} 333 334static int32_t FillQueryParam(struct queryparam *orig, struct QueryParam *dest) 335{ 336 dest->type = orig->qp_type; 337 dest->netId = orig->qp_netid; 338 dest->mark = orig->qp_mark; 339 dest->flags = orig->qp_flag; 340 dest->qHook = NULL; 341 return 0; 342} 343 344static int32_t NetSysSetResolvCacheInternal(int sockFd, uint16_t netId, const struct ParamWrapper param, 345 struct addrinfo *res) 346{ 347 struct RequestInfo info = { 348 .uid = getuid(), 349 .command = SET_CACHE, 350 .netId = netId, 351 }; 352 if (netId == 0 && GetNetForApp() > 0) { 353 info.netId = (uint32_t)GetNetForApp(); 354 } 355 int32_t result = NetsysSendKeyForCache(sockFd, param, info); 356 if (result < 0) { 357 return result; 358 } 359 360 struct AddrInfo addrInfo[MAX_RESULTS] = {}; 361 int32_t resNum = FillAddrInfo(addrInfo, res); 362 if (resNum < 0) { 363 return CloseSocketReturn(sockFd, -1); 364 } 365 366 if (!PollSendData(sockFd, (char *)&resNum, sizeof(resNum))) { 367 DNS_CONFIG_PRINT("send failed %d", errno); 368 return CloseSocketReturn(sockFd, -errno); 369 } 370 371 if (resNum == 0) { 372 return CloseSocketReturn(sockFd, 0); 373 } 374 375 if (!PollSendData(sockFd, (char *)addrInfo, sizeof(struct AddrInfo) * resNum)) { 376 DNS_CONFIG_PRINT("send failed %d", errno); 377 return CloseSocketReturn(sockFd, -errno); 378 } 379 380 return CloseSocketReturn(sockFd, 0); 381} 382 383int32_t NetSysSetResolvCache(uint16_t netId, const struct ParamWrapper param, struct addrinfo *res) 384{ 385 char *hostName = param.host; 386 if (hostName == NULL || strlen(hostName) == 0 || res == NULL) { 387 DNS_CONFIG_PRINT("Invalid Param"); 388 return -EINVAL; 389 } 390 391 int sockFd = CreateConnectionToNetSys(); 392 if (sockFd < 0) { 393 DNS_CONFIG_PRINT("NetSysSetResolvCache CreateConnectionToNetSys connect to netsys err: %d", errno); 394 return sockFd; 395 } 396 397 int err = NetSysSetResolvCacheInternal(sockFd, netId, param, res); 398 if (err < 0) { 399 DNS_CONFIG_PRINT("NetSysSetResolvCache NetSysSetResolvCacheInternal err: %d", errno); 400 return err; 401 } 402 403 return 0; 404} 405 406static int32_t NetSysIsIpv6EnableInternal(int sockFd, uint16_t netId, int *enable) 407{ 408 struct RequestInfo info = { 409 .uid = getuid(), 410 .command = JUDGE_IPV6, 411 .netId = netId, 412 }; 413 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) { 414 DNS_CONFIG_PRINT("send failed %d", errno); 415 return CloseSocketReturn(sockFd, -errno); 416 } 417 418 if (!PollRecvData(sockFd, (char *)enable, sizeof(int))) { 419 DNS_CONFIG_PRINT("read failed %d", errno); 420 return CloseSocketReturn(sockFd, -errno); 421 } 422 423 return CloseSocketReturn(sockFd, 0); 424} 425 426int NetSysIsIpv6Enable(uint16_t netId) 427{ 428 int sockFd = CreateConnectionToNetSys(); 429 if (sockFd < 0) { 430 DNS_CONFIG_PRINT("NetSysIsIpv6Enable CreateConnectionToNetSys connect to netsys err: %d", errno); 431 return sockFd; 432 } 433 int enable = 0; 434 int err = NetSysIsIpv6EnableInternal(sockFd, netId, &enable); 435 if (err < 0) { 436 return 0; 437 } 438 439 return enable; 440} 441 442static int32_t NetSysPostDnsResultPollSendData(int sockFd, int queryret, int32_t resNum, struct QueryParam *param, 443 struct AddrInfo addrInfo[static MAX_RESULTS]) 444{ 445 if (!PollSendData(sockFd, (char *)&queryret, sizeof(int))) { 446 DNS_CONFIG_PRINT("send failed %d", errno); 447 return CloseSocketReturn(sockFd, -errno); 448 } 449 450 if (!PollSendData(sockFd, (char *)&resNum, sizeof(int32_t))) { 451 DNS_CONFIG_PRINT("send failed %d", errno); 452 return CloseSocketReturn(sockFd, -errno); 453 } 454 455 if (!PollSendData(sockFd, (char *)param, sizeof(struct QueryParam))) { 456 DNS_CONFIG_PRINT("send failed %d", errno); 457 return CloseSocketReturn(sockFd, -errno); 458 } 459 460 if (resNum > 0) { 461 if (!PollSendData(sockFd, (char *)addrInfo, sizeof(struct AddrInfo) * resNum)) { 462 DNS_CONFIG_PRINT("send failed %d", errno); 463 return CloseSocketReturn(sockFd, -errno); 464 } 465 } 466 return CloseSocketReturn(sockFd, 0); 467} 468 469static int32_t NetSysPostDnsResultInternal(int sockFd, uint16_t netId, char* name, int usedtime, int queryret, 470 struct addrinfo *res, struct queryparam *param) 471{ 472 struct RequestInfo info = { 473 .uid = getuid(), 474 .command = POST_DNS_RESULT, 475 .netId = netId, 476 }; 477 478 int32_t uid = (int32_t)(getuid()); 479 int32_t pid = getpid(); 480 uint32_t nameLen = strlen(name) + 1; 481 NETSYS_CLIENT_PRINT("NetSysPostDnsResultInternal uid %d, pid %d, netid %d pkg", uid, pid, netId); 482 483 struct AddrInfo addrInfo[MAX_RESULTS] = {}; 484 struct QueryParam netparam = {}; 485 int32_t resNum = 0; 486 if (queryret == 0) { 487 resNum = FillAddrInfo(addrInfo, res); 488 } 489 if (resNum < 0) { 490 return CloseSocketReturn(sockFd, -1); 491 } 492 FillQueryParam(param, &netparam); 493 494 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) { 495 DNS_CONFIG_PRINT("send failed %d", errno); 496 return CloseSocketReturn(sockFd, -errno); 497 } 498 499 if (!PollSendData(sockFd, (char *)&uid, sizeof(int32_t))) { 500 DNS_CONFIG_PRINT("send failed %d", errno); 501 return CloseSocketReturn(sockFd, -errno); 502 } 503 504 if (!PollSendData(sockFd, (char *)&pid, sizeof(int32_t))) { 505 DNS_CONFIG_PRINT("send failed %d", errno); 506 return CloseSocketReturn(sockFd, -errno); 507 } 508 509 if (!PollSendData(sockFd, (char *)&nameLen, sizeof(uint32_t))) { 510 DNS_CONFIG_PRINT("send failed %d", errno); 511 return CloseSocketReturn(sockFd, -errno); 512 } 513 514 if (!PollSendData(sockFd, name, (sizeof(char) * nameLen))) { 515 DNS_CONFIG_PRINT("send failed %d", errno); 516 return CloseSocketReturn(sockFd, -errno); 517 } 518 519 if (!PollSendData(sockFd, (char *)&usedtime, sizeof(int))) { 520 DNS_CONFIG_PRINT("send failed %d", errno); 521 return CloseSocketReturn(sockFd, -errno); 522 } 523 524 return NetSysPostDnsResultPollSendData(sockFd, queryret, resNum, &netparam, addrInfo); 525} 526 527int32_t NetSysPostDnsResult(int netid, char* name, int usedtime, int queryret, 528 struct addrinfo *res, struct queryparam *param) 529{ 530 if (name == NULL) { 531 return -1; 532 } 533 534 int sockFd = CreateConnectionToNetSys(); 535 if (sockFd < 0) { 536 DNS_CONFIG_PRINT("NetSysPostDnsResult CreateConnectionToNetSys connect to netsys err: %d", errno); 537 return sockFd; 538 } 539 int err = NetSysPostDnsResultInternal(sockFd, netid, name, usedtime, queryret, res, param); 540 if (err < 0) { 541 return -1; 542 } 543 544 return 0; 545} 546 547static int32_t NetSysGetDefaultNetworkInternal(int sockFd, uint16_t netId, int32_t *currentNetId) 548{ 549 struct RequestInfo info = { 550 .uid = getuid(), 551 .command = GET_DEFAULT_NETWORK, 552 .netId = netId, 553 }; 554 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) { 555 DNS_CONFIG_PRINT("send failed %d", errno); 556 return CloseSocketReturn(sockFd, -errno); 557 } 558 559 if (!PollRecvData(sockFd, (char *)currentNetId, sizeof(int))) { 560 DNS_CONFIG_PRINT("read failed %d", errno); 561 return CloseSocketReturn(sockFd, -errno); 562 } 563 DNS_CONFIG_PRINT("currentNetId %d", *currentNetId); 564 return CloseSocketReturn(sockFd, 0); 565} 566 567int32_t NetSysGetDefaultNetwork(uint16_t netId, int32_t* currentNetId) 568{ 569 int sockFd = CreateConnectionToNetSys(); 570 int err = NetSysGetDefaultNetworkInternal(sockFd, netId, currentNetId); 571 if (err < 0) { 572 return -1; 573 } 574 575 return 0; 576} 577 578static int32_t NetSysBindSocketInternal(int sockFd, uint16_t netId, int32_t fd) 579{ 580 struct RequestInfo info = { 581 .uid = getuid(), 582 .command = BIND_SOCKET, 583 .netId = netId, 584 }; 585 if (!PollSendData(sockFd, (const char *)(&info), sizeof(info))) { 586 DNS_CONFIG_PRINT("send failed %d", errno); 587 return CloseSocketReturn(sockFd, -errno); 588 } 589 590 if (!PollSendData(sockFd, (const char *)(&fd), sizeof(int32_t))) { 591 DNS_CONFIG_PRINT("send failed %d", errno); 592 return CloseSocketReturn(sockFd, -errno); 593 } 594 595 return CloseSocketReturn(sockFd, 0); 596} 597 598int32_t NetSysBindSocket(int32_t fd, uint32_t netId) 599{ 600 int sockFd = CreateConnectionToNetSys(); 601 DNS_CONFIG_PRINT("NetSysBindSocket %d", fd); 602 int err = NetSysBindSocketInternal(sockFd, netId, fd); 603 if (err < 0) { 604 return -1; 605 } 606 607 return 0; 608} 609 610#ifdef __cplusplus 611} 612#endif 613