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