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