1 /*
2  * Copyright (c) 2023-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 "local_socket_exec.h"
17 
18 #include <cerrno>
19 #include <fcntl.h>
20 #include <poll.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <thread>
24 #include <unistd.h>
25 
26 #include "context_key.h"
27 #include "napi_utils.h"
28 #include "netstack_log.h"
29 #include "securec.h"
30 #include "socket_async_work.h"
31 #include "socket_module.h"
32 
33 #ifndef EPOLLIN
34 #define EPOLLIN 0x001
35 #endif
36 
37 namespace {
38 constexpr int BACKLOG = 32;
39 
40 constexpr int DEFAULT_BUFFER_SIZE = 8192;
41 
42 constexpr int MAX_SOCKET_BUFFER_SIZE = 262144;
43 
44 constexpr int DEFAULT_POLL_TIMEOUT_MS = 500;
45 
46 constexpr int UNKNOW_ERROR = -1;
47 
48 constexpr int NO_MEMORY = -2;
49 
50 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
51 constexpr int MAX_CLIENTS = 1024;
52 #endif
53 
54 constexpr int ERRNO_BAD_FD = 9;
55 
56 constexpr int DEFAULT_TIMEOUT_MS = 20000;
57 
58 constexpr int UNIT_CONVERSION_1000 = 1000; // multiples of conversion between units
59 
60 constexpr char LOCAL_SOCKET_CONNECTION[] = "LocalSocketConnection";
61 
62 constexpr char LOCAL_SOCKET_SERVER_HANDLE_CLIENT[] = "OS_NET_LSAcc";
63 
64 constexpr char LOCAL_SOCKET_SERVER_ACCEPT_RECV_DATA[] = "OS_NET_LSAccRD";
65 
66 constexpr char LOCAL_SOCKET_CONNECT[] = "OS_NET_LSCon";
67 } // namespace
68 
69 namespace OHOS::NetStack::Socket::LocalSocketExec {
70 struct MsgWithLocalRemoteInfo {
71     MsgWithLocalRemoteInfo() = delete;
MsgWithLocalRemoteInfoOHOS::NetStack::Socket::LocalSocketExec::MsgWithLocalRemoteInfo72     MsgWithLocalRemoteInfo(void *d, size_t length, const std::string &path) : data(d), len(length)
73     {
74         remoteInfo.SetAddress(path);
75     }
~MsgWithLocalRemoteInfoOHOS::NetStack::Socket::LocalSocketExec::MsgWithLocalRemoteInfo76     ~MsgWithLocalRemoteInfo()
77     {
78         if (data) {
79             free(data);
80         }
81     }
82     void *data = nullptr;
83     size_t len = 0;
84     LocalSocketRemoteInfo remoteInfo;
85 };
86 
LocalSocketServerConnectionFinalize(napi_env,void * data,void *)87 void LocalSocketServerConnectionFinalize(napi_env, void *data, void *)
88 {
89     NETSTACK_LOGI("localsocket connection is finalized");
90     EventManager *manager = reinterpret_cast<EventManager *>(data);
91     if (manager != nullptr) {
92         LocalSocketConnectionData *connectData = reinterpret_cast<LocalSocketConnectionData *>(manager->GetData());
93         if (connectData != nullptr) {
94             auto serverManager = connectData->serverManager_;
95             if (serverManager != nullptr) {
96                 serverManager->RemoveEventManager(connectData->clientId_);
97                 serverManager->RemoveAccept(connectData->clientId_);
98             }
99             delete connectData;
100             connectData = nullptr;
101         }
102     }
103 }
104 
NewInstanceWithConstructor(napi_env env,napi_callback_info info,napi_value jsConstructor,LocalSocketConnectionData * data)105 napi_value NewInstanceWithConstructor(napi_env env, napi_callback_info info, napi_value jsConstructor,
106                                       LocalSocketConnectionData *data)
107 {
108     napi_value result = nullptr;
109     NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
110 
111     EventManager *manager = new (std::nothrow) EventManager();
112     if (manager == nullptr) {
113         delete data;
114         return result;
115     }
116     manager->SetData(reinterpret_cast<void *>(data));
117     EventManager::SetValid(manager);
118     data->serverManager_->AddEventManager(data->clientId_, manager);
119     manager->CreateEventReference(env, result);
120     napi_wrap(env, result, reinterpret_cast<void *>(manager), LocalSocketServerConnectionFinalize, nullptr, nullptr);
121     return result;
122 }
123 
ConstructLocalSocketConnection(napi_env env,napi_callback_info info,LocalSocketConnectionData * data)124 napi_value ConstructLocalSocketConnection(napi_env env, napi_callback_info info, LocalSocketConnectionData *data)
125 {
126     std::initializer_list<napi_property_descriptor> properties = {
127         DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_SEND,
128                               SocketModuleExports::LocalSocketConnection::Send),
129         DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_CLOSE,
130                               SocketModuleExports::LocalSocketConnection::Close),
131         DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_ON,
132                               SocketModuleExports::LocalSocketConnection::On),
133         DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_OFF,
134                               SocketModuleExports::LocalSocketConnection::Off),
135     };
136 
137     auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
138         napi_value thisVal = nullptr;
139         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
140         return thisVal;
141     };
142 
143     napi_property_descriptor descriptors[properties.size()];
144     std::copy(properties.begin(), properties.end(), descriptors);
145 
146     napi_value jsConstructor = nullptr;
147     napi_define_class(env, LOCAL_SOCKET_CONNECTION, NAPI_AUTO_LENGTH, constructor, nullptr, properties.size(),
148                       descriptors, &jsConstructor);
149 
150     if (jsConstructor != nullptr) {
151         napi_value result = NewInstanceWithConstructor(env, info, jsConstructor, data);
152         NapiUtils::SetInt32Property(env, result, SocketModuleExports::LocalSocketConnection::PROPERTY_CLIENT_ID,
153                                     data->clientId_);
154         return result;
155     }
156     delete data;
157     return NapiUtils::GetUndefined(env);
158 }
159 
MakeLocalSocketConnectionMessage(napi_env env,void * para)160 static napi_value MakeLocalSocketConnectionMessage(napi_env env, void *para)
161 {
162     auto pData = reinterpret_cast<LocalSocketConnectionData *>(para);
163     napi_callback_info info = nullptr;
164     return ConstructLocalSocketConnection(env, info, pData);
165 }
166 
MakeJsLocalSocketMessageParam(napi_env env,napi_value msgBuffer,MsgWithLocalRemoteInfo * msg)167 static napi_value MakeJsLocalSocketMessageParam(napi_env env, napi_value msgBuffer, MsgWithLocalRemoteInfo *msg)
168 {
169     napi_value obj = NapiUtils::CreateObject(env);
170     if (NapiUtils::GetValueType(env, obj) != napi_object) {
171         return nullptr;
172     }
173     if (NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
174         NapiUtils::SetNamedProperty(env, obj, KEY_MESSAGE, msgBuffer);
175     }
176     NapiUtils::SetStringPropertyUtf8(env, obj, KEY_ADDRESS, msg->remoteInfo.GetAddress());
177     NapiUtils::SetUint32Property(env, obj, KEY_SIZE, msg->len);
178     return obj;
179 }
180 
MakeLocalSocketMessage(napi_env env,void * param)181 static napi_value MakeLocalSocketMessage(napi_env env, void *param)
182 {
183     auto *manager = reinterpret_cast<EventManager *>(param);
184     auto *msg = reinterpret_cast<MsgWithLocalRemoteInfo *>(manager->GetQueueData());
185     auto deleter = [](const MsgWithLocalRemoteInfo *p) { delete p; };
186     std::unique_ptr<MsgWithLocalRemoteInfo, decltype(deleter)> handler(msg, deleter);
187     if (msg == nullptr || msg->data == nullptr || msg->len == 0) {
188         NETSTACK_LOGE("msg or msg->data or msg->len is invalid");
189         return NapiUtils::GetUndefined(env);
190     }
191     void *dataHandle = nullptr;
192     napi_value msgBuffer = NapiUtils::CreateArrayBuffer(env, msg->len, &dataHandle);
193     if (dataHandle == nullptr || !NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
194         return NapiUtils::GetUndefined(env);
195     }
196     int result = memcpy_s(dataHandle, msg->len, msg->data, msg->len);
197     if (result != EOK) {
198         NETSTACK_LOGE("memcpy err, res: %{public}d, len: %{public}zu", result, msg->len);
199         return NapiUtils::GetUndefined(env);
200     }
201     return MakeJsLocalSocketMessageParam(env, msgBuffer, msg);
202 }
203 
CallbackTemplate(uv_work_t * work,int status)204 template <napi_value (*MakeJsValue)(napi_env, void *)> static void CallbackTemplate(uv_work_t *work, int status)
205 {
206     (void)status;
207 
208     auto workWrapper = static_cast<UvWorkWrapper *>(work->data);
209     napi_env env = workWrapper->env;
210     auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
211     std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
212 
213     napi_value obj = MakeJsValue(env, workWrapper->data);
214 
215     std::pair<napi_value, napi_value> arg = {NapiUtils::GetUndefined(workWrapper->env), obj};
216     workWrapper->manager->Emit(workWrapper->type, arg);
217 
218     delete workWrapper;
219     delete work;
220 }
221 
OnRecvLocalSocketMessage(EventManager * manager,void * data,size_t len,const std::string & path)222 static bool OnRecvLocalSocketMessage(EventManager *manager, void *data, size_t len, const std::string &path)
223 {
224     if (manager == nullptr || data == nullptr || len == 0) {
225         NETSTACK_LOGE("manager or data or len is invalid");
226         return false;
227     }
228     MsgWithLocalRemoteInfo *msg = new (std::nothrow) MsgWithLocalRemoteInfo(data, len, path);
229     if (msg == nullptr) {
230         NETSTACK_LOGE("MsgWithLocalRemoteInfo construct error");
231         return false;
232     }
233     if (EventManager::IsManagerValid(manager)) {
234         manager->SetQueueData(reinterpret_cast<void *>(msg));
235         manager->EmitByUv(EVENT_MESSAGE, manager, CallbackTemplate<MakeLocalSocketMessage>);
236     }
237     return true;
238 }
239 
PollFd(pollfd * fds,nfds_t num,int timeout)240 static bool PollFd(pollfd *fds, nfds_t num, int timeout)
241 {
242     int ret = poll(fds, num, timeout);
243     if (ret == -1) {
244         NETSTACK_LOGE("poll to send failed, socket is %{public}d, errno is %{public}d", fds->fd, errno);
245         return false;
246     }
247     if (ret == 0) {
248         NETSTACK_LOGE("poll to send timeout, socket is %{public}d, timeout is %{public}d", fds->fd, timeout);
249         return false;
250     }
251     return true;
252 }
253 
ConfirmSocketTimeoutMs(int sock,int type,int defaultValue)254 static int ConfirmSocketTimeoutMs(int sock, int type, int defaultValue)
255 {
256     timeval timeout;
257     socklen_t optlen = sizeof(timeout);
258     if (getsockopt(sock, SOL_SOCKET, type, reinterpret_cast<void *>(&timeout), &optlen) < 0) {
259         NETSTACK_LOGE("get timeout failed, type: %{public}d, sock: %{public}d, errno: %{public}d", type, sock, errno);
260         return defaultValue;
261     }
262     auto socketTimeoutMs = timeout.tv_sec * UNIT_CONVERSION_1000 + timeout.tv_usec / UNIT_CONVERSION_1000;
263     return socketTimeoutMs == 0 ? defaultValue : socketTimeoutMs;
264 }
265 
PollSendData(int sock,const char * data,size_t size,sockaddr * addr,socklen_t addrLen)266 static bool PollSendData(int sock, const char *data, size_t size, sockaddr *addr, socklen_t addrLen)
267 {
268     int bufferSize = DEFAULT_BUFFER_SIZE;
269     int opt = 0;
270     socklen_t optLen = sizeof(opt);
271     if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
272         bufferSize = opt;
273     }
274     int sockType = 0;
275     optLen = sizeof(sockType);
276     if (getsockopt(sock, SOL_SOCKET, SO_TYPE, reinterpret_cast<void *>(&sockType), &optLen) < 0) {
277         NETSTACK_LOGI("get sock opt sock type failed, socket is %{public}d, errno is %{public}d", sock, errno);
278         return false;
279     }
280 
281     auto curPos = data;
282     size_t leftSize = size;
283     nfds_t num = 1;
284     pollfd fds[1] = {{0}};
285     fds[0].fd = sock;
286     fds[0].events = static_cast<short>(POLLOUT);
287 
288     int sendTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_SNDTIMEO, DEFAULT_TIMEOUT_MS);
289     while (leftSize > 0) {
290         if (!PollFd(fds, num, sendTimeoutMs)) {
291             if (errno != EINTR) {
292                 return false;
293             }
294         }
295         size_t sendSize = (sockType == SOCK_STREAM ? leftSize : std::min<size_t>(leftSize, bufferSize));
296         auto sendLen = sendto(sock, curPos, sendSize, 0, addr, addrLen);
297         if (sendLen < 0) {
298             if (errno == EAGAIN || errno == EINTR) {
299                 continue;
300             }
301             NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", sock, errno);
302             return false;
303         }
304         if (sendLen == 0) {
305             break;
306         }
307         curPos += sendLen;
308         leftSize -= sendLen;
309     }
310 
311     if (leftSize != 0) {
312         NETSTACK_LOGE("send not complete, socket is %{public}d, errno is %{public}d", sock, errno);
313         return false;
314     }
315     return true;
316 }
317 
LocalSocketSendEvent(LocalSocketSendContext * context)318 static bool LocalSocketSendEvent(LocalSocketSendContext *context)
319 {
320     if (context == nullptr) {
321         return false;
322     }
323     if (!PollSendData(context->GetSocketFd(), context->GetOptionsRef().GetBufferRef().c_str(),
324                       context->GetOptionsRef().GetBufferRef().size(), nullptr, 0)) {
325         NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
326         context->SetErrorCode(errno);
327         return false;
328     }
329     return true;
330 }
331 
MakeError(napi_env env,void * errCode)332 static napi_value MakeError(napi_env env, void *errCode)
333 {
334     auto code = reinterpret_cast<int32_t *>(errCode);
335     auto deleter = [](const int32_t *p) { delete p; };
336     std::unique_ptr<int32_t, decltype(deleter)> handler(code, deleter);
337 
338     napi_value err = NapiUtils::CreateObject(env);
339     if (NapiUtils::GetValueType(env, err) != napi_object) {
340         return NapiUtils::GetUndefined(env);
341     }
342     NapiUtils::SetInt32Property(env, err, KEY_ERROR_CODE, *code);
343     return err;
344 }
345 
MakeClose(napi_env env,void * data)346 static napi_value MakeClose(napi_env env, void *data)
347 {
348     (void)data;
349     napi_value obj = NapiUtils::CreateObject(env);
350     if (NapiUtils::GetValueType(env, obj) != napi_object) {
351         return NapiUtils::GetUndefined(env);
352     }
353 
354     return obj;
355 }
356 
357 class LocalSocketMessageCallback {
358 public:
359     LocalSocketMessageCallback() = delete;
360 
361     ~LocalSocketMessageCallback() = default;
362 
LocalSocketMessageCallback(EventManager * manager,const std::string & path="")363     explicit LocalSocketMessageCallback(EventManager *manager, const std::string &path = "")
364         : manager_(manager), socketPath_(path)
365     {
366     }
367 
OnError(int err) const368     void OnError(int err) const
369     {
370         if (EventManager::IsManagerValid(manager_)) {
371             manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
372         }
373     }
374 
OnCloseMessage(EventManager * manager=nullptr) const375     void OnCloseMessage(EventManager *manager = nullptr) const
376     {
377         if (manager == nullptr && EventManager::IsManagerValid(manager_)) {
378             manager_->EmitByUv(EVENT_CLOSE, nullptr, CallbackTemplate<MakeClose>);
379         } else if (manager != nullptr && EventManager::IsManagerValid(manager)) {
380             manager->EmitByUv(EVENT_CLOSE, nullptr, CallbackTemplate<MakeClose>);
381         }
382     }
383 
OnMessage(void * data,size_t dataLen) const384     bool OnMessage(void *data, size_t dataLen) const
385     {
386         return OnRecvLocalSocketMessage(manager_, data, dataLen, socketPath_);
387     }
388 
OnMessage(EventManager * manager,void * data,size_t len) const389     bool OnMessage(EventManager *manager, void *data, size_t len) const
390     {
391         return OnRecvLocalSocketMessage(manager, data, len, socketPath_);
392     }
393 
OnLocalSocketConnectionMessage(int clientId,LocalSocketServerManager * serverManager) const394     void OnLocalSocketConnectionMessage(int clientId, LocalSocketServerManager *serverManager) const
395     {
396         LocalSocketConnectionData *data = new (std::nothrow) LocalSocketConnectionData(clientId, serverManager);
397         if (data != nullptr && EventManager::IsManagerValid(manager_)) {
398             manager_->EmitByUv(EVENT_CONNECT, data, CallbackTemplate<MakeLocalSocketConnectionMessage>);
399         }
400     }
GetEventManager() const401     EventManager *GetEventManager() const
402     {
403         return manager_;
404     }
405 
406     EventManager *manager_;
407 
408 private:
409     std::string socketPath_;
410 };
411 
SetSocketBufferSize(int sockfd,int type,uint32_t size)412 static bool SetSocketBufferSize(int sockfd, int type, uint32_t size)
413 {
414     if (size > MAX_SOCKET_BUFFER_SIZE) {
415         NETSTACK_LOGE("invalid socket buffer size: %{public}u", size);
416         return false;
417     }
418     if (setsockopt(sockfd, SOL_SOCKET, type, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
419         NETSTACK_LOGE("localsocket set sock size failed, sock: %{public}d, type: %{public}d, size: %{public}u, size",
420                       sockfd, type, size);
421         return false;
422     }
423     return true;
424 }
425 
SetLocalSocketOptions(int sockfd,const LocalExtraOptions & options)426 static bool SetLocalSocketOptions(int sockfd, const LocalExtraOptions &options)
427 {
428     if (options.AlreadySetRecvBufSize()) {
429         uint32_t recvBufSize = options.GetReceiveBufferSize();
430         if (!SetSocketBufferSize(sockfd, SO_RCVBUF, recvBufSize)) {
431             return false;
432         }
433     }
434     if (options.AlreadySetSendBufSize()) {
435         uint32_t sendBufSize = options.GetSendBufferSize();
436         if (!SetSocketBufferSize(sockfd, SO_SNDBUF, sendBufSize)) {
437             return false;
438         }
439     }
440     if (options.AlreadySetTimeout()) {
441         uint32_t timeMs = options.GetSocketTimeout();
442         timeval timeout = {timeMs / UNIT_CONVERSION_1000, (timeMs % UNIT_CONVERSION_1000) * UNIT_CONVERSION_1000};
443         if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
444             NETSTACK_LOGE("localsocket setsockopt error, SO_RCVTIMEO, fd: %{public}d", sockfd);
445             return false;
446         }
447         if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
448             NETSTACK_LOGE("localsocket setsockopt error, SO_SNDTIMEO, fd: %{public}d", sockfd);
449             return false;
450         }
451     }
452     return true;
453 }
454 
SetSocketDefaultBufferSize(int sockfd,LocalSocketServerManager * mgr)455 static void SetSocketDefaultBufferSize(int sockfd, LocalSocketServerManager *mgr)
456 {
457     uint32_t recvSize = DEFAULT_BUFFER_SIZE;
458     if (mgr->alreadySetExtraOptions_ && mgr->extraOptions_.AlreadySetRecvBufSize()) {
459         recvSize = mgr->extraOptions_.GetReceiveBufferSize();
460     }
461     SetSocketBufferSize(sockfd, SO_RCVBUF, recvSize);
462     uint32_t sendSize = DEFAULT_BUFFER_SIZE;
463     if (mgr->alreadySetExtraOptions_ && mgr->extraOptions_.AlreadySetSendBufSize()) {
464         sendSize = mgr->extraOptions_.GetSendBufferSize();
465     }
466     SetSocketBufferSize(sockfd, SO_SNDBUF, sendSize);
467 }
468 
ConfirmBufferSize(int sock)469 static int ConfirmBufferSize(int sock)
470 {
471     int bufferSize = DEFAULT_BUFFER_SIZE;
472     int opt = 0;
473     socklen_t optLen = sizeof(opt);
474     if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
475         bufferSize = opt;
476     }
477     return bufferSize;
478 }
479 
RecvInErrorCondition(int reason,int clientId,const LocalSocketMessageCallback & callback,LocalSocketServerManager * serverManager)480 static inline void RecvInErrorCondition(int reason, int clientId, const LocalSocketMessageCallback &callback,
481                                         LocalSocketServerManager *serverManager)
482 {
483     callback.OnError(reason);
484     serverManager->RemoveAccept(clientId);
485 }
486 
487 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
LocalSocketServerRecvHandler(int connectFd,LocalSocketServerManager * serverManager,const LocalSocketMessageCallback & callback,const std::string & path)488 static void LocalSocketServerRecvHandler(int connectFd, LocalSocketServerManager *serverManager,
489                                          const LocalSocketMessageCallback &callback, const std::string &path)
490 {
491     serverManager->IncreaseThreadCounts();
492     int clientId = serverManager->AddAccept(connectFd);
493     if (serverManager->alreadySetExtraOptions_) {
494         SetLocalSocketOptions(connectFd, serverManager->extraOptions_);
495     }
496     NETSTACK_LOGI("local socket server accept new, fd: %{public}d, id: %{public}d", connectFd, clientId);
497     callback.OnLocalSocketConnectionMessage(clientId, serverManager);
498     EventManager *eventManager = serverManager->WaitForManager(clientId);
499     int sockRecvSize = ConfirmBufferSize(connectFd);
500     auto buffer = std::make_unique<char[]>(sockRecvSize);
501     if (buffer == nullptr) {
502         NETSTACK_LOGE("failed to malloc, connectFd: %{public}d, malloc size: %{public}d", connectFd, sockRecvSize);
503         RecvInErrorCondition(NO_MEMORY, clientId, callback, serverManager);
504         serverManager->NotifyLoopFinished();
505         return;
506     }
507     while (true) {
508         if (memset_s(buffer.get(), sockRecvSize, 0, sockRecvSize) != EOK) {
509             NETSTACK_LOGE("memset_s failed, connectFd: %{public}d, clientId: %{public}d", connectFd, clientId);
510             continue;
511         }
512         int32_t recvSize = recv(connectFd, buffer.get(), sockRecvSize, 0);
513         if (recvSize == 0) {
514             NETSTACK_LOGI("session closed, errno:%{public}d,fd:%{public}d,id:%{public}d", errno, connectFd, clientId);
515             callback.OnCloseMessage(eventManager);
516             serverManager->RemoveAccept(clientId);
517             break;
518         } else if (recvSize < 0) {
519             if (errno != EINTR && errno != EAGAIN) {
520                 NETSTACK_LOGE("recv error, errno:%{public}d,fd:%{public}d,id:%{public}d", errno, connectFd, clientId);
521                 RecvInErrorCondition(errno, clientId, callback, serverManager);
522                 break;
523             }
524         } else {
525             NETSTACK_LOGD("recv, fd:%{public}d, size:%{public}d", connectFd, recvSize);
526             void *data = malloc(recvSize);
527             if (data == nullptr) {
528                 RecvInErrorCondition(NO_MEMORY, clientId, callback, serverManager);
529                 break;
530             }
531             if (memcpy_s(data, recvSize, buffer.get(), recvSize) != EOK ||
532                 !callback.OnMessage(eventManager, data, recvSize)) {
533                 free(data);
534             }
535         }
536     }
537     serverManager->NotifyLoopFinished();
538 }
539 
LocalSocketServerAccept(LocalSocketServerManager * mgr,const LocalSocketMessageCallback & callback,const std::string & path)540 static void LocalSocketServerAccept(LocalSocketServerManager *mgr, const LocalSocketMessageCallback &callback,
541                                     const std::string &path)
542 {
543     struct sockaddr_un clientAddress;
544     socklen_t clientAddrLength = sizeof(clientAddress);
545     struct pollfd fds[1] = {{.fd = mgr->sockfd_, .events = POLLIN}};
546     nfds_t num = 1;
547     mgr->IncreaseThreadCounts();
548     while (true) {
549         int ret = poll(fds, num, DEFAULT_POLL_TIMEOUT_MS);
550         if (ret < 0) {
551             NETSTACK_LOGE("poll to accept failed, socket is %{public}d, errno is %{public}d", mgr->sockfd_, errno);
552             callback.OnError(errno);
553             break;
554         }
555         if (mgr->isServerDestruct_) {
556             NETSTACK_LOGI("server object destruction, loop finished");
557             break;
558         }
559         if (fds[0].revents & POLLIN) {
560             int connectFd = accept(mgr->sockfd_, reinterpret_cast<sockaddr *>(&clientAddress), &clientAddrLength);
561             if (connectFd < 0) {
562                 continue;
563             }
564             if (mgr->GetClientCounts() >= MAX_CLIENTS) {
565                 NETSTACK_LOGE("local socket server max number of clients reached, sockfd: %{public}d", mgr->sockfd_);
566                 close(connectFd);
567                 continue;
568             }
569             SetSocketDefaultBufferSize(connectFd, mgr);
570             if (!mgr->isServerDestruct_) {
571                 std::thread handlerThread(LocalSocketServerRecvHandler, connectFd, mgr, std::ref(callback),
572                                           std::ref(path));
573                 pthread_setname_np(LOCAL_SOCKET_SERVER_HANDLE_CLIENT);
574                 handlerThread.detach();
575             }
576         }
577     }
578 }
579 #else
RecvHandler(int connectFd,const LocalSocketMessageCallback & callback,LocalSocketServerManager * mgr)580 static void RecvHandler(int connectFd, const LocalSocketMessageCallback &callback, LocalSocketServerManager *mgr)
581 {
582     int clientId = mgr->GetClientId(connectFd);
583     EventManager *eventManager = mgr->GetManager(clientId);
584     if (eventManager == nullptr) {
585         NETSTACK_LOGI("manager is null");
586         callback.OnError(UNKNOW_ERROR);
587         return;
588     }
589     int sockRecvSize = ConfirmBufferSize(connectFd);
590     auto buffer = std::make_unique<char[]>(sockRecvSize);
591     if (buffer == nullptr) {
592         NETSTACK_LOGE("failed to malloc, connectFd: %{public}d, malloc size: %{public}d", connectFd, sockRecvSize);
593         RecvInErrorCondition(NO_MEMORY, clientId, callback, mgr);
594         return;
595     }
596     int32_t recvSize = recv(connectFd, buffer.get(), sockRecvSize, 0);
597     if (recvSize == 0) {
598         NETSTACK_LOGI("session closed, errno:%{public}d,fd:%{public}d,id:%{public}d", errno, connectFd, clientId);
599         callback.OnCloseMessage(eventManager);
600         mgr->RemoveAccept(clientId);
601     } else if (recvSize < 0) {
602         if (errno != EINTR && errno != EAGAIN) {
603             if (mgr->GetAcceptFd(clientId) < 0) {
604                 callback.OnCloseMessage(eventManager);
605                 return;
606             }
607             NETSTACK_LOGE("recv error, errno:%{public}d,fd:%{public}d,id:%{public}d", errno, connectFd, clientId);
608             RecvInErrorCondition(errno, clientId, callback, mgr);
609         }
610     } else {
611         NETSTACK_LOGI("recv, fd:%{public}d, size:%{public}d", connectFd, recvSize);
612         void *data = malloc(recvSize);
613         if (data == nullptr) {
614             RecvInErrorCondition(NO_MEMORY, clientId, callback, mgr);
615             return;
616         }
617         if (memcpy_s(data, recvSize, buffer.get(), recvSize) != EOK ||
618             !callback.OnMessage(eventManager, data, recvSize)) {
619             free(data);
620         }
621     }
622 }
623 
AcceptHandler(int fd,LocalSocketServerManager * mgr,const LocalSocketMessageCallback & callback)624 static void AcceptHandler(int fd, LocalSocketServerManager *mgr, const LocalSocketMessageCallback &callback)
625 {
626     pthread_setname_np(pthread_self(), LOCAL_SOCKET_SERVER_HANDLE_CLIENT);
627     if (fd < 0) {
628         NETSTACK_LOGE("accept a invalid fd");
629         return;
630     }
631     int clientId = mgr->AddAccept(fd);
632     if (clientId < 0) {
633         NETSTACK_LOGE("add connect fd err, fd:%{public}d", fd);
634         callback.OnError(UNKNOW_ERROR);
635         close(fd);
636         return;
637     }
638     callback.OnLocalSocketConnectionMessage(clientId, mgr);
639     mgr->WaitRegisteringEvent(clientId);
640     if (mgr->RegisterEpollEvent(fd, EPOLLIN) == -1) {
641         NETSTACK_LOGE("new connection register err, fd:%{public}d, errno:%{public}d", fd, errno);
642         callback.OnError(errno);
643         close(fd);
644         return;
645     }
646     SetSocketDefaultBufferSize(fd, mgr);
647     if (mgr->alreadySetExtraOptions_) {
648         SetLocalSocketOptions(fd, mgr->extraOptions_);
649     }
650 }
651 
LocalSocketServerAccept(LocalSocketServerManager * mgr,const LocalSocketMessageCallback & callback)652 static void LocalSocketServerAccept(LocalSocketServerManager *mgr, const LocalSocketMessageCallback &callback)
653 {
654     pthread_setname_np(pthread_self(), LOCAL_SOCKET_SERVER_ACCEPT_RECV_DATA);
655     struct sockaddr_un clientAddress;
656     socklen_t clientAddrLength = sizeof(clientAddress);
657     if (mgr->RegisterEpollEvent(mgr->sockfd_, EPOLLIN) == -1) {
658         NETSTACK_LOGE("register listen fd err, fd:%{public}d, errno:%{public}d", mgr->sockfd_, errno);
659         callback.OnError(errno);
660         return;
661     }
662     mgr->SetServerDestructStatus(false);
663     while (true) {
664         int eventNum = mgr->EpollWait();
665         if (eventNum == -1) {
666             if (errno == EINTR) {
667                 continue;
668             }
669             NETSTACK_LOGE("epoll wait err, fd:%{public}d, errno:%{public}d", mgr->sockfd_, errno);
670             callback.OnError(errno);
671             break;
672         }
673         if (mgr->GetServerDestructStatus()) {
674             NETSTACK_LOGI("server object destruct, exit the loop");
675             break;
676         }
677         for (int i = 0; i < eventNum; ++i) {
678             if ((mgr->events_[i].data.fd == mgr->sockfd_) && (mgr->events_[i].events & EPOLLIN)) {
679                 int connectFd = accept(mgr->sockfd_, reinterpret_cast<sockaddr *>(&clientAddress), &clientAddrLength);
680                 std::thread th(AcceptHandler, connectFd, mgr, callback);
681                 th.detach();
682             } else if ((mgr->events_[i].data.fd != mgr->sockfd_) && (mgr->events_[i].events & EPOLLIN)) {
683                 RecvHandler(mgr->events_[i].data.fd, callback, mgr);
684             }
685         }
686     }
687     mgr->NotifyLoopFinished();
688 }
689 #endif
690 
UpdateRecvBuffer(int sock,int & bufferSize,std::unique_ptr<char[]> & buf,const LocalSocketMessageCallback & callback)691 static int UpdateRecvBuffer(int sock, int &bufferSize, std::unique_ptr<char[]> &buf,
692                             const LocalSocketMessageCallback &callback)
693 {
694     if (int currentRecvBufferSize = ConfirmBufferSize(sock); currentRecvBufferSize != bufferSize) {
695         bufferSize = currentRecvBufferSize;
696         if (bufferSize <= 0 || bufferSize > MAX_SOCKET_BUFFER_SIZE) {
697             NETSTACK_LOGE("buffer size is out of range, size: %{public}d", bufferSize);
698             bufferSize = DEFAULT_BUFFER_SIZE;
699         }
700         buf.reset(new (std::nothrow) char[bufferSize]);
701         if (buf == nullptr) {
702             callback.OnError(NO_MEMORY);
703             return NO_MEMORY;
704         }
705     }
706     return 0;
707 }
708 
PollRecvData(int sock,const LocalSocketMessageCallback & callback)709 static void PollRecvData(int sock, const LocalSocketMessageCallback &callback)
710 {
711     int bufferSize = ConfirmBufferSize(sock);
712     auto buf = std::make_unique<char[]>(bufferSize);
713     if (buf == nullptr) {
714         callback.OnError(NO_MEMORY);
715         return;
716     }
717     nfds_t num = 1;
718     pollfd fds[1] = {{.fd = sock, .events = POLLIN}};
719     int recvTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_RCVTIMEO, DEFAULT_POLL_TIMEOUT_MS);
720     while (true) {
721         int ret = poll(fds, num, recvTimeoutMs);
722         if (ret < 0) {
723             NETSTACK_LOGE("poll to recv failed, socket is %{public}d, errno is %{public}d", sock, errno);
724             callback.OnError(errno);
725             return;
726         } else if (ret == 0) {
727             continue;
728         }
729         if (memset_s(buf.get(), bufferSize, 0, bufferSize) != EOK) {
730             NETSTACK_LOGE("memset_s failed, client fd: %{public}d, bufferSize: %{public}d", sock, bufferSize);
731             continue;
732         }
733         if (UpdateRecvBuffer(sock, bufferSize, buf, callback) < 0) {
734             return;
735         }
736         auto recvLen = recv(sock, buf.get(), bufferSize, 0);
737         if (recvLen < 0) {
738             if (errno == EAGAIN || errno == EINTR) {
739                 continue;
740             }
741             NETSTACK_LOGE("recv failed, socket is %{public}d, errno is %{public}d", sock, errno);
742             if (auto mgr = reinterpret_cast<LocalSocketManager *>(callback.manager_->GetData()); mgr != nullptr) {
743                 mgr->GetSocketCloseStatus() ? callback.OnCloseMessage() : callback.OnError(errno);
744             }
745             return;
746         } else if (recvLen == 0) {
747             callback.OnCloseMessage();
748             break;
749         }
750         void *data = malloc(recvLen);
751         if (data == nullptr) {
752             callback.OnError(NO_MEMORY);
753             return;
754         }
755         if (memcpy_s(data, recvLen, buf.get(), recvLen) != EOK || !callback.OnMessage(data, recvLen)) {
756             free(data);
757         }
758     }
759 }
760 
ExecLocalSocketBind(LocalSocketBindContext * context)761 bool ExecLocalSocketBind(LocalSocketBindContext *context)
762 {
763     if (context == nullptr) {
764         return false;
765     }
766     struct sockaddr_un addr;
767     addr.sun_family = AF_UNIX;
768     if (strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, context->GetSocketPath().c_str()) != 0) {
769         NETSTACK_LOGE("failed to copy socket path, sockfd: %{public}d", context->GetSocketFd());
770         context->SetErrorCode(UNKNOW_ERROR);
771         return false;
772     }
773     if (bind(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)) == -1) {
774         NETSTACK_LOGE("failed to bind local socket, errno: %{public}d", errno);
775         context->SetErrorCode(errno);
776         return false;
777     }
778     return true;
779 }
780 
NonBlockConnect(int sock,sockaddr * addr,socklen_t addrLen,uint32_t timeoutMSec)781 static bool NonBlockConnect(int sock, sockaddr *addr, socklen_t addrLen, uint32_t timeoutMSec)
782 {
783     if (connect(sock, addr, addrLen) == -1) {
784         pollfd fds[1] = {{.fd = sock, .events = POLLOUT}};
785         if (errno != EINPROGRESS) {
786             NETSTACK_LOGE("connect error, fd: %{public}d, errno: %{public}d", sock, errno);
787             return false;
788         }
789         int pollResult = poll(fds, 1, timeoutMSec);
790         if (pollResult == 0) {
791             NETSTACK_LOGE("connection timeout, fd: %{public}d, timeout: %{public}d", sock, timeoutMSec);
792             return false;
793         } else if (pollResult == -1) {
794             NETSTACK_LOGE("poll connect error, fd: %{public}d, errno: %{public}d", sock, errno);
795             return false;
796         }
797         int error = 0;
798         socklen_t errorLen = sizeof(error);
799         if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &errorLen) < 0 || error != 0) {
800             NETSTACK_LOGE("failed to get socket so_error, fd: %{public}d, errno: %{public}d", sock, errno);
801             return false;
802         }
803     }
804     return true;
805 }
806 
ExecLocalSocketConnect(LocalSocketConnectContext * context)807 bool ExecLocalSocketConnect(LocalSocketConnectContext *context)
808 {
809     if (context == nullptr) {
810         return false;
811     }
812     struct sockaddr_un addr;
813     memset_s(&addr, sizeof(addr), 0, sizeof(addr));
814     addr.sun_family = AF_UNIX;
815     int sockfd = context->GetSocketFd();
816     SetSocketBufferSize(sockfd, SO_RCVBUF, DEFAULT_BUFFER_SIZE);
817     if (strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, context->GetSocketPath().c_str()) != 0) {
818         NETSTACK_LOGE("failed to copy local socket path, sockfd: %{public}d", sockfd);
819         context->SetErrorCode(UNKNOW_ERROR);
820         return false;
821     }
822     NETSTACK_LOGI("local socket client fd: %{public}d", context->GetSocketFd());
823     if (!NonBlockConnect(sockfd, reinterpret_cast<sockaddr *>(&addr), sizeof(addr), context->GetTimeoutMs())) {
824         NETSTACK_LOGE("failed to connect local socket, errno: %{public}d, %{public}s", errno, strerror(errno));
825         context->SetErrorCode(errno);
826         return false;
827     }
828     if (auto pMgr = reinterpret_cast<LocalSocketManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
829         pMgr->isConnected_ = true;
830     }
831     std::thread serviceThread(PollRecvData, sockfd, LocalSocketMessageCallback(context->GetManager(), context->
832                               GetSocketPath()));
833 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
834     pthread_setname_np(LOCAL_SOCKET_CONNECT);
835 #else
836     pthread_setname_np(serviceThread.native_handle(), LOCAL_SOCKET_CONNECT);
837 #endif
838     serviceThread.detach();
839     return true;
840 }
841 
ExecLocalSocketSend(LocalSocketSendContext * context)842 bool ExecLocalSocketSend(LocalSocketSendContext *context)
843 {
844     if (context == nullptr) {
845         return false;
846     }
847 #ifdef FUZZ_TEST
848     return true;
849 #endif
850     if (context->GetSocketFd() < 0) {
851         context->SetErrorCode(EBADF);
852     }
853     bool result = LocalSocketSendEvent(context);
854     NapiUtils::CreateUvQueueWorkEnhanced(context->GetEnv(), context, SocketAsyncWork::LocalSocketSendCallback);
855     return result;
856 }
857 
ExecLocalSocketClose(LocalSocketCloseContext * context)858 bool ExecLocalSocketClose(LocalSocketCloseContext *context)
859 {
860     if (context == nullptr) {
861         return false;
862     }
863     if (close(context->GetSocketFd()) < 0) {
864         NETSTACK_LOGE("failed to closed localsock, fd: %{public}d, errno: %{public}d", context->GetSocketFd(), errno);
865         context->SetErrorCode(errno);
866         return false;
867     }
868     context->SetSocketFd(-1);
869     if (auto pMgr = reinterpret_cast<LocalSocketManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
870         pMgr->isConnected_ = false;
871         pMgr->SetSocketCloseStatus(true);
872     }
873     return true;
874 }
875 
ExecLocalSocketGetState(LocalSocketGetStateContext * context)876 bool ExecLocalSocketGetState(LocalSocketGetStateContext *context)
877 {
878     if (context == nullptr) {
879         return false;
880     }
881     struct sockaddr_un unAddr = {0};
882     socklen_t len = sizeof(unAddr);
883     SocketStateBase &state = context->GetStateRef();
884     if (getsockname(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&unAddr), &len) < 0) {
885         NETSTACK_LOGI("local socket do not bind or socket has closed");
886         state.SetIsBound(false);
887     } else {
888         state.SetIsBound(strlen(unAddr.sun_path) > 0);
889     }
890     if (auto pMgr = reinterpret_cast<LocalSocketManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
891         state.SetIsConnected(pMgr->isConnected_);
892     }
893     return true;
894 }
895 
ExecLocalSocketGetLocalAddress(LocalSocketGetLocalAddressContext * context)896 bool ExecLocalSocketGetLocalAddress(LocalSocketGetLocalAddressContext *context)
897 {
898     if (context == nullptr) {
899         NETSTACK_LOGE("context is nullptr");
900         return false;
901     }
902     struct sockaddr_un unAddr = {0};
903     socklen_t len = sizeof(unAddr);
904     if (getsockname(context->GetSocketFd(), (struct sockaddr *)&unAddr, &len) == 0) {
905         context->SetSocketPath(unAddr.sun_path);
906         return true;
907     } else {
908         NETSTACK_LOGE("local socket get socket name fail");
909         context->SetNeedThrowException(true);
910         context->SetErrorCode(errno);
911         return false;
912     }
913 }
914 
ExecLocalSocketGetSocketFd(LocalSocketGetSocketFdContext * context)915 bool ExecLocalSocketGetSocketFd(LocalSocketGetSocketFdContext *context)
916 {
917     if (context == nullptr) {
918         return false;
919     }
920     return true;
921 }
922 
ExecLocalSocketSetExtraOptions(LocalSocketSetExtraOptionsContext * context)923 bool ExecLocalSocketSetExtraOptions(LocalSocketSetExtraOptionsContext *context)
924 {
925     if (context == nullptr) {
926         return false;
927     }
928     if (SetLocalSocketOptions(context->GetSocketFd(), context->GetOptionsRef())) {
929         return true;
930     }
931     context->SetErrorCode(errno);
932     return false;
933 }
934 
GetLocalSocketOptions(int sockfd,LocalExtraOptions & optionsRef)935 static bool GetLocalSocketOptions(int sockfd, LocalExtraOptions &optionsRef)
936 {
937     int result = 0;
938     socklen_t len = sizeof(result);
939     if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &result, &len) == -1) {
940         NETSTACK_LOGE("getsockopt error, SO_RCVBUF");
941         return false;
942     }
943     optionsRef.SetReceiveBufferSize(result);
944     if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &result, &len) == -1) {
945         NETSTACK_LOGE("getsockopt error, SO_SNDBUF");
946         return false;
947     }
948     optionsRef.SetSendBufferSize(result);
949     timeval timeout;
950     socklen_t timeLen = sizeof(timeout);
951     if (getsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, &timeLen) == -1) {
952         NETSTACK_LOGE("getsockopt error, SO_SNDTIMEO");
953         return false;
954     }
955     optionsRef.SetSocketTimeout(timeout.tv_sec * UNIT_CONVERSION_1000 + timeout.tv_usec / UNIT_CONVERSION_1000);
956     return true;
957 }
958 
ExecLocalSocketGetExtraOptions(LocalSocketGetExtraOptionsContext * context)959 bool ExecLocalSocketGetExtraOptions(LocalSocketGetExtraOptionsContext *context)
960 {
961     if (context == nullptr) {
962         return false;
963     }
964     LocalExtraOptions &optionsRef = context->GetOptionsRef();
965     if (!GetLocalSocketOptions(context->GetSocketFd(), optionsRef)) {
966         context->SetErrorCode(errno);
967         return false;
968     }
969     return true;
970 }
971 
LocalSocketServerBind(LocalSocketServerListenContext * context)972 static bool LocalSocketServerBind(LocalSocketServerListenContext *context)
973 {
974     unlink(context->GetSocketPath().c_str());
975     struct sockaddr_un addr;
976     addr.sun_family = AF_UNIX;
977     if (int err = strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, context->GetSocketPath().c_str()); err != 0) {
978         NETSTACK_LOGE("failed to copy socket path");
979         context->SetErrorCode(err);
980         return false;
981     }
982     if (bind(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)) == -1) {
983         NETSTACK_LOGE("failed to bind local socket, fd: %{public}d, errno: %{public}d", context->GetSocketFd(), errno);
984         context->SetErrorCode(errno);
985         return false;
986     }
987     NETSTACK_LOGI("local socket server bind success");
988     return true;
989 }
990 
ExecLocalSocketServerListen(LocalSocketServerListenContext * context)991 bool ExecLocalSocketServerListen(LocalSocketServerListenContext *context)
992 {
993     if (context == nullptr) {
994         return false;
995     }
996     if (!LocalSocketServerBind(context)) {
997         return false;
998     }
999     if (listen(context->GetSocketFd(), BACKLOG) < 0) {
1000         NETSTACK_LOGE("local socket server listen error, fd: %{public}d", context->GetSocketFd());
1001         context->SetErrorCode(errno);
1002         return false;
1003     }
1004     NETSTACK_LOGI("local socket server listen success");
1005     LocalSocketServerManager *mgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
1006     if (mgr == nullptr) {
1007         NETSTACK_LOGE("LocalSocketServerManager reinterpret cast failed");
1008         context->SetErrorCode(UNKNOW_ERROR);
1009         return false;
1010     }
1011 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
1012     std::thread serviceThread(LocalSocketServerAccept, mgr, LocalSocketMessageCallback(context->GetManager()),
1013                                                                                        context->GetSocketPath());
1014     pthread_setname_np(LOCAL_SOCKET_SERVER_ACCEPT_RECV_DATA);
1015 #else
1016     std::thread serviceThread(LocalSocketServerAccept, mgr, LocalSocketMessageCallback(context->GetManager(),
1017                                                                                        context->GetSocketPath()));
1018 #endif
1019     serviceThread.detach();
1020     return true;
1021 }
1022 
ExecLocalSocketServerEnd(LocalSocketServerEndContext * context)1023 bool ExecLocalSocketServerEnd(LocalSocketServerEndContext *context)
1024 {
1025     if (context == nullptr || context->GetManager() == nullptr) {
1026         return false;
1027     }
1028     LocalSocketServerManager *mgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
1029     if (mgr == nullptr) {
1030         NETSTACK_LOGE("LocalSocketServerManager reinterpret cast failed");
1031         context->SetErrorCode(UNKNOW_ERROR);
1032         return false;
1033     }
1034     mgr->SetServerDestructStatus(true);
1035     mgr->RemoveAllAccept();
1036     mgr->RemoveAllEventManager();
1037     if (mgr->sockfd_ > 0) {
1038         close(mgr->sockfd_);
1039         mgr->sockfd_ = -1;
1040     }
1041     if (mgr->epollFd_ > 0) {
1042         close(mgr->epollFd_);
1043         mgr->epollFd_ = -1;
1044     }
1045     mgr->WaitForEndingLoop();
1046     delete mgr;
1047     context->GetManager()->SetData(nullptr);
1048     return true;
1049 }
1050 
ExecLocalSocketServerGetState(LocalSocketServerGetStateContext * context)1051 bool ExecLocalSocketServerGetState(LocalSocketServerGetStateContext *context)
1052 {
1053     if (context == nullptr) {
1054         return false;
1055     }
1056     struct sockaddr_un unAddr = {0};
1057     socklen_t len = sizeof(unAddr);
1058     SocketStateBase &state = context->GetStateRef();
1059     if (getsockname(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&unAddr), &len) == 0) {
1060         state.SetIsBound(true);
1061     }
1062     auto pMgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
1063     if (pMgr != nullptr) {
1064         state.SetIsConnected(pMgr->GetClientCounts() > 0);
1065     }
1066     return true;
1067 }
1068 
ExecLocalSocketServerGetLocalAddress(LocalSocketServerGetLocalAddressContext * context)1069 bool ExecLocalSocketServerGetLocalAddress(LocalSocketServerGetLocalAddressContext *context)
1070 {
1071     if (context == nullptr) {
1072         NETSTACK_LOGE("context is nullptr");
1073         return false;
1074     }
1075     struct sockaddr_un unAddr = {0};
1076     socklen_t len = sizeof(unAddr);
1077     if (getsockname(context->GetSocketFd(), (struct sockaddr *)&unAddr, &len) == 0) {
1078         context->SetSocketPath(unAddr.sun_path);
1079         return true;
1080     } else {
1081         NETSTACK_LOGE("local socket get socket name fail");
1082         context->SetNeedThrowException(true);
1083         context->SetErrorCode(errno);
1084         return false;
1085     }
1086 }
1087 
ExecLocalSocketServerSetExtraOptions(LocalSocketServerSetExtraOptionsContext * context)1088 bool ExecLocalSocketServerSetExtraOptions(LocalSocketServerSetExtraOptionsContext *context)
1089 {
1090     if (context == nullptr) {
1091         return false;
1092     }
1093     auto serverManager = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
1094     if (serverManager == nullptr) {
1095         return false;
1096     }
1097     for (const auto &[id, fd] : serverManager->acceptFds_) {
1098         if (!SetLocalSocketOptions(fd, context->GetOptionsRef())) {
1099             context->SetErrorCode(errno);
1100             return false;
1101         }
1102     }
1103     serverManager->extraOptions_ = context->GetOptionsRef();
1104     serverManager->alreadySetExtraOptions_ = true;
1105     return true;
1106 }
1107 
ExecLocalSocketServerGetExtraOptions(LocalSocketServerGetExtraOptionsContext * context)1108 bool ExecLocalSocketServerGetExtraOptions(LocalSocketServerGetExtraOptionsContext *context)
1109 {
1110     if (context == nullptr) {
1111         return false;
1112     }
1113     if (auto pMgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
1114         LocalExtraOptions &options = context->GetOptionsRef();
1115         if (pMgr->alreadySetExtraOptions_) {
1116             options = pMgr->extraOptions_;
1117         } else {
1118             if (!GetLocalSocketOptions(context->GetSocketFd(), options)) {
1119                 context->SetErrorCode(errno);
1120                 return false;
1121             }
1122             options.SetReceiveBufferSize(DEFAULT_BUFFER_SIZE);
1123             options.SetSendBufferSize(DEFAULT_BUFFER_SIZE);
1124         }
1125         return true;
1126     }
1127     context->SetErrorCode(UNKNOW_ERROR);
1128     return false;
1129 }
1130 
ExecLocalSocketConnectionSend(LocalSocketServerSendContext * context)1131 bool ExecLocalSocketConnectionSend(LocalSocketServerSendContext *context)
1132 {
1133     if (context == nullptr) {
1134         return false;
1135     }
1136     int clientId = context->GetClientId();
1137     auto data = reinterpret_cast<LocalSocketConnectionData *>(context->GetManager()->GetData());
1138     if (data == nullptr || data->serverManager_ == nullptr) {
1139         NETSTACK_LOGE("localsocket connection send, data or manager is nullptr, id: %{public}d", clientId);
1140         return false;
1141     }
1142     int acceptFd = data->serverManager_->GetAcceptFd(clientId);
1143     if (acceptFd <= 0) {
1144         NETSTACK_LOGE("accept fd is invalid, id: %{public}d, fd: %{public}d", clientId, acceptFd);
1145         context->SetErrorCode(ERRNO_BAD_FD);
1146         return false;
1147     }
1148 
1149     if (!PollSendData(acceptFd, context->GetOptionsRef().GetBufferRef().c_str(),
1150                       context->GetOptionsRef().GetBufferRef().size(), nullptr, 0)) {
1151         NETSTACK_LOGE("localsocket connection send failed, fd: %{public}d, errno: %{public}d", acceptFd, errno);
1152         context->SetErrorCode(errno);
1153         return false;
1154     }
1155     return true;
1156 }
1157 
ExecLocalSocketConnectionClose(LocalSocketServerCloseContext * context)1158 bool ExecLocalSocketConnectionClose(LocalSocketServerCloseContext *context)
1159 {
1160     if (context == nullptr) {
1161         return false;
1162     }
1163     auto data = reinterpret_cast<LocalSocketConnectionData *>(context->GetManager()->GetData());
1164     if (data == nullptr || data->serverManager_ == nullptr) {
1165         NETSTACK_LOGE("connection close callback reinterpret cast failed");
1166         return false;
1167     }
1168     int acceptFd = data->serverManager_->GetAcceptFd(context->GetClientId());
1169     if (acceptFd <= 0) {
1170         NETSTACK_LOGE("socket invalid, fd: %{public}d", acceptFd);
1171         context->SetErrorCode(EBADF);
1172         return false;
1173     }
1174 
1175     if (shutdown(acceptFd, SHUT_RDWR) != 0) {
1176         NETSTACK_LOGE("socket shutdown failed, socket is %{public}d, errno is %{public}d", acceptFd, errno);
1177     }
1178     int ret = close(acceptFd);
1179     if (ret < 0) {
1180         NETSTACK_LOGE("sock closed failed, socket is %{public}d, errno is %{public}d", acceptFd, errno);
1181     } else {
1182         NETSTACK_LOGI("sock %{public}d closed success", acceptFd);
1183         data->serverManager_->RemoveAccept(context->GetClientId());
1184     }
1185     return true;
1186 }
1187 
ExecLocalSocketConnectionGetLocalAddress(LocalSocketServerGetLocalAddressContext * context)1188 bool ExecLocalSocketConnectionGetLocalAddress(LocalSocketServerGetLocalAddressContext *context)
1189 {
1190     if (context == nullptr) {
1191         NETSTACK_LOGE("context is nullptr");
1192         return false;
1193     }
1194     int socketFD = -1;
1195     if (auto data = reinterpret_cast<LocalSocketConnectionData *>(context->GetManager()->GetData()); data != nullptr) {
1196         if (data->serverManager_ == nullptr) {
1197             NETSTACK_LOGE("invalid serverManager or socket has closed");
1198             context->SetNeedThrowException(true);
1199             context->SetErrorCode(EBADF);
1200             return false;
1201         }
1202         socketFD = data->serverManager_->GetAcceptFd(context->GetClientId());
1203         if (socketFD > 0) {
1204             struct sockaddr_un addr;
1205             socklen_t addrLen = sizeof(addr);
1206             if (getsockname(socketFD, reinterpret_cast<struct sockaddr *>(&addr), &addrLen) == 0) {
1207                 context->SetSocketPath(addr.sun_path);
1208                 return true;
1209             } else {
1210                 NETSTACK_LOGE("local accept socket get socket name fail");
1211                 context->SetNeedThrowException(true);
1212                 context->SetErrorCode(errno);
1213                 return false;
1214             }
1215         }
1216     }
1217     NETSTACK_LOGE("invalid serverManager or socket has closed");
1218     context->SetNeedThrowException(true);
1219     context->SetErrorCode(EBADF);
1220     return false;
1221 }
1222 
LocalSocketBindCallback(LocalSocketBindContext * context)1223 napi_value LocalSocketBindCallback(LocalSocketBindContext *context)
1224 {
1225     return NapiUtils::GetUndefined(context->GetEnv());
1226 }
1227 
LocalSocketConnectCallback(LocalSocketConnectContext * context)1228 napi_value LocalSocketConnectCallback(LocalSocketConnectContext *context)
1229 {
1230     context->Emit(EVENT_CONNECT, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1231                                                 NapiUtils::GetUndefined(context->GetEnv())));
1232     return NapiUtils::GetUndefined(context->GetEnv());
1233 }
1234 
LocalSocketSendCallback(LocalSocketSendContext * context)1235 napi_value LocalSocketSendCallback(LocalSocketSendContext *context)
1236 {
1237     return NapiUtils::GetUndefined(context->GetEnv());
1238 }
1239 
LocalSocketCloseCallback(LocalSocketCloseContext * context)1240 napi_value LocalSocketCloseCallback(LocalSocketCloseContext *context)
1241 {
1242     auto manager = context->GetManager();
1243     if (manager != nullptr) {
1244         NETSTACK_LOGD("local socket close, delete js ref");
1245         manager->DeleteEventReference(context->GetEnv());
1246     }
1247     return NapiUtils::GetUndefined(context->GetEnv());
1248 }
1249 
LocalSocketGetStateCallback(LocalSocketGetStateContext * context)1250 napi_value LocalSocketGetStateCallback(LocalSocketGetStateContext *context)
1251 {
1252     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1253     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1254         return NapiUtils::GetUndefined(context->GetEnv());
1255     }
1256     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->GetStateRef().IsBound());
1257     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->GetStateRef().IsClose());
1258     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->GetStateRef().IsConnected());
1259     return obj;
1260 }
1261 
LocalSocketGetLocalAddressCallback(LocalSocketGetLocalAddressContext * context)1262 napi_value LocalSocketGetLocalAddressCallback(LocalSocketGetLocalAddressContext *context)
1263 {
1264     auto path = context->GetSocketPath();
1265     auto strRes = NapiUtils::CreateStringUtf8(context->GetEnv(), path);
1266     if (NapiUtils::GetValueType(context->GetEnv(), strRes) != napi_string) {
1267         return NapiUtils::GetUndefined(context->GetEnv());
1268     }
1269     return strRes;
1270 }
1271 
LocalSocketGetSocketFdCallback(LocalSocketGetSocketFdContext * context)1272 napi_value LocalSocketGetSocketFdCallback(LocalSocketGetSocketFdContext *context)
1273 {
1274     int sockFd = context->GetSocketFd();
1275     if (sockFd <= 0) {
1276         return NapiUtils::GetUndefined(context->GetEnv());
1277     }
1278     return NapiUtils::CreateUint32(context->GetEnv(), sockFd);
1279 }
1280 
LocalSocketSetExtraOptionsCallback(LocalSocketSetExtraOptionsContext * context)1281 napi_value LocalSocketSetExtraOptionsCallback(LocalSocketSetExtraOptionsContext *context)
1282 {
1283     return NapiUtils::GetUndefined(context->GetEnv());
1284 }
1285 
LocalSocketGetExtraOptionsCallback(LocalSocketGetExtraOptionsContext * context)1286 napi_value LocalSocketGetExtraOptionsCallback(LocalSocketGetExtraOptionsContext *context)
1287 {
1288     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1289     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1290         return NapiUtils::GetUndefined(context->GetEnv());
1291     }
1292     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_REUSE_ADDRESS, false);
1293     NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_RECEIVE_BUFFER_SIZE,
1294                                 context->GetOptionsRef().GetReceiveBufferSize());
1295     NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_SEND_BUFFER_SIZE,
1296                                 context->GetOptionsRef().GetSendBufferSize());
1297     NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_TIMEOUT, context->GetOptionsRef().GetSocketTimeout());
1298     return obj;
1299 }
1300 
LocalSocketServerListenCallback(LocalSocketServerListenContext * context)1301 napi_value LocalSocketServerListenCallback(LocalSocketServerListenContext *context)
1302 {
1303     context->Emit(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1304                                                   NapiUtils::GetUndefined(context->GetEnv())));
1305     return NapiUtils::GetUndefined(context->GetEnv());
1306 }
1307 
LocalSocketServerEndCallback(LocalSocketServerEndContext * context)1308 napi_value LocalSocketServerEndCallback(LocalSocketServerEndContext *context)
1309 {
1310     return NapiUtils::GetUndefined(context->GetEnv());
1311 }
1312 
LocalSocketServerGetStateCallback(LocalSocketServerGetStateContext * context)1313 napi_value LocalSocketServerGetStateCallback(LocalSocketServerGetStateContext *context)
1314 {
1315     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1316     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1317         return NapiUtils::GetUndefined(context->GetEnv());
1318     }
1319     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->GetStateRef().IsBound());
1320     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->GetStateRef().IsClose());
1321     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->GetStateRef().IsConnected());
1322     return obj;
1323 }
1324 
LocalSocketServerGetLocalAddressCallback(LocalSocketServerGetLocalAddressContext * context)1325 napi_value LocalSocketServerGetLocalAddressCallback(LocalSocketServerGetLocalAddressContext *context)
1326 {
1327     auto path = context->GetSocketPath();
1328     auto strRes = NapiUtils::CreateStringUtf8(context->GetEnv(), path);
1329     if (NapiUtils::GetValueType(context->GetEnv(), strRes) != napi_string) {
1330         return NapiUtils::GetUndefined(context->GetEnv());
1331     }
1332     return strRes;
1333 }
1334 
LocalSocketServerSetExtraOptionsCallback(LocalSocketServerSetExtraOptionsContext * context)1335 napi_value LocalSocketServerSetExtraOptionsCallback(LocalSocketServerSetExtraOptionsContext *context)
1336 {
1337     return NapiUtils::GetUndefined(context->GetEnv());
1338 }
1339 
LocalSocketServerGetExtraOptionsCallback(LocalSocketServerGetExtraOptionsContext * context)1340 napi_value LocalSocketServerGetExtraOptionsCallback(LocalSocketServerGetExtraOptionsContext *context)
1341 {
1342     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1343     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1344         return NapiUtils::GetUndefined(context->GetEnv());
1345     }
1346     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_REUSE_ADDRESS, false);
1347     NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_RECEIVE_BUFFER_SIZE,
1348                                 context->GetOptionsRef().GetReceiveBufferSize());
1349     NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_SEND_BUFFER_SIZE,
1350                                 context->GetOptionsRef().GetSendBufferSize());
1351     NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_TIMEOUT, context->GetOptionsRef().GetSocketTimeout());
1352     return obj;
1353 }
1354 
LocalSocketConnectionSendCallback(LocalSocketServerSendContext * context)1355 napi_value LocalSocketConnectionSendCallback(LocalSocketServerSendContext *context)
1356 {
1357     return NapiUtils::GetUndefined(context->GetEnv());
1358 }
1359 
LocalSocketConnectionCloseCallback(LocalSocketServerCloseContext * context)1360 napi_value LocalSocketConnectionCloseCallback(LocalSocketServerCloseContext *context)
1361 {
1362     auto manager = context->GetManager();
1363     if (manager != nullptr) {
1364         NETSTACK_LOGD("local socket connection close, delete js ref");
1365         manager->DeleteEventReference(context->GetEnv());
1366     }
1367     return NapiUtils::GetUndefined(context->GetEnv());
1368 }
1369 
LocalSocketConnectionGetLocalAddressCallback(LocalSocketServerGetLocalAddressContext * context)1370 napi_value LocalSocketConnectionGetLocalAddressCallback(LocalSocketServerGetLocalAddressContext *context)
1371 {
1372     auto path = context->GetSocketPath();
1373     auto strRes = NapiUtils::CreateStringUtf8(context->GetEnv(), path);
1374     if (NapiUtils::GetValueType(context->GetEnv(), strRes) != napi_string) {
1375         return NapiUtils::GetUndefined(context->GetEnv());
1376     }
1377     return strRes;
1378 }
1379 } // namespace OHOS::NetStack::Socket::LocalSocketExec
1380