1b1b8bc3fSopenharmony_ci/* 2b1b8bc3fSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License. 5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at 6b1b8bc3fSopenharmony_ci * 7b1b8bc3fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1b8bc3fSopenharmony_ci * 9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and 13b1b8bc3fSopenharmony_ci * limitations under the License. 14b1b8bc3fSopenharmony_ci */ 15b1b8bc3fSopenharmony_ci 16b1b8bc3fSopenharmony_ci#include "vpn_manager.h" 17b1b8bc3fSopenharmony_ci 18b1b8bc3fSopenharmony_ci#include <arpa/inet.h> 19b1b8bc3fSopenharmony_ci#include <fcntl.h> 20b1b8bc3fSopenharmony_ci#include <linux/if.h> 21b1b8bc3fSopenharmony_ci#include <linux/ipv6.h> 22b1b8bc3fSopenharmony_ci#include <linux/if_tun.h> 23b1b8bc3fSopenharmony_ci#include <netinet/in.h> 24b1b8bc3fSopenharmony_ci#include <sys/ioctl.h> 25b1b8bc3fSopenharmony_ci#include <sys/socket.h> 26b1b8bc3fSopenharmony_ci#include <sys/types.h> 27b1b8bc3fSopenharmony_ci#include <sys/un.h> 28b1b8bc3fSopenharmony_ci#include <thread> 29b1b8bc3fSopenharmony_ci#include <unistd.h> 30b1b8bc3fSopenharmony_ci 31b1b8bc3fSopenharmony_ci#include "init_socket.h" 32b1b8bc3fSopenharmony_ci#include "net_manager_constants.h" 33b1b8bc3fSopenharmony_ci#include "netnative_log_wrapper.h" 34b1b8bc3fSopenharmony_ci#include "securec.h" 35b1b8bc3fSopenharmony_ci#include "netmanager_base_common_utils.h" 36b1b8bc3fSopenharmony_ci 37b1b8bc3fSopenharmony_cinamespace OHOS { 38b1b8bc3fSopenharmony_cinamespace NetManagerStandard { 39b1b8bc3fSopenharmony_ci 40b1b8bc3fSopenharmony_cinamespace { 41b1b8bc3fSopenharmony_ciconstexpr const char *TUN_CARD_NAME = "vpn-tun"; 42b1b8bc3fSopenharmony_ciconstexpr const char *TUN_DEVICE_PATH = "/dev/tun"; 43b1b8bc3fSopenharmony_ciconstexpr int32_t NET_MASK_MAX_LENGTH = 32; 44b1b8bc3fSopenharmony_ciconstexpr int32_t MAX_UNIX_SOCKET_CLIENT = 5; 45b1b8bc3fSopenharmony_ci} // namespace 46b1b8bc3fSopenharmony_ci 47b1b8bc3fSopenharmony_ciint32_t VpnManager::CreateVpnInterface() 48b1b8bc3fSopenharmony_ci{ 49b1b8bc3fSopenharmony_ci if (tunFd_ != 0) { 50b1b8bc3fSopenharmony_ci StartVpnInterfaceFdListen(); 51b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 52b1b8bc3fSopenharmony_ci } 53b1b8bc3fSopenharmony_ci 54b1b8bc3fSopenharmony_ci ifreq ifr = {}; 55b1b8bc3fSopenharmony_ci if (InitIfreq(ifr, TUN_CARD_NAME) != NETMANAGER_SUCCESS) { 56b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 57b1b8bc3fSopenharmony_ci } 58b1b8bc3fSopenharmony_ci 59b1b8bc3fSopenharmony_ci int32_t tunfd = open(TUN_DEVICE_PATH, O_RDWR | O_NONBLOCK); 60b1b8bc3fSopenharmony_ci if (tunfd <= 0) { 61b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("open virtual device failed: %{public}d", errno); 62b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 63b1b8bc3fSopenharmony_ci } 64b1b8bc3fSopenharmony_ci 65b1b8bc3fSopenharmony_ci ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 66b1b8bc3fSopenharmony_ci if (ioctl(tunfd, TUNSETIFF, &ifr) < 0) { 67b1b8bc3fSopenharmony_ci close(tunfd); 68b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("tun set iff error: %{public}d", errno); 69b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 70b1b8bc3fSopenharmony_ci } 71b1b8bc3fSopenharmony_ci 72b1b8bc3fSopenharmony_ci net4Sock_ = socket(AF_INET, SOCK_DGRAM, 0); 73b1b8bc3fSopenharmony_ci if (net4Sock_ < 0) { 74b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno); 75b1b8bc3fSopenharmony_ci } 76b1b8bc3fSopenharmony_ci net6Sock_ = socket(AF_INET6, SOCK_DGRAM, 0); 77b1b8bc3fSopenharmony_ci if (net6Sock_ < 0) { 78b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("create SOCK_DGRAM ipv6 failed: %{public}d", errno); 79b1b8bc3fSopenharmony_ci } 80b1b8bc3fSopenharmony_ci if (net4Sock_ < 0 && net6Sock_ < 0) { 81b1b8bc3fSopenharmony_ci close(tunfd); 82b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("create SOCK_DGRAM ip failed"); 83b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 84b1b8bc3fSopenharmony_ci } 85b1b8bc3fSopenharmony_ci 86b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("open virtual device successfully, [%{public}d]", tunfd); 87b1b8bc3fSopenharmony_ci tunFd_ = tunfd; 88b1b8bc3fSopenharmony_ci SetVpnUp(); 89b1b8bc3fSopenharmony_ci StartVpnInterfaceFdListen(); 90b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 91b1b8bc3fSopenharmony_ci} 92b1b8bc3fSopenharmony_ci 93b1b8bc3fSopenharmony_civoid VpnManager::DestroyVpnInterface() 94b1b8bc3fSopenharmony_ci{ 95b1b8bc3fSopenharmony_ci SetVpnDown(); 96b1b8bc3fSopenharmony_ci if (net4Sock_ != 0) { 97b1b8bc3fSopenharmony_ci close(net4Sock_); 98b1b8bc3fSopenharmony_ci net4Sock_ = 0; 99b1b8bc3fSopenharmony_ci } 100b1b8bc3fSopenharmony_ci if (net6Sock_ != 0) { 101b1b8bc3fSopenharmony_ci close(net6Sock_); 102b1b8bc3fSopenharmony_ci net6Sock_ = 0; 103b1b8bc3fSopenharmony_ci } 104b1b8bc3fSopenharmony_ci if (tunFd_ != 0) { 105b1b8bc3fSopenharmony_ci close(tunFd_); 106b1b8bc3fSopenharmony_ci tunFd_ = 0; 107b1b8bc3fSopenharmony_ci } 108b1b8bc3fSopenharmony_ci} 109b1b8bc3fSopenharmony_ci 110b1b8bc3fSopenharmony_ciint32_t VpnManager::SetVpnResult(std::atomic_int &fd, unsigned long cmd, ifreq &ifr) 111b1b8bc3fSopenharmony_ci{ 112b1b8bc3fSopenharmony_ci if (fd > 0) { 113b1b8bc3fSopenharmony_ci if (ioctl(fd, cmd, &ifr) < 0) { 114b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("set vpn error, errno:%{public}d", errno); 115b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 116b1b8bc3fSopenharmony_ci } 117b1b8bc3fSopenharmony_ci } 118b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 119b1b8bc3fSopenharmony_ci} 120b1b8bc3fSopenharmony_ci 121b1b8bc3fSopenharmony_ciint32_t VpnManager::SetVpnMtu(const std::string &ifName, int32_t mtu) 122b1b8bc3fSopenharmony_ci{ 123b1b8bc3fSopenharmony_ci if (mtu <= 0) { 124b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("invalid mtu value"); 125b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 126b1b8bc3fSopenharmony_ci } 127b1b8bc3fSopenharmony_ci 128b1b8bc3fSopenharmony_ci ifreq ifr; 129b1b8bc3fSopenharmony_ci if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) { 130b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 131b1b8bc3fSopenharmony_ci } 132b1b8bc3fSopenharmony_ci 133b1b8bc3fSopenharmony_ci ifr.ifr_mtu = mtu; 134b1b8bc3fSopenharmony_ci int32_t ret4 = SetVpnResult(net4Sock_, SIOCSIFMTU, ifr); 135b1b8bc3fSopenharmony_ci int32_t ret6 = SetVpnResult(net6Sock_, SIOCSIFMTU, ifr); 136b1b8bc3fSopenharmony_ci if (ret4 == NETMANAGER_ERROR || ret6 == NETMANAGER_ERROR || (net4Sock_ < 0 && net6Sock_ < 0)) { 137b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set MTU failed"); 138b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 139b1b8bc3fSopenharmony_ci } else { 140b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set MTU success"); 141b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 142b1b8bc3fSopenharmony_ci } 143b1b8bc3fSopenharmony_ci} 144b1b8bc3fSopenharmony_ci 145b1b8bc3fSopenharmony_ciint32_t VpnManager::SetVpnAddress(const std::string &ifName, const std::string &tunAddr, int32_t prefix) 146b1b8bc3fSopenharmony_ci{ 147b1b8bc3fSopenharmony_ci ifreq ifr = {}; 148b1b8bc3fSopenharmony_ci if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) { 149b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 150b1b8bc3fSopenharmony_ci } 151b1b8bc3fSopenharmony_ci 152b1b8bc3fSopenharmony_ci bool isIpv6 = CommonUtils::IsValidIPV6(tunAddr); 153b1b8bc3fSopenharmony_ci if (isIpv6) { 154b1b8bc3fSopenharmony_ci struct in6_ifreq ifr6 = {}; 155b1b8bc3fSopenharmony_ci if (ioctl(net6Sock_, SIOCGIFINDEX, &ifr) <0) { 156b1b8bc3fSopenharmony_ci NETNATIVE_LOGE(" get network interface ipv6 failed: %{public}d", errno); 157b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 158b1b8bc3fSopenharmony_ci } 159b1b8bc3fSopenharmony_ci if (inet_pton(AF_INET6, tunAddr.c_str(), &ifr6.ifr6_addr) == 0) { 160b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("inet_pton ipv6 address failed: %{public}d", errno); 161b1b8bc3fSopenharmony_ci } 162b1b8bc3fSopenharmony_ci ifr6.ifr6_prefixlen = prefix; 163b1b8bc3fSopenharmony_ci ifr6.ifr6_ifindex = ifr.ifr_ifindex; 164b1b8bc3fSopenharmony_ci if (ioctl(net6Sock_, SIOCSIFADDR, &ifr6) < 0) { 165b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("ioctl set ipv6 address failed: %{public}d", errno); 166b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 167b1b8bc3fSopenharmony_ci } 168b1b8bc3fSopenharmony_ci } else { 169b1b8bc3fSopenharmony_ci in_addr ipv4Addr = {}; 170b1b8bc3fSopenharmony_ci if (inet_aton(tunAddr.c_str(), &ipv4Addr) == 0) { 171b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("addr inet_aton error"); 172b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 173b1b8bc3fSopenharmony_ci } 174b1b8bc3fSopenharmony_ci 175b1b8bc3fSopenharmony_ci auto sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_addr); 176b1b8bc3fSopenharmony_ci sin->sin_family = AF_INET; 177b1b8bc3fSopenharmony_ci sin->sin_addr = ipv4Addr; 178b1b8bc3fSopenharmony_ci if (ioctl(net4Sock_, SIOCSIFADDR, &ifr) < 0) { 179b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("ioctl set ipv4 address failed: %{public}d", errno); 180b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 181b1b8bc3fSopenharmony_ci } 182b1b8bc3fSopenharmony_ci 183b1b8bc3fSopenharmony_ci if (prefix <= 0 || prefix >= NET_MASK_MAX_LENGTH) { 184b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("prefix: %{public}d error", prefix); 185b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 186b1b8bc3fSopenharmony_ci } 187b1b8bc3fSopenharmony_ci in_addr_t mask = prefix ? (~0 << (NET_MASK_MAX_LENGTH - prefix)) : 0; 188b1b8bc3fSopenharmony_ci sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_netmask); 189b1b8bc3fSopenharmony_ci sin->sin_family = AF_INET; 190b1b8bc3fSopenharmony_ci sin->sin_addr.s_addr = htonl(mask); 191b1b8bc3fSopenharmony_ci if (ioctl(net4Sock_, SIOCSIFNETMASK, &ifr) < 0) { 192b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("ioctl set ip mask failed: %{public}d", errno); 193b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 194b1b8bc3fSopenharmony_ci } 195b1b8bc3fSopenharmony_ci } 196b1b8bc3fSopenharmony_ci 197b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set ip address success"); 198b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 199b1b8bc3fSopenharmony_ci} 200b1b8bc3fSopenharmony_ci 201b1b8bc3fSopenharmony_ciint32_t VpnManager::SetVpnUp() 202b1b8bc3fSopenharmony_ci{ 203b1b8bc3fSopenharmony_ci ifreq ifr = {}; 204b1b8bc3fSopenharmony_ci if (InitIfreq(ifr, TUN_CARD_NAME) != NETMANAGER_SUCCESS) { 205b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 206b1b8bc3fSopenharmony_ci } 207b1b8bc3fSopenharmony_ci 208b1b8bc3fSopenharmony_ci ifr.ifr_flags = IFF_UP; 209b1b8bc3fSopenharmony_ci int32_t ret4 = SetVpnResult(net4Sock_, SIOCSIFFLAGS, ifr); 210b1b8bc3fSopenharmony_ci int32_t ret6 = SetVpnResult(net6Sock_, SIOCSIFFLAGS, ifr); 211b1b8bc3fSopenharmony_ci if (ret4 == NETMANAGER_ERROR || ret6 == NETMANAGER_ERROR || (net4Sock_ < 0 && net6Sock_ < 0)) { 212b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set iff up failed"); 213b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 214b1b8bc3fSopenharmony_ci } else { 215b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set iff up success"); 216b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 217b1b8bc3fSopenharmony_ci } 218b1b8bc3fSopenharmony_ci} 219b1b8bc3fSopenharmony_ci 220b1b8bc3fSopenharmony_ciint32_t VpnManager::SetVpnDown() 221b1b8bc3fSopenharmony_ci{ 222b1b8bc3fSopenharmony_ci ifreq ifr = {}; 223b1b8bc3fSopenharmony_ci if (InitIfreq(ifr, TUN_CARD_NAME) != NETMANAGER_SUCCESS) { 224b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 225b1b8bc3fSopenharmony_ci } 226b1b8bc3fSopenharmony_ci 227b1b8bc3fSopenharmony_ci ifr.ifr_flags &= ~IFF_UP; 228b1b8bc3fSopenharmony_ci int32_t ret4 = SetVpnResult(net4Sock_, SIOCSIFFLAGS, ifr); 229b1b8bc3fSopenharmony_ci int32_t ret6 = SetVpnResult(net6Sock_, SIOCSIFFLAGS, ifr); 230b1b8bc3fSopenharmony_ci if (ret4 == NETMANAGER_ERROR || ret6 == NETMANAGER_ERROR || (net4Sock_ < 0 && net6Sock_ < 0)) { 231b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set iff down failed"); 232b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 233b1b8bc3fSopenharmony_ci } else { 234b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("set iff down success"); 235b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 236b1b8bc3fSopenharmony_ci } 237b1b8bc3fSopenharmony_ci} 238b1b8bc3fSopenharmony_ci 239b1b8bc3fSopenharmony_ciint32_t VpnManager::InitIfreq(ifreq &ifr, const std::string &cardName) 240b1b8bc3fSopenharmony_ci{ 241b1b8bc3fSopenharmony_ci if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) { 242b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("memset_s ifr failed!"); 243b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 244b1b8bc3fSopenharmony_ci } 245b1b8bc3fSopenharmony_ci if (strncpy_s(ifr.ifr_name, IFNAMSIZ, cardName.c_str(), strlen(cardName.c_str())) != EOK) { 246b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("strcpy_s ifr name fail"); 247b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 248b1b8bc3fSopenharmony_ci } 249b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 250b1b8bc3fSopenharmony_ci} 251b1b8bc3fSopenharmony_ci 252b1b8bc3fSopenharmony_ciint32_t VpnManager::SendVpnInterfaceFdToClient(int32_t clientFd, int32_t tunFd) 253b1b8bc3fSopenharmony_ci{ 254b1b8bc3fSopenharmony_ci char buf[1] = {0}; 255b1b8bc3fSopenharmony_ci iovec iov; 256b1b8bc3fSopenharmony_ci iov.iov_base = buf; 257b1b8bc3fSopenharmony_ci iov.iov_len = sizeof(buf); 258b1b8bc3fSopenharmony_ci union { 259b1b8bc3fSopenharmony_ci cmsghdr align; 260b1b8bc3fSopenharmony_ci char cmsg[CMSG_SPACE(sizeof(int32_t))]; 261b1b8bc3fSopenharmony_ci } cmsgu; 262b1b8bc3fSopenharmony_ci if (memset_s(cmsgu.cmsg, sizeof(cmsgu.cmsg), 0, sizeof(cmsgu.cmsg)) != EOK) { 263b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("memset_s cmsgu.cmsg failed!"); 264b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 265b1b8bc3fSopenharmony_ci } 266b1b8bc3fSopenharmony_ci msghdr message; 267b1b8bc3fSopenharmony_ci if (memset_s(&message, sizeof(message), 0, sizeof(message)) != EOK) { 268b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("memset_s message failed!"); 269b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 270b1b8bc3fSopenharmony_ci } 271b1b8bc3fSopenharmony_ci 272b1b8bc3fSopenharmony_ci message.msg_iov = &iov; 273b1b8bc3fSopenharmony_ci message.msg_iovlen = 1; 274b1b8bc3fSopenharmony_ci message.msg_control = cmsgu.cmsg; 275b1b8bc3fSopenharmony_ci message.msg_controllen = sizeof(cmsgu.cmsg); 276b1b8bc3fSopenharmony_ci cmsghdr *cmsgh = CMSG_FIRSTHDR(&message); 277b1b8bc3fSopenharmony_ci cmsgh->cmsg_len = CMSG_LEN(sizeof(tunFd)); 278b1b8bc3fSopenharmony_ci cmsgh->cmsg_level = SOL_SOCKET; 279b1b8bc3fSopenharmony_ci cmsgh->cmsg_type = SCM_RIGHTS; 280b1b8bc3fSopenharmony_ci if (memcpy_s(CMSG_DATA(cmsgh), sizeof(tunFd), &tunFd, sizeof(tunFd)) != EOK) { 281b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("memcpy_s cmsgu failed!"); 282b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 283b1b8bc3fSopenharmony_ci } 284b1b8bc3fSopenharmony_ci if (sendmsg(clientFd, &message, 0) < 0) { 285b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("sendmsg error: %{public}d, clientfd[%{public}d], tunfd[%{public}d]", errno, clientFd, tunFd); 286b1b8bc3fSopenharmony_ci return NETMANAGER_ERROR; 287b1b8bc3fSopenharmony_ci } 288b1b8bc3fSopenharmony_ci return NETMANAGER_SUCCESS; 289b1b8bc3fSopenharmony_ci} 290b1b8bc3fSopenharmony_ci 291b1b8bc3fSopenharmony_civoid VpnManager::StartUnixSocketListen() 292b1b8bc3fSopenharmony_ci{ 293b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("StartUnixSocketListen..."); 294b1b8bc3fSopenharmony_ci int32_t serverfd = GetControlSocket("tunfd"); 295b1b8bc3fSopenharmony_ci if (listen(serverfd, MAX_UNIX_SOCKET_CLIENT) < 0) { 296b1b8bc3fSopenharmony_ci close(serverfd); 297b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("listen socket error: %{public}d", errno); 298b1b8bc3fSopenharmony_ci return; 299b1b8bc3fSopenharmony_ci } 300b1b8bc3fSopenharmony_ci 301b1b8bc3fSopenharmony_ci sockaddr_in clientAddr; 302b1b8bc3fSopenharmony_ci socklen_t len = sizeof(clientAddr); 303b1b8bc3fSopenharmony_ci while (true) { 304b1b8bc3fSopenharmony_ci int32_t clientFd = accept(serverfd, reinterpret_cast<sockaddr *>(&clientAddr), &len); 305b1b8bc3fSopenharmony_ci if (clientFd < 0) { 306b1b8bc3fSopenharmony_ci NETNATIVE_LOGE("accept socket error: %{public}d", errno); 307b1b8bc3fSopenharmony_ci continue; 308b1b8bc3fSopenharmony_ci } 309b1b8bc3fSopenharmony_ci 310b1b8bc3fSopenharmony_ci SendVpnInterfaceFdToClient(clientFd, tunFd_); 311b1b8bc3fSopenharmony_ci close(clientFd); 312b1b8bc3fSopenharmony_ci } 313b1b8bc3fSopenharmony_ci 314b1b8bc3fSopenharmony_ci close(serverfd); 315b1b8bc3fSopenharmony_ci listeningFlag_ = false; 316b1b8bc3fSopenharmony_ci} 317b1b8bc3fSopenharmony_ci 318b1b8bc3fSopenharmony_civoid VpnManager::StartVpnInterfaceFdListen() 319b1b8bc3fSopenharmony_ci{ 320b1b8bc3fSopenharmony_ci if (listeningFlag_) { 321b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("VpnInterface fd is listening..."); 322b1b8bc3fSopenharmony_ci return; 323b1b8bc3fSopenharmony_ci } 324b1b8bc3fSopenharmony_ci 325b1b8bc3fSopenharmony_ci NETNATIVE_LOGI("StartVpnInterfaceFdListen..."); 326b1b8bc3fSopenharmony_ci std::thread unixThread([this]() { StartUnixSocketListen(); }); 327b1b8bc3fSopenharmony_ci unixThread.detach(); 328b1b8bc3fSopenharmony_ci pthread_setname_np(unixThread.native_handle(), "unix_socket_tunfd"); 329b1b8bc3fSopenharmony_ci listeningFlag_ = true; 330b1b8bc3fSopenharmony_ci} 331b1b8bc3fSopenharmony_ci 332b1b8bc3fSopenharmony_ci} // namespace NetManagerStandard 333b1b8bc3fSopenharmony_ci} // namespace OHOS 334