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