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