• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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