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