1 /*
2 * Copyright (c) 2023 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 namespace {
34 constexpr int BACKLOG = 32;
35
36 constexpr int DEFAULT_BUFFER_SIZE = 8192;
37
38 constexpr int MAX_SOCKET_BUFFER_SIZE = 212992;
39
40 constexpr int DEFAULT_POLL_TIMEOUT_MS = 500;
41
42 constexpr int UNKNOW_ERROR = -1;
43
44 constexpr int NO_MEMORY = -2;
45
46 constexpr int MAX_CLIENTS = 1024;
47
48 constexpr int ERRNO_BAD_FD = 9;
49
50 constexpr int DEFAULT_TIMEOUT_MS = 20000;
51
52 constexpr int UNIT_CONVERSION_1000 = 1000; // multiples of conversion between units
53
54 constexpr int SOCKET_SIZE_CONVERSION = 2; // socket buffer size, the actual value is twice the set value
55
56 constexpr char LOCAL_SOCKET_CONNECTION[] = "LocalSocketConnection";
57
58 constexpr char LOCAL_SOCKET_SERVER_HANDLE_CLIENT[] = "LocalSocketServerHandleClient";
59
60 constexpr char LOCAL_SOCKET_SERVER_ACCEPT_RECV_DATA[] = "LocalSocketServerAcceptRecvData";
61 } // namespace
62
63 namespace OHOS::NetStack::Socket::LocalSocketExec {
64 struct MsgWithLocalRemoteInfo {
65 MsgWithLocalRemoteInfo() = delete;
MsgWithLocalRemoteInfoOHOS::NetStack::Socket::LocalSocketExec::MsgWithLocalRemoteInfo66 MsgWithLocalRemoteInfo(void *d, size_t length, const std::string &path) : data(d), len(length)
67 {
68 remoteInfo.SetAddress(path);
69 }
~MsgWithLocalRemoteInfoOHOS::NetStack::Socket::LocalSocketExec::MsgWithLocalRemoteInfo70 ~MsgWithLocalRemoteInfo()
71 {
72 if (data) {
73 free(data);
74 }
75 }
76 void *data = nullptr;
77 size_t len = 0;
78 LocalSocketRemoteInfo remoteInfo;
79 };
80
LocalSocketServerConnectionFinalize(napi_env,void * data,void *)81 void LocalSocketServerConnectionFinalize(napi_env, void *data, void *)
82 {
83 NETSTACK_LOGI("localsocket connection is finalized");
84 EventManager *manager = reinterpret_cast<EventManager *>(data);
85 if (manager != nullptr) {
86 LocalSocketConnectionData *connectData = reinterpret_cast<LocalSocketConnectionData *>(manager->GetData());
87 if (connectData != nullptr) {
88 connectData->serverManager_->RemoveEventManager(connectData->clientId_);
89 connectData->serverManager_->RemoveAccept(connectData->clientId_);
90 delete connectData;
91 }
92 }
93 }
94
NewInstanceWithConstructor(napi_env env,napi_callback_info info,napi_value jsConstructor,LocalSocketConnectionData * data)95 napi_value NewInstanceWithConstructor(napi_env env, napi_callback_info info, napi_value jsConstructor,
96 LocalSocketConnectionData *data)
97 {
98 napi_value result = nullptr;
99 NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
100
101 EventManager *manager = new (std::nothrow) EventManager();
102 if (manager == nullptr) {
103 return result;
104 }
105 manager->SetData(reinterpret_cast<void *>(data));
106 EventManager::SetValid(manager);
107 data->serverManager_->AddEventManager(data->clientId_, manager);
108 napi_wrap(env, result, reinterpret_cast<void *>(manager), LocalSocketServerConnectionFinalize, nullptr, nullptr);
109 return result;
110 }
111
ConstructLocalSocketConnection(napi_env env,napi_callback_info info,LocalSocketConnectionData * data)112 napi_value ConstructLocalSocketConnection(napi_env env, napi_callback_info info, LocalSocketConnectionData *data)
113 {
114 std::initializer_list<napi_property_descriptor> properties = {
115 DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_SEND,
116 SocketModuleExports::LocalSocketConnection::Send),
117 DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_CLOSE,
118 SocketModuleExports::LocalSocketConnection::Close),
119 DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_ON,
120 SocketModuleExports::LocalSocketConnection::On),
121 DECLARE_NAPI_FUNCTION(SocketModuleExports::LocalSocketConnection::FUNCTION_OFF,
122 SocketModuleExports::LocalSocketConnection::Off),
123 };
124
125 auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
126 napi_value thisVal = nullptr;
127 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
128 return thisVal;
129 };
130
131 napi_property_descriptor descriptors[properties.size()];
132 std::copy(properties.begin(), properties.end(), descriptors);
133
134 napi_value jsConstructor = nullptr;
135 NAPI_CALL_BASE(env,
136 napi_define_class(env, LOCAL_SOCKET_CONNECTION, NAPI_AUTO_LENGTH, constructor, nullptr,
137 properties.size(), descriptors, &jsConstructor),
138 NapiUtils::GetUndefined(env));
139
140 if (jsConstructor != nullptr) {
141 napi_value result = NewInstanceWithConstructor(env, info, jsConstructor, data);
142 NapiUtils::SetInt32Property(env, result, SocketModuleExports::LocalSocketConnection::PROPERTY_CLIENT_ID,
143 data->clientId_);
144 return result;
145 }
146 return NapiUtils::GetUndefined(env);
147 }
148
MakeLocalSocketConnectionMessage(napi_env env,void * para)149 static napi_value MakeLocalSocketConnectionMessage(napi_env env, void *para)
150 {
151 auto pData = reinterpret_cast<LocalSocketConnectionData *>(para);
152 napi_callback_info info = nullptr;
153 return ConstructLocalSocketConnection(env, info, pData);
154 }
155
MakeJsLocalSocketMessageParam(napi_env env,napi_value msgBuffer,MsgWithLocalRemoteInfo * msg)156 static napi_value MakeJsLocalSocketMessageParam(napi_env env, napi_value msgBuffer, MsgWithLocalRemoteInfo *msg)
157 {
158 napi_value obj = NapiUtils::CreateObject(env);
159 if (NapiUtils::GetValueType(env, obj) != napi_object) {
160 return nullptr;
161 }
162 if (NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
163 NapiUtils::SetNamedProperty(env, obj, KEY_MESSAGE, msgBuffer);
164 }
165 NapiUtils::SetStringPropertyUtf8(env, obj, KEY_ADDRESS, msg->remoteInfo.GetAddress());
166 NapiUtils::SetUint32Property(env, obj, KEY_SIZE, msg->len);
167 return obj;
168 }
169
MakeLocalSocketMessage(napi_env env,void * param)170 static napi_value MakeLocalSocketMessage(napi_env env, void *param)
171 {
172 EventManager *manager = reinterpret_cast<EventManager *>(param);
173 MsgWithLocalRemoteInfo *msg = reinterpret_cast<MsgWithLocalRemoteInfo *>(manager->GetQueueData());
174 manager->PopQueueData();
175 auto deleter = [](const MsgWithLocalRemoteInfo *p) { delete p; };
176 std::unique_ptr<MsgWithLocalRemoteInfo, decltype(deleter)> handler(msg, deleter);
177 if (msg == nullptr || msg->data == nullptr || msg->len == 0) {
178 NETSTACK_LOGE("msg or msg->data or msg->len is invalid");
179 return NapiUtils::GetUndefined(env);
180 }
181 void *dataHandle = nullptr;
182 napi_value msgBuffer = NapiUtils::CreateArrayBuffer(env, msg->len, &dataHandle);
183 if (dataHandle == nullptr || !NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
184 return NapiUtils::GetUndefined(env);
185 }
186 int result = memcpy_s(dataHandle, msg->len, msg->data, msg->len);
187 if (result != EOK) {
188 NETSTACK_LOGE("memcpy err, res: %{public}d, msg: %{public}s, len: %{public}u", result,
189 reinterpret_cast<char *>(msg->data), msg->len);
190 return NapiUtils::GetUndefined(env);
191 }
192 return MakeJsLocalSocketMessageParam(env, msgBuffer, msg);
193 }
194
CallbackTemplate(uv_work_t * work,int status)195 template <napi_value (*MakeJsValue)(napi_env, void *)> static void CallbackTemplate(uv_work_t *work, int status)
196 {
197 (void)status;
198
199 auto workWrapper = static_cast<UvWorkWrapper *>(work->data);
200 napi_env env = workWrapper->env;
201 auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
202 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
203
204 napi_value obj = MakeJsValue(env, workWrapper->data);
205
206 std::pair<napi_value, napi_value> arg = {NapiUtils::GetUndefined(workWrapper->env), obj};
207 workWrapper->manager->Emit(workWrapper->type, arg);
208
209 delete workWrapper;
210 delete work;
211 }
212
OnRecvLocalSocketMessage(EventManager * manager,void * data,size_t len,const std::string & path)213 static bool OnRecvLocalSocketMessage(EventManager *manager, void *data, size_t len, const std::string &path)
214 {
215 if (manager == nullptr || data == nullptr || len == 0) {
216 NETSTACK_LOGE("manager or data or len is invalid");
217 return false;
218 }
219 MsgWithLocalRemoteInfo *msg = new (std::nothrow) MsgWithLocalRemoteInfo(data, len, path);
220 if (msg == nullptr) {
221 NETSTACK_LOGE("MsgWithLocalRemoteInfo construct error");
222 return false;
223 }
224 manager->SetQueueData(reinterpret_cast<void *>(msg));
225 manager->EmitByUv(EVENT_MESSAGE, manager, CallbackTemplate<MakeLocalSocketMessage>);
226 return true;
227 }
228
PollFd(pollfd * fds,nfds_t num,int timeout)229 static bool PollFd(pollfd *fds, nfds_t num, int timeout)
230 {
231 int ret = poll(fds, num, timeout);
232 if (ret == -1) {
233 NETSTACK_LOGE("poll to send failed, socket is %{public}d, errno is %{public}d", fds->fd, errno);
234 return false;
235 }
236 if (ret == 0) {
237 NETSTACK_LOGE("poll to send timeout, socket is %{public}d, timeout is %{public}d", fds->fd, timeout);
238 return false;
239 }
240 return true;
241 }
242
ConfirmSocketTimeoutMs(int sock,int type,int defaultValue)243 static int ConfirmSocketTimeoutMs(int sock, int type, int defaultValue)
244 {
245 timeval timeout;
246 socklen_t optlen = sizeof(timeout);
247 if (getsockopt(sock, SOL_SOCKET, type, reinterpret_cast<void *>(&timeout), &optlen) < 0) {
248 NETSTACK_LOGE("get timeout failed, type: %{public}d, sock: %{public}d, errno: %{public}d", type, sock, errno);
249 return defaultValue;
250 }
251 auto socketTimeoutMs = timeout.tv_sec * UNIT_CONVERSION_1000 + timeout.tv_usec / UNIT_CONVERSION_1000;
252 return socketTimeoutMs == 0 ? defaultValue : socketTimeoutMs;
253 }
254
PollSendData(int sock,const char * data,size_t size,sockaddr * addr,socklen_t addrLen)255 static bool PollSendData(int sock, const char *data, size_t size, sockaddr *addr, socklen_t addrLen)
256 {
257 int bufferSize = DEFAULT_BUFFER_SIZE;
258 int opt = 0;
259 socklen_t optLen = sizeof(opt);
260 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
261 bufferSize = opt;
262 }
263 int sockType = 0;
264 optLen = sizeof(sockType);
265 if (getsockopt(sock, SOL_SOCKET, SO_TYPE, reinterpret_cast<void *>(&sockType), &optLen) < 0) {
266 NETSTACK_LOGI("get sock opt sock type failed, socket is %{public}d, errno is %{public}d", sock, errno);
267 return false;
268 }
269
270 auto curPos = data;
271 ssize_t leftSize = static_cast<ssize_t>(size);
272 nfds_t num = 1;
273 pollfd fds[1] = {{0}};
274 fds[0].fd = sock;
275 fds[0].events = static_cast<short>(POLLOUT);
276
277 int sendTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_SNDTIMEO, DEFAULT_TIMEOUT_MS);
278 while (leftSize > 0) {
279 if (!PollFd(fds, num, sendTimeoutMs)) {
280 return false;
281 }
282 size_t sendSize = (sockType == SOCK_STREAM ? leftSize : std::min<size_t>(leftSize, bufferSize));
283 auto sendLen = sendto(sock, curPos, sendSize, 0, addr, addrLen);
284 if (sendLen < 0) {
285 if (errno == EAGAIN) {
286 continue;
287 }
288 NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", sock, errno);
289 return false;
290 }
291 if (sendLen == 0) {
292 break;
293 }
294 curPos += sendLen;
295 leftSize -= sendLen;
296 }
297
298 if (leftSize != 0) {
299 NETSTACK_LOGE("send not complete, socket is %{public}d, errno is %{public}d", sock, errno);
300 return false;
301 }
302 return true;
303 }
304
LocalSocketSendEvent(LocalSocketSendContext * context)305 static bool LocalSocketSendEvent(LocalSocketSendContext *context)
306 {
307 if (context == nullptr) {
308 return false;
309 }
310 if (!PollSendData(context->GetSocketFd(), context->GetOptionsRef().GetBufferRef().c_str(),
311 context->GetOptionsRef().GetBufferRef().size(), nullptr, 0)) {
312 NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
313 context->SetErrorCode(errno);
314 return false;
315 }
316 return true;
317 }
318
MakeNonBlock(int sock)319 static bool MakeNonBlock(int sock)
320 {
321 int flags = fcntl(sock, F_GETFL, 0);
322 while (flags == -1 && errno == EINTR) {
323 flags = fcntl(sock, F_GETFL, 0);
324 }
325 if (flags == -1) {
326 NETSTACK_LOGE("make non block failed, socket is %{public}d, errno is %{public}d", sock, errno);
327 return false;
328 }
329 int ret = fcntl(sock, F_SETFL, static_cast<size_t>(flags) | static_cast<size_t>(O_NONBLOCK));
330 while (ret == -1 && errno == EINTR) {
331 ret = fcntl(sock, F_SETFL, static_cast<size_t>(flags) | static_cast<size_t>(O_NONBLOCK));
332 }
333 if (ret == -1) {
334 NETSTACK_LOGE("make non block failed, socket is %{public}d, errno is %{public}d", sock, errno);
335 return false;
336 }
337 return true;
338 }
339
MakeLocalSocket(int socketType,bool needNonblock)340 int MakeLocalSocket(int socketType, bool needNonblock)
341 {
342 int sock = socket(AF_UNIX, socketType, 0);
343 NETSTACK_LOGI("new local socket is %{public}d", sock);
344 if (sock < 0) {
345 NETSTACK_LOGE("make local socket failed, errno is %{public}d", errno);
346 return -1;
347 }
348 if (needNonblock && !MakeNonBlock(sock)) {
349 close(sock);
350 return -1;
351 }
352 return sock;
353 }
354
MakeError(napi_env env,void * errCode)355 static napi_value MakeError(napi_env env, void *errCode)
356 {
357 auto code = reinterpret_cast<int32_t *>(errCode);
358 auto deleter = [](const int32_t *p) { delete p; };
359 std::unique_ptr<int32_t, decltype(deleter)> handler(code, deleter);
360
361 napi_value err = NapiUtils::CreateObject(env);
362 if (NapiUtils::GetValueType(env, err) != napi_object) {
363 return NapiUtils::GetUndefined(env);
364 }
365 NapiUtils::SetInt32Property(env, err, KEY_ERROR_CODE, *code);
366 return err;
367 }
368
MakeClose(napi_env env,void * data)369 static napi_value MakeClose(napi_env env, void *data)
370 {
371 (void)data;
372 napi_value obj = NapiUtils::CreateObject(env);
373 if (NapiUtils::GetValueType(env, obj) != napi_object) {
374 return NapiUtils::GetUndefined(env);
375 }
376
377 return obj;
378 }
379
380 class LocalSocketMessageCallback {
381 public:
382 LocalSocketMessageCallback() = delete;
383
384 ~LocalSocketMessageCallback() = default;
385
LocalSocketMessageCallback(EventManager * manager,const std::string & path="")386 explicit LocalSocketMessageCallback(EventManager *manager, const std::string &path = "")
387 : manager_(manager), socketPath_(path)
388 {
389 }
390
OnError(int err) const391 void OnError(int err) const
392 {
393 manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
394 }
395
OnCloseMessage(EventManager * manager) const396 void OnCloseMessage(EventManager *manager) const
397 {
398 manager->EmitByUv(EVENT_CLOSE, nullptr, CallbackTemplate<MakeClose>);
399 }
400
OnMessage(void * data,size_t dataLen,sockaddr * addr) const401 bool OnMessage(void *data, size_t dataLen, [[maybe_unused]] sockaddr *addr) const
402 {
403 return OnRecvLocalSocketMessage(manager_, data, dataLen, socketPath_);
404 }
405
OnMessage(EventManager * manager,void * data,size_t len,const std::string & path) const406 bool OnMessage(EventManager *manager, void *data, size_t len, const std::string &path) const
407 {
408 return OnRecvLocalSocketMessage(manager, data, len, path);
409 }
410
OnLocalSocketConnectionMessage(int clientId,LocalSocketServerManager * serverManager) const411 void OnLocalSocketConnectionMessage(int clientId, LocalSocketServerManager *serverManager) const
412 {
413 LocalSocketConnectionData *data = new (std::nothrow) LocalSocketConnectionData(clientId, serverManager);
414 if (data != nullptr) {
415 manager_->EmitByUv(EVENT_CONNECT, data, CallbackTemplate<MakeLocalSocketConnectionMessage>);
416 }
417 }
GetEventManager() const418 EventManager *GetEventManager() const
419 {
420 return manager_;
421 }
422
423 protected:
424 EventManager *manager_;
425
426 private:
427 std::string socketPath_;
428 };
429
SetSocketBufferSize(int sockfd,int type,uint32_t size)430 static bool SetSocketBufferSize(int sockfd, int type, uint32_t size)
431 {
432 if (size > MAX_SOCKET_BUFFER_SIZE) {
433 NETSTACK_LOGE("invalid socket buffer size: %{public}u", size);
434 return false;
435 }
436 if (setsockopt(sockfd, SOL_SOCKET, type, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
437 NETSTACK_LOGE("localsocket set sock size failed, sock: %{public}d, type: %{public}d, size: %{public}u, size",
438 sockfd, type, size);
439 return false;
440 }
441 return true;
442 }
443
SetLocalSocketOptions(int sockfd,const LocalExtraOptions & options)444 static bool SetLocalSocketOptions(int sockfd, const LocalExtraOptions &options)
445 {
446 if (options.AlreadySetRecvBufSize()) {
447 uint32_t recvBufSize = options.GetReceiveBufferSize() / SOCKET_SIZE_CONVERSION;
448 if (!SetSocketBufferSize(sockfd, SO_RCVBUF, recvBufSize)) {
449 return false;
450 }
451 }
452 if (options.AlreadySetSendBufSize()) {
453 uint32_t sendBufSize = options.GetSendBufferSize() / SOCKET_SIZE_CONVERSION;
454 if (!SetSocketBufferSize(sockfd, SO_SNDBUF, sendBufSize)) {
455 return false;
456 }
457 }
458 if (options.AlreadySetTimeout()) {
459 uint32_t timeMs = options.GetSocketTimeout();
460 timeval timeout = {timeMs / UNIT_CONVERSION_1000, (timeMs % UNIT_CONVERSION_1000) * UNIT_CONVERSION_1000};
461 if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
462 NETSTACK_LOGE("localsocket setsockopt error, SO_RCVTIMEO, fd: %{public}d", sockfd);
463 return false;
464 }
465 if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
466 NETSTACK_LOGE("localsocket setsockopt error, SO_SNDTIMEO, fd: %{public}d", sockfd);
467 return false;
468 }
469 }
470 return true;
471 }
472
SetSocketDefaultBufferSize(int sockfd,LocalSocketServerManager * mgr)473 static void SetSocketDefaultBufferSize(int sockfd, LocalSocketServerManager *mgr)
474 {
475 uint32_t recvSize = DEFAULT_BUFFER_SIZE / SOCKET_SIZE_CONVERSION;
476 if (mgr->alreadySetExtraOptions_ && mgr->extraOptions_.AlreadySetRecvBufSize()) {
477 recvSize = mgr->extraOptions_.GetReceiveBufferSize();
478 }
479 SetSocketBufferSize(sockfd, SO_RCVBUF, recvSize);
480 uint32_t sendSize = DEFAULT_BUFFER_SIZE / SOCKET_SIZE_CONVERSION;
481 if (mgr->alreadySetExtraOptions_ && mgr->extraOptions_.AlreadySetSendBufSize()) {
482 sendSize = mgr->extraOptions_.GetSendBufferSize();
483 }
484 SetSocketBufferSize(sockfd, SO_SNDBUF, sendSize);
485 }
486
ConfirmBufferSize(int sock)487 static int ConfirmBufferSize(int sock)
488 {
489 int bufferSize = DEFAULT_BUFFER_SIZE;
490 int opt = 0;
491 socklen_t optLen = sizeof(opt);
492 if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
493 bufferSize = opt;
494 }
495 return bufferSize;
496 }
497
LocalSocketServerRecvHandler(int connectFd,LocalSocketServerManager * serverManager,const LocalSocketMessageCallback & callback,const std::string & path)498 static void LocalSocketServerRecvHandler(int connectFd, LocalSocketServerManager *serverManager,
499 const LocalSocketMessageCallback &callback, const std::string &path)
500 {
501 int clientId = serverManager->AddAccept(connectFd);
502 if (serverManager->alreadySetExtraOptions_) {
503 SetLocalSocketOptions(connectFd, serverManager->extraOptions_);
504 }
505 NETSTACK_LOGI("local socket server accept new, fd: %{public}d, id: %{public}d", connectFd, clientId);
506 callback.OnLocalSocketConnectionMessage(clientId, serverManager);
507 EventManager *eventManager = serverManager->WaitForManager(clientId);
508 int sockRecvSize = ConfirmBufferSize(connectFd);
509 void *buffer = malloc(sockRecvSize);
510 if (buffer == nullptr) {
511 NETSTACK_LOGE("failed to malloc, connectFd: %{public}d, malloc size: %{public}d", connectFd, sockRecvSize);
512 return;
513 }
514 while (true) {
515 if (memset_s(buffer, sockRecvSize, 0, sockRecvSize) != EOK) {
516 NETSTACK_LOGE("memset_s failed, connectFd: %{public}d, clientId: %{public}d", connectFd, clientId);
517 break;
518 }
519 int32_t recvSize = recv(connectFd, buffer, sockRecvSize, 0);
520 if (recvSize <= 0) {
521 if (errno != EAGAIN) {
522 NETSTACK_LOGE("conntion close, recvSize:%{public}d, errno:%{public}d, fd:%{public}d, id:%{public}d",
523 recvSize, errno, connectFd, clientId);
524 callback.OnCloseMessage(eventManager);
525 serverManager->RemoveAccept(clientId);
526 break;
527 }
528 } else {
529 NETSTACK_LOGD("localsocket recv: fd: %{public}d, size: %{public}d, buf: %{public}s", connectFd, recvSize,
530 reinterpret_cast<char *>(buffer));
531 void *data = malloc(recvSize);
532 if (data == nullptr) {
533 callback.OnError(NO_MEMORY);
534 break;
535 }
536 if (memcpy_s(data, recvSize, buffer, recvSize) != EOK ||
537 !callback.OnMessage(eventManager, data, recvSize, path)) {
538 free(data);
539 }
540 }
541 }
542 free(buffer);
543 }
544
LocalSocketServerAccept(LocalSocketServerManager * mgr,const LocalSocketMessageCallback & callback,const std::string & path)545 static void LocalSocketServerAccept(LocalSocketServerManager *mgr, const LocalSocketMessageCallback &callback,
546 const std::string &path)
547 {
548 while (true) {
549 struct sockaddr_un clientAddress;
550 socklen_t clientAddrLength = sizeof(clientAddress);
551 int connectFd = accept(mgr->sockfd_, reinterpret_cast<sockaddr *>(&clientAddress), &clientAddrLength);
552 if (connectFd < 0) {
553 continue;
554 }
555 if (mgr->GetClientCounts() >= MAX_CLIENTS) {
556 NETSTACK_LOGE("local socket server max number of clients reached, sockfd: %{public}d", mgr->sockfd_);
557 close(connectFd);
558 continue;
559 }
560 SetSocketDefaultBufferSize(connectFd, mgr);
561 std::thread handlerThread(LocalSocketServerRecvHandler, connectFd, mgr, std::ref(callback), std::ref(path));
562 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
563 pthread_setname_np(LOCAL_SOCKET_SERVER_HANDLE_CLIENT);
564 #else
565 pthread_setname_np(handlerThread.native_handle(), LOCAL_SOCKET_SERVER_HANDLE_CLIENT);
566 #endif
567 handlerThread.detach();
568 }
569 }
570
PollRecvData(int sock,sockaddr * addr,socklen_t addrLen,const LocalSocketMessageCallback & callback)571 static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const LocalSocketMessageCallback &callback)
572 {
573 int bufferSize = ConfirmBufferSize(sock);
574 auto deleter = [](char *s) { free(reinterpret_cast<void *>(s)); };
575 std::unique_ptr<char, decltype(deleter)> buf(reinterpret_cast<char *>(malloc(bufferSize)), deleter);
576 if (buf == nullptr) {
577 callback.OnError(NO_MEMORY);
578 return;
579 }
580 auto addrDeleter = [](sockaddr *a) { free(reinterpret_cast<void *>(a)); };
581 std::unique_ptr<sockaddr, decltype(addrDeleter)> pAddr(addr, addrDeleter);
582 nfds_t num = 1;
583 pollfd fds[1] = {{.fd = sock, .events = POLLIN}};
584 int recvTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_RCVTIMEO, DEFAULT_POLL_TIMEOUT_MS);
585 while (true) {
586 int ret = poll(fds, num, recvTimeoutMs);
587 if (ret < 0) {
588 NETSTACK_LOGE("poll to recv failed, socket is %{public}d, errno is %{public}d", sock, errno);
589 callback.OnError(errno);
590 return;
591 }
592 if (ret == 0) {
593 continue;
594 }
595 if (static_cast<int>(reinterpret_cast<uint64_t>(callback.GetEventManager()->GetData())) == 0) {
596 return;
597 }
598 (void)memset_s(buf.get(), bufferSize, 0, bufferSize);
599 socklen_t tempAddrLen = addrLen;
600 auto recvLen = recvfrom(sock, buf.get(), bufferSize, 0, addr, &tempAddrLen);
601 if (recvLen < 0) {
602 if (errno == EAGAIN) {
603 continue;
604 }
605 NETSTACK_LOGE("recv failed, socket is %{public}d, errno is %{public}d", sock, errno);
606 callback.OnError(errno);
607 return;
608 }
609 if (recvLen == 0) {
610 continue;
611 }
612 void *data = malloc(recvLen);
613 if (data == nullptr) {
614 callback.OnError(NO_MEMORY);
615 return;
616 }
617 if (memcpy_s(data, recvLen, buf.get(), recvLen) != EOK || !callback.OnMessage(data, recvLen, addr)) {
618 free(data);
619 }
620 }
621 }
622
ExecLocalSocketBind(LocalSocketBindContext * context)623 bool ExecLocalSocketBind(LocalSocketBindContext *context)
624 {
625 if (context == nullptr) {
626 return false;
627 }
628 struct sockaddr_un addr;
629 addr.sun_family = AF_UNIX;
630 if (strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, context->GetSocketPath().c_str()) != 0) {
631 NETSTACK_LOGE("failed to copy socket path, sockfd: %{public}d", context->GetSocketFd());
632 context->SetErrorCode(UNKNOW_ERROR);
633 return false;
634 }
635 if (bind(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)) == -1) {
636 NETSTACK_LOGE("failed to bind local socket, errno: %{public}d", errno);
637 context->SetErrorCode(errno);
638 return false;
639 }
640 return true;
641 }
642
NonBlockConnect(int sock,sockaddr * addr,socklen_t addrLen,uint32_t timeoutMSec)643 static bool NonBlockConnect(int sock, sockaddr *addr, socklen_t addrLen, uint32_t timeoutMSec)
644 {
645 if (connect(sock, addr, addrLen) == -1) {
646 pollfd fds[1] = {{.fd = sock, .events = POLLOUT}};
647 if (errno != EINPROGRESS) {
648 NETSTACK_LOGE("connect error, fd: %{public}d, errno: %{public}d", sock, errno);
649 return false;
650 }
651 int pollResult = poll(fds, 1, timeoutMSec);
652 if (pollResult == 0) {
653 NETSTACK_LOGE("connection timeout, fd: %{public}d, timeout: %{public}d", sock, timeoutMSec);
654 return false;
655 } else if (pollResult == -1) {
656 NETSTACK_LOGE("poll connect error, fd: %{public}d, errno: %{public}d", sock, errno);
657 return false;
658 }
659 int error = 0;
660 socklen_t errorLen = sizeof(error);
661 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &errorLen) < 0 || error != 0) {
662 NETSTACK_LOGE("failed to get socket so_error, fd: %{public}d, errno: %{public}d", sock, errno);
663 return false;
664 }
665 }
666 return true;
667 }
668
ExecLocalSocketConnect(LocalSocketConnectContext * context)669 bool ExecLocalSocketConnect(LocalSocketConnectContext *context)
670 {
671 if (context == nullptr) {
672 return false;
673 }
674 struct sockaddr_un addr;
675 memset_s(&addr, sizeof(addr), 0, sizeof(addr));
676 addr.sun_family = AF_UNIX;
677 int sockfd = context->GetSocketFd();
678 SetSocketBufferSize(sockfd, SO_RCVBUF, DEFAULT_BUFFER_SIZE);
679 if (strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, context->GetSocketPath().c_str()) != 0) {
680 NETSTACK_LOGE("failed to copy local socket path, sockfd: %{public}d", sockfd);
681 context->SetErrorCode(UNKNOW_ERROR);
682 return false;
683 }
684 NETSTACK_LOGI("local socket client fd: %{public}d, path: %{public}s", context->GetSocketFd(), addr.sun_path);
685 if (!NonBlockConnect(sockfd, reinterpret_cast<sockaddr *>(&addr), sizeof(addr), context->GetTimeoutMs())) {
686 NETSTACK_LOGE("failed to connect local socket, errno: %{public}d, %{public}s", errno, strerror(errno));
687 context->SetErrorCode(errno);
688 return false;
689 }
690 if (auto pMgr = reinterpret_cast<LocalSocketManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
691 pMgr->isConnected_ = true;
692 }
693 std::thread serviceThread(PollRecvData, sockfd, nullptr, 0, LocalSocketMessageCallback(context->GetManager(),
694 context->GetSocketPath()));
695 serviceThread.detach();
696 return true;
697 }
698
ExecLocalSocketSend(LocalSocketSendContext * context)699 bool ExecLocalSocketSend(LocalSocketSendContext *context)
700 {
701 if (context == nullptr) {
702 return false;
703 }
704 if (context->GetSocketFd() < 0) {
705 return false;
706 }
707 bool result = LocalSocketSendEvent(context);
708 NapiUtils::CreateUvQueueWorkEnhanced(context->GetEnv(), context, SocketAsyncWork::LocalSocketSendCallback);
709 return result;
710 }
711
ExecLocalSocketClose(LocalSocketCloseContext * context)712 bool ExecLocalSocketClose(LocalSocketCloseContext *context)
713 {
714 if (context == nullptr) {
715 return false;
716 }
717 if (close(context->GetSocketFd()) < 0) {
718 NETSTACK_LOGE("failed to closed localsock, fd: %{public}d, errno: %{public}d", context->GetSocketFd(), errno);
719 context->SetErrorCode(errno);
720 return false;
721 }
722 context->SetSocketFd(0);
723 if (auto pMgr = reinterpret_cast<LocalSocketManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
724 pMgr->isConnected_ = false;
725 }
726 return true;
727 }
728
ExecLocalSocketGetState(LocalSocketGetStateContext * context)729 bool ExecLocalSocketGetState(LocalSocketGetStateContext *context)
730 {
731 if (context == nullptr) {
732 return false;
733 }
734 struct sockaddr_un unAddr = {0};
735 socklen_t len = sizeof(unAddr);
736 SocketStateBase &state = context->GetStateRef();
737 if (getsockname(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&unAddr), &len) < 0) {
738 NETSTACK_LOGI("localsocket do not bind or socket has closed");
739 state.SetIsBound(false);
740 } else {
741 state.SetIsBound(strlen(unAddr.sun_path) > 0);
742 }
743 if (auto pMgr = reinterpret_cast<LocalSocketManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
744 state.SetIsConnected(pMgr->isConnected_);
745 }
746 return true;
747 }
748
ExecLocalSocketGetSocketFd(LocalSocketGetSocketFdContext * context)749 bool ExecLocalSocketGetSocketFd(LocalSocketGetSocketFdContext *context)
750 {
751 if (context == nullptr) {
752 return false;
753 }
754 return true;
755 }
756
ExecLocalSocketSetExtraOptions(LocalSocketSetExtraOptionsContext * context)757 bool ExecLocalSocketSetExtraOptions(LocalSocketSetExtraOptionsContext *context)
758 {
759 if (context == nullptr) {
760 return false;
761 }
762 if (SetLocalSocketOptions(context->GetSocketFd(), context->GetOptionsRef())) {
763 return true;
764 }
765 context->SetErrorCode(errno);
766 return false;
767 }
768
GetLocalSocketOptions(int sockfd,LocalExtraOptions & optionsRef)769 static bool GetLocalSocketOptions(int sockfd, LocalExtraOptions &optionsRef)
770 {
771 int result = 0;
772 socklen_t len = sizeof(result);
773 if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &result, &len) == -1) {
774 NETSTACK_LOGE("getsockopt error, SO_RCVBUF");
775 return false;
776 }
777 optionsRef.SetReceiveBufferSize(result);
778 if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &result, &len) == -1) {
779 NETSTACK_LOGE("getsockopt error, SO_SNDBUF");
780 return false;
781 }
782 optionsRef.SetSendBufferSize(result);
783 timeval timeout;
784 socklen_t timeLen = sizeof(timeout);
785 if (getsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, &timeLen) == -1) {
786 NETSTACK_LOGE("getsockopt error, SO_SNDTIMEO");
787 return false;
788 }
789 optionsRef.SetSocketTimeout(timeout.tv_sec * UNIT_CONVERSION_1000 + timeout.tv_usec / UNIT_CONVERSION_1000);
790 return true;
791 }
792
ExecLocalSocketGetExtraOptions(LocalSocketGetExtraOptionsContext * context)793 bool ExecLocalSocketGetExtraOptions(LocalSocketGetExtraOptionsContext *context)
794 {
795 if (context == nullptr) {
796 return false;
797 }
798 LocalExtraOptions &optionsRef = context->GetOptionsRef();
799 if (!GetLocalSocketOptions(context->GetSocketFd(), optionsRef)) {
800 context->SetErrorCode(errno);
801 return false;
802 }
803 return true;
804 }
805
LocalSocketServerBind(LocalSocketServerListenContext * context)806 static bool LocalSocketServerBind(LocalSocketServerListenContext *context)
807 {
808 unlink(context->GetSocketPath().c_str());
809 struct sockaddr_un addr;
810 addr.sun_family = AF_UNIX;
811 if (int err = strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, context->GetSocketPath().c_str()); err != 0) {
812 NETSTACK_LOGE("failed to copy socket path");
813 context->SetErrorCode(err);
814 return false;
815 }
816 if (bind(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)) == -1) {
817 NETSTACK_LOGE("failed to bind local socket, fd: %{public}d, errno: %{public}d", context->GetSocketFd(), errno);
818 context->SetErrorCode(errno);
819 return false;
820 }
821 NETSTACK_LOGI("local socket server bind success: %{public}s", addr.sun_path);
822 return true;
823 }
824
ExecLocalSocketServerListen(LocalSocketServerListenContext * context)825 bool ExecLocalSocketServerListen(LocalSocketServerListenContext *context)
826 {
827 if (context == nullptr) {
828 return false;
829 }
830 if (!LocalSocketServerBind(context)) {
831 return false;
832 }
833 if (listen(context->GetSocketFd(), BACKLOG) < 0) {
834 NETSTACK_LOGE("local socket server listen error, fd: %{public}d", context->GetSocketFd());
835 context->SetErrorCode(errno);
836 return false;
837 }
838 NETSTACK_LOGI("local socket server listen success");
839 LocalSocketServerManager *mgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
840 if (mgr == nullptr) {
841 NETSTACK_LOGE("LocalSocketServerManager reinterpret cast failed");
842 context->SetErrorCode(UNKNOW_ERROR);
843 return false;
844 }
845 std::thread serviceThread(LocalSocketServerAccept, mgr, LocalSocketMessageCallback(context->GetManager()),
846 context->GetSocketPath());
847 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
848 pthread_setname_np(LOCAL_SOCKET_SERVER_ACCEPT_RECV_DATA);
849 #else
850 pthread_setname_np(serviceThread.native_handle(), LOCAL_SOCKET_SERVER_ACCEPT_RECV_DATA);
851 #endif
852 serviceThread.detach();
853 return true;
854 }
855
ExecLocalSocketServerGetState(LocalSocketServerGetStateContext * context)856 bool ExecLocalSocketServerGetState(LocalSocketServerGetStateContext *context)
857 {
858 if (context == nullptr) {
859 return false;
860 }
861 struct sockaddr_un unAddr = {0};
862 socklen_t len = sizeof(unAddr);
863 SocketStateBase &state = context->GetStateRef();
864 if (getsockname(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&unAddr), &len) == 0) {
865 state.SetIsBound(true);
866 }
867 auto pMgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
868 if (pMgr != nullptr) {
869 state.SetIsConnected(pMgr->GetClientCounts() > 0);
870 }
871 return true;
872 }
873
ExecLocalSocketServerSetExtraOptions(LocalSocketServerSetExtraOptionsContext * context)874 bool ExecLocalSocketServerSetExtraOptions(LocalSocketServerSetExtraOptionsContext *context)
875 {
876 if (context == nullptr) {
877 return false;
878 }
879 auto serverManager = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
880 if (serverManager == nullptr) {
881 return false;
882 }
883 for (const auto &[id, fd] : serverManager->acceptFds_) {
884 if (!SetLocalSocketOptions(fd, context->GetOptionsRef())) {
885 context->SetErrorCode(errno);
886 return false;
887 }
888 }
889 serverManager->extraOptions_ = context->GetOptionsRef();
890 serverManager->alreadySetExtraOptions_ = true;
891 return true;
892 }
893
ExecLocalSocketServerGetExtraOptions(LocalSocketServerGetExtraOptionsContext * context)894 bool ExecLocalSocketServerGetExtraOptions(LocalSocketServerGetExtraOptionsContext *context)
895 {
896 if (context == nullptr) {
897 return false;
898 }
899 if (auto pMgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData()); pMgr != nullptr) {
900 LocalExtraOptions &options = context->GetOptionsRef();
901 if (pMgr->alreadySetExtraOptions_) {
902 options = pMgr->extraOptions_;
903 } else {
904 if (!GetLocalSocketOptions(context->GetSocketFd(), options)) {
905 context->SetErrorCode(errno);
906 return false;
907 }
908 options.SetReceiveBufferSize(DEFAULT_BUFFER_SIZE);
909 options.SetSendBufferSize(DEFAULT_BUFFER_SIZE);
910 }
911 return true;
912 }
913 context->SetErrorCode(UNKNOW_ERROR);
914 return false;
915 }
916
ExecLocalSocketConnectionSend(LocalSocketServerSendContext * context)917 bool ExecLocalSocketConnectionSend(LocalSocketServerSendContext *context)
918 {
919 if (context == nullptr) {
920 return false;
921 }
922 int clientId = context->GetClientId();
923 auto data = reinterpret_cast<LocalSocketConnectionData *>(context->GetManager()->GetData());
924 if (data == nullptr) {
925 NETSTACK_LOGE("is nullptr, id: %{public}d", clientId);
926 return false;
927 }
928 int acceptFd = data->serverManager_->GetAcceptFd(clientId);
929 if (acceptFd <= 0) {
930 NETSTACK_LOGE("accept fd is invalid, id: %{public}d, fd: %{public}d", clientId, acceptFd);
931 context->SetErrorCode(ERRNO_BAD_FD);
932 return false;
933 }
934
935 if (!PollSendData(acceptFd, context->GetOptionsRef().GetBufferRef().c_str(),
936 context->GetOptionsRef().GetBufferRef().size(), nullptr, 0)) {
937 NETSTACK_LOGE("localsocket connection send failed, fd: %{public}d, errno: %{public}d", acceptFd, errno);
938 context->SetErrorCode(errno);
939 return false;
940 }
941 return true;
942 }
943
ExecLocalSocketConnectionClose(LocalSocketServerCloseContext * context)944 bool ExecLocalSocketConnectionClose(LocalSocketServerCloseContext *context)
945 {
946 if (context == nullptr) {
947 return false;
948 }
949 if (auto mgr = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData()); mgr != nullptr) {
950 if (mgr->sockfd_ > 0) {
951 return true;
952 }
953 }
954 NETSTACK_LOGI("socket has lost");
955 context->SetErrorCode(UNKNOW_ERROR);
956 return false;
957 }
958
LocalSocketBindCallback(LocalSocketBindContext * context)959 napi_value LocalSocketBindCallback(LocalSocketBindContext *context)
960 {
961 return NapiUtils::GetUndefined(context->GetEnv());
962 }
963
LocalSocketConnectCallback(LocalSocketConnectContext * context)964 napi_value LocalSocketConnectCallback(LocalSocketConnectContext *context)
965 {
966 return NapiUtils::GetUndefined(context->GetEnv());
967 }
968
LocalSocketSendCallback(LocalSocketSendContext * context)969 napi_value LocalSocketSendCallback(LocalSocketSendContext *context)
970 {
971 return NapiUtils::GetUndefined(context->GetEnv());
972 }
973
LocalSocketCloseCallback(LocalSocketCloseContext * context)974 napi_value LocalSocketCloseCallback(LocalSocketCloseContext *context)
975 {
976 return NapiUtils::GetUndefined(context->GetEnv());
977 }
978
LocalSocketGetStateCallback(LocalSocketGetStateContext * context)979 napi_value LocalSocketGetStateCallback(LocalSocketGetStateContext *context)
980 {
981 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
982 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
983 return NapiUtils::GetUndefined(context->GetEnv());
984 }
985 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->GetStateRef().IsBound());
986 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->GetStateRef().IsClose());
987 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->GetStateRef().IsConnected());
988 return obj;
989 }
990
LocalSocketGetSocketFdCallback(LocalSocketGetSocketFdContext * context)991 napi_value LocalSocketGetSocketFdCallback(LocalSocketGetSocketFdContext *context)
992 {
993 int sockFd = context->GetSocketFd();
994 if (sockFd <= 0) {
995 return NapiUtils::GetUndefined(context->GetEnv());
996 }
997 return NapiUtils::CreateUint32(context->GetEnv(), sockFd);
998 }
999
LocalSocketSetExtraOptionsCallback(LocalSocketSetExtraOptionsContext * context)1000 napi_value LocalSocketSetExtraOptionsCallback(LocalSocketSetExtraOptionsContext *context)
1001 {
1002 return NapiUtils::GetUndefined(context->GetEnv());
1003 }
1004
LocalSocketGetExtraOptionsCallback(LocalSocketGetExtraOptionsContext * context)1005 napi_value LocalSocketGetExtraOptionsCallback(LocalSocketGetExtraOptionsContext *context)
1006 {
1007 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1008 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1009 return NapiUtils::GetUndefined(context->GetEnv());
1010 }
1011 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_REUSE_ADDRESS, false);
1012 NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_RECEIVE_BUFFER_SIZE,
1013 context->GetOptionsRef().GetReceiveBufferSize());
1014 NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_SEND_BUFFER_SIZE,
1015 context->GetOptionsRef().GetSendBufferSize());
1016 NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_TIMEOUT, context->GetOptionsRef().GetSocketTimeout());
1017 return obj;
1018 }
1019
LocalSocketServerListenCallback(LocalSocketServerListenContext * context)1020 napi_value LocalSocketServerListenCallback(LocalSocketServerListenContext *context)
1021 {
1022 context->Emit(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1023 NapiUtils::GetUndefined(context->GetEnv())));
1024 return NapiUtils::GetUndefined(context->GetEnv());
1025 }
1026
LocalSocketServerGetStateCallback(LocalSocketServerGetStateContext * context)1027 napi_value LocalSocketServerGetStateCallback(LocalSocketServerGetStateContext *context)
1028 {
1029 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1030 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1031 return NapiUtils::GetUndefined(context->GetEnv());
1032 }
1033 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->GetStateRef().IsBound());
1034 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->GetStateRef().IsClose());
1035 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->GetStateRef().IsConnected());
1036 return obj;
1037 }
1038
LocalSocketServerSetExtraOptionsCallback(LocalSocketServerSetExtraOptionsContext * context)1039 napi_value LocalSocketServerSetExtraOptionsCallback(LocalSocketServerSetExtraOptionsContext *context)
1040 {
1041 return NapiUtils::GetUndefined(context->GetEnv());
1042 }
1043
LocalSocketServerGetExtraOptionsCallback(LocalSocketServerGetExtraOptionsContext * context)1044 napi_value LocalSocketServerGetExtraOptionsCallback(LocalSocketServerGetExtraOptionsContext *context)
1045 {
1046 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1047 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1048 return NapiUtils::GetUndefined(context->GetEnv());
1049 }
1050 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_REUSE_ADDRESS, false);
1051 NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_RECEIVE_BUFFER_SIZE,
1052 context->GetOptionsRef().GetReceiveBufferSize());
1053 NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_SEND_BUFFER_SIZE,
1054 context->GetOptionsRef().GetSendBufferSize());
1055 NapiUtils::SetInt32Property(context->GetEnv(), obj, KEY_TIMEOUT, context->GetOptionsRef().GetSocketTimeout());
1056 return obj;
1057 }
1058
LocalSocketConnectionSendCallback(LocalSocketServerSendContext * context)1059 napi_value LocalSocketConnectionSendCallback(LocalSocketServerSendContext *context)
1060 {
1061 return NapiUtils::GetUndefined(context->GetEnv());
1062 }
1063
LocalSocketConnectionCloseCallback(LocalSocketServerCloseContext * context)1064 napi_value LocalSocketConnectionCloseCallback(LocalSocketServerCloseContext *context)
1065 {
1066 auto pServerManager = reinterpret_cast<LocalSocketServerManager *>(context->GetManager()->GetData());
1067 if (pServerManager == nullptr) {
1068 NETSTACK_LOGE("connection close callback reinterpret cast failed");
1069 return NapiUtils::GetUndefined(context->GetEnv());
1070 }
1071 int acceptFd = pServerManager->GetAcceptFd(context->GetClientId());
1072 if (acceptFd <= 0) {
1073 NETSTACK_LOGE("socket invalid, fd: %{public}d", acceptFd);
1074 return NapiUtils::GetUndefined(context->GetEnv());
1075 }
1076
1077 if (shutdown(acceptFd, SHUT_RDWR) != 0) {
1078 NETSTACK_LOGE("socket shutdown failed, socket is %{public}d, errno is %{public}d", acceptFd, errno);
1079 }
1080 int ret = close(acceptFd);
1081 if (ret < 0) {
1082 NETSTACK_LOGE("sock closed failed, socket is %{public}d, errno is %{public}d", acceptFd, errno);
1083 } else {
1084 NETSTACK_LOGI("sock %{public}d closed success", acceptFd);
1085 pServerManager->RemoveAccept(context->GetClientId());
1086 context->Emit(EVENT_CLOSE, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1087 NapiUtils::GetUndefined(context->GetEnv())));
1088 }
1089
1090 return NapiUtils::GetUndefined(context->GetEnv());
1091 }
1092 } // namespace OHOS::NetStack::Socket::LocalSocketExec
1093