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