• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "socket_module.h"
17 
18 #include <cstdint>
19 #include <initializer_list>
20 #include <new>
21 #include <unistd.h>
22 #include <utility>
23 
24 #include "bind_context.h"
25 #include "common_context.h"
26 #include "connect_context.h"
27 #include "context_key.h"
28 #include "event_list.h"
29 #include "event_manager.h"
30 #include "local_socket_context.h"
31 #include "local_socket_exec.h"
32 #include "local_socket_server_context.h"
33 #include "module_template.h"
34 #include "multicast_get_loopback_context.h"
35 #include "multicast_get_ttl_context.h"
36 #include "multicast_membership_context.h"
37 #include "multicast_set_loopback_context.h"
38 #include "multicast_set_ttl_context.h"
39 #include "napi/native_api.h"
40 #include "napi/native_common.h"
41 #include "napi_utils.h"
42 #include "net_address.h"
43 #include "netstack_common_utils.h"
44 #include "netstack_log.h"
45 #include "node_api.h"
46 #include "socket_async_work.h"
47 #include "socket_exec.h"
48 #include "socket_exec_common.h"
49 #include "tcp_extra_context.h"
50 #include "tcp_send_context.h"
51 #include "tcp_server_common_context.h"
52 #include "tcp_server_extra_context.h"
53 #include "tcp_server_listen_context.h"
54 #include "tcp_server_send_context.h"
55 #include "tlssocket_module.h"
56 #include "tlssocketserver_module.h"
57 #include "udp_extra_context.h"
58 #include "udp_send_context.h"
59 
60 static constexpr const char *SOCKET_MODULE_NAME = "net.socket";
61 
62 static const char *UDP_BIND_NAME = "UdpBind";
63 static const char *UDP_SEND_NAME = "UdpSend";
64 static const char *UDP_CLOSE_NAME = "UdpClose";
65 static const char *UDP_GET_STATE = "UdpGetState";
66 static const char *UDP_GET_LOCAL_ADDRESS = "UdpGetLocalAddress";
67 static const char *UDP_SET_EXTRA_OPTIONS_NAME = "UdpSetExtraOptions";
68 static constexpr const char *UDP_GET_SOCKET_FD = "UdpGetSocketFd";
69 
70 static constexpr const char *UDP_ADD_MEMBERSHIP = "UdpAddMembership";
71 static constexpr const char *UDP_DROP_MEMBERSHIP = "UdpDropMembership";
72 static constexpr const char *UDP_SET_MULTICAST_TTL = "UdpSetMulticastTTL";
73 static constexpr const char *UDP_GET_MULTICAST_TTL = "UdpGetMulticastTTL";
74 static constexpr const char *UDP_SET_LOOPBACK_MODE = "UdpSetLoopbackMode";
75 static constexpr const char *UDP_GET_LOOPBACK_MODE = "UdpGetLoopbackMode";
76 
77 static constexpr const char *LOCAL_SOCKET_BIND = "LocalSocketBind";
78 static constexpr const char *LOCAL_SOCKET_CONNECT = "LocalSocketConnect";
79 static constexpr const char *LOCAL_SOCKET_SEND = "LocalSocketSend";
80 static constexpr const char *LOCAL_SOCKET_CLOSE = "LocalSocketClose";
81 static constexpr const char *LOCAL_SOCKET_GET_STATE = "LocalSocketGetState";
82 static constexpr const char *LOCAL_SOCKET_GET_LOCAL_ADDRESS = "LocalSocketGetState";
83 static constexpr const char *LOCAL_SOCKET_GET_SOCKET_FD = "LocalSocketGetSocketFd";
84 static constexpr const char *LOCAL_SOCKET_SET_EXTRA_OPTIONS = "LocalSocketSetExtraOptions";
85 static constexpr const char *LOCAL_SOCKET_GET_EXTRA_OPTIONS = "LocalSocketGetExtraOptions";
86 
87 static constexpr const char *LOCAL_SOCKET_SERVER_LISTEN = "LocalSocketServerListen";
88 static constexpr const char *LOCAL_SOCKET_SERVER_END = "LocalSocketServerEnd";
89 static constexpr const char *LOCAL_SOCKET_SERVER_GET_STATE = "LocalSocketServerGetState";
90 static constexpr const char *LOCAL_SOCKET_SERVER_GET_LOCAL_ADDRESS = "LocalSocketServerGetState";
91 static constexpr const char *LOCAL_SOCKET_SERVER_SET_EXTRA_OPTIONS = "LocalSocketServerSetExtraOptions";
92 static constexpr const char *LOCAL_SOCKET_SERVER_GET_EXTRA_OPTIONS = "LocalSocketServerGetExtraOptions";
93 
94 static constexpr const char *LOCAL_SOCKET_CONNECTION_SEND = "LocalSocketConnectionSend";
95 static constexpr const char *LOCAL_SOCKET_CONNECTION_GET_LOCAL_ADDRESS = "LocalSocketConnectionGetLocalAddress";
96 static constexpr const char *LOCAL_SOCKET_CONNECTION_CLOSE = "LocalSocketConnectionClose";
97 
98 static const char *TCP_BIND_NAME = "TcpBind";
99 static const char *TCP_CONNECT_NAME = "TcpConnect";
100 static const char *TCP_SEND_NAME = "TcpSend";
101 static const char *TCP_CLOSE_NAME = "TcpClose";
102 static const char *TCP_GET_STATE = "TcpGetState";
103 static const char *TCP_GET_REMOTE_ADDRESS = "TcpGetRemoteAddress";
104 static const char *TCP_GET_LOCAL_ADDRESS = "TcpGetLocalAddress";
105 static const char *TCP_SET_EXTRA_OPTIONS_NAME = "TcpSetExtraOptions";
106 static constexpr const char *TCP_GET_SOCKET_FD = "TcpGetSocketFd";
107 
108 static constexpr const char *TCP_SERVER_LISTEN_NAME = "TcpServerListen";
109 static constexpr const char *TCP_SERVER_GET_STATE = "TcpServerGetState";
110 static constexpr const char *TCP_SERVER_GET_LOCAL_ADDRESS = "TcpServerGetLocalAddress";
111 static constexpr const char *TCP_SERVER_SET_EXTRA_OPTIONS_NAME = "TcpServerSetExtraOptions";
112 
113 static constexpr const char *TCP_CONNECTION_SEND_NAME = "TcpConnectionSend";
114 static constexpr const char *TCP_CONNECTION_CLOSE_NAME = "TcpConnectionClose";
115 static constexpr const char *TCP_CONNECTION_GET_REMOTE_ADDRESS = "TcpConnectionGetRemoteAddress";
116 static constexpr const char *TCP_CONNECTION_GET_LOCAL_ADDRESS = "TcpConnectionGetLocalAddress";
117 
118 static constexpr const char *KEY_SOCKET_FD = "socketFd";
119 
120 static constexpr const char *SOCKETPROXYTYPE = "ProxyTypes";
121 static constexpr const char *SOCKETPROXYTYPE_NONE = "NONE";
122 static constexpr const char *SOCKETPROXYTYPE_SOCKS5 = "SOCKS5";
123 
124 static constexpr int PARAM_COUNT_TWO = 2;
125 
126 #define SOCKET_INTERFACE(Context, executor, callback, work, name) \
127     ModuleTemplate::InterfaceWithSharedManager<Context>(env, info, name, work, \
128         SocketAsyncWork::executor, SocketAsyncWork::callback)
129 
130 namespace OHOS::NetStack::Socket {
Finalize(napi_env,void * data,void *)131 void Finalize(napi_env, void *data, void *)
132 {
133     NETSTACK_LOGD("socket handle is finalized");
134     auto sharedManager = reinterpret_cast<std::shared_ptr<EventManager> *>(data);
135     if (sharedManager != nullptr && *sharedManager != nullptr) {
136         auto manager = *sharedManager;
137         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData()));
138         if (sock != -1) {
139             SocketExec::SingletonSocketConfig::GetInstance().RemoveServerSocket(sock);
140             close(sock);
141             manager->SetData(reinterpret_cast<void *>(-1));
142         }
143         delete sharedManager;
144     }
145 }
146 
FinalizeTcpSocketServer(napi_env,void * data,void *)147 void FinalizeTcpSocketServer(napi_env, void *data, void *)
148 {
149     NETSTACK_LOGI("tcp socket server handle is finalized");
150     auto sharedManager = reinterpret_cast<std::shared_ptr<EventManager> *>(data);
151     if (sharedManager != nullptr && *sharedManager != nullptr) {
152         auto manager = *sharedManager;
153         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData()));
154         if (sock != -1) {
155             SocketExec::SingletonSocketConfig::GetInstance().RemoveServerSocket(sock);
156             NETSTACK_LOGI("tcp socket server shutdown: %{public}d", sock);
157             shutdown(sock, SHUT_RDWR);
158             manager->SetData(reinterpret_cast<void *>(-1));
159         }
160         delete sharedManager;
161     }
162 }
163 
FinalizeLocalsocketServer(napi_env,void * data,void *)164 void FinalizeLocalsocketServer(napi_env, void *data, void *)
165 {
166     auto sharedManager = reinterpret_cast<std::shared_ptr<EventManager> *>(data);
167     if (sharedManager != nullptr && *sharedManager != nullptr) {
168         auto manager = *sharedManager;
169         if (auto serverMgr = reinterpret_cast<LocalSocketServerManager *>(manager->GetData()); serverMgr != nullptr) {
170             NETSTACK_LOGI("localsocket server handle is finalized, fd: %{public}d", serverMgr->sockfd_);
171 #if !defined(MAC_PLATFORM) && !defined(IOS_PLATFORM)
172             serverMgr->SetServerDestructStatus(true);
173 #else
174             serverMgr->isServerDestruct_ = true;
175 #endif
176             serverMgr->RemoveAllAccept();
177             serverMgr->RemoveAllEventManager();
178             if (serverMgr->sockfd_ > 0) {
179                 close(serverMgr->sockfd_);
180                 serverMgr->sockfd_ = -1;
181             }
182 #if !defined(MAC_PLATFORM) && !defined(IOS_PLATFORM)
183             close(serverMgr->epollFd_);
184 #endif
185             serverMgr->WaitForEndingLoop();
186             delete serverMgr;
187         }
188         delete sharedManager;
189     }
190 }
191 
FinalizeLocalSocket(napi_env,void * data,void *)192 void FinalizeLocalSocket(napi_env, void *data, void *)
193 {
194     auto sharedManager = reinterpret_cast<std::shared_ptr<EventManager> *>(data);
195     if (sharedManager != nullptr && *sharedManager != nullptr) {
196         auto manager = *sharedManager;
197         if (auto pMgr = reinterpret_cast<LocalSocketManager *>(manager->GetData()); pMgr != nullptr) {
198             NETSTACK_LOGI("localsocket handle is finalized, fd: %{public}d", pMgr->sockfd_);
199             if (pMgr->sockfd_ > 0) {
200                 close(pMgr->sockfd_);
201                 pMgr->sockfd_ = 0;
202             }
203             delete pMgr;
204         }
205         delete sharedManager;
206     }
207 }
208 
SetSocket(napi_env env,napi_value thisVal,BaseContext * context,int sock)209 static bool SetSocket(napi_env env, napi_value thisVal, BaseContext *context, int sock)
210 {
211     if (sock < 0) {
212         napi_value error = NapiUtils::CreateObject(env);
213         if (NapiUtils::GetValueType(env, error) != napi_object) {
214             return false;
215         }
216         NapiUtils::SetUint32Property(env, error, KEY_ERROR_CODE, errno);
217         context->EmitSharedManager(EVENT_ERROR, std::make_pair(NapiUtils::GetUndefined(env), error));
218         return false;
219     }
220 
221     std::shared_ptr<EventManager> *sharedManager = nullptr;
222     if (napi_unwrap(env, thisVal, reinterpret_cast<void **>(&sharedManager)) != napi_ok || sharedManager == nullptr) {
223         return false;
224     }
225     auto manager = *sharedManager;
226     if (manager == nullptr) {
227         return false;
228     }
229     manager->SetData(reinterpret_cast<void *>(sock));
230     NapiUtils::SetInt32Property(env, thisVal, KEY_SOCKET_FD, sock);
231     return true;
232 }
233 
MakeTcpClientBindSocket(napi_env env,napi_value thisVal,BindContext * context)234 static bool MakeTcpClientBindSocket(napi_env env, napi_value thisVal, BindContext *context)
235 {
236     if (!context->IsParseOK()) {
237         context->SetErrorCode(PARSE_ERROR_CODE);
238         return false;
239     }
240     if (!CommonUtils::HasInternetPermission()) {
241         context->SetPermissionDenied(true);
242         return false;
243     }
244     NETSTACK_LOGD("bind ip family is %{public}d", context->address_.GetSaFamily());
245     if (context->GetSharedManager()->GetData() != nullptr) {
246         NETSTACK_LOGE("tcp connect has been called");
247         return true;
248     }
249     int sock = ExecCommonUtils::MakeTcpSocket(context->address_.GetSaFamily());
250     if (!SetSocket(env, thisVal, context, sock)) {
251         return false;
252     }
253     context->SetExecOK(true);
254     return true;
255 }
256 
MakeTcpClientConnectSocket(napi_env env,napi_value thisVal,ConnectContext * context)257 static bool MakeTcpClientConnectSocket(napi_env env, napi_value thisVal, ConnectContext *context)
258 {
259     if (!context->IsParseOK()) {
260         context->SetErrorCode(PARSE_ERROR_CODE);
261         return false;
262     }
263     if (!CommonUtils::HasInternetPermission()) {
264         context->SetPermissionDenied(true);
265         return false;
266     }
267     NETSTACK_LOGD("connect ip family is %{public}d", context->options.address.GetSaFamily());
268 
269     auto manager = context->GetSharedManager();
270     if (manager != nullptr &&
271         manager->GetData() != nullptr &&
272         static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData())) != -1) {
273         NETSTACK_LOGD("tcp bind has been called");
274         return true;
275     }
276     int sock = ExecCommonUtils::MakeTcpSocket(context->options.address.GetSaFamily());
277     if (!SetSocket(env, thisVal, context, sock)) {
278         return false;
279     }
280     context->SetExecOK(true);
281     return true;
282 }
283 
MakeTcpServerSocket(napi_env env,napi_value thisVal,TcpServerListenContext * context)284 static bool MakeTcpServerSocket(napi_env env, napi_value thisVal, TcpServerListenContext *context)
285 {
286     if (!context->IsParseOK()) {
287         context->SetErrorCode(PARSE_ERROR_CODE);
288         return false;
289     }
290     if (!CommonUtils::HasInternetPermission()) {
291         context->SetPermissionDenied(true);
292         return false;
293     }
294     int sock = ExecCommonUtils::MakeTcpSocket(context->address_.GetSaFamily(), false);
295     if (sock <= 0) {
296         return false;
297     }
298     int reuse = 1; // 1 means enable reuseaddr feature
299     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&reuse), sizeof(reuse)) < 0) {
300         NETSTACK_LOGE("failed to set tcp server listen socket reuseaddr on, sockfd: %{public}d", sock);
301     }
302     if (!SetSocket(env, thisVal, context, sock)) {
303         return false;
304     }
305     context->SetExecOK(true);
306     return true;
307 }
308 
MakeUdpSocket(napi_env env,napi_value thisVal,BindContext * context)309 static bool MakeUdpSocket(napi_env env, napi_value thisVal, BindContext *context)
310 {
311     if (!context->IsParseOK()) {
312         context->SetErrorCode(PARSE_ERROR_CODE);
313         return false;
314     }
315     if (!CommonUtils::HasInternetPermission()) {
316         context->SetPermissionDenied(true);
317         return false;
318     }
319     int sock = ExecCommonUtils::MakeUdpSocket(context->address_.GetSaFamily());
320     if (!SetSocket(env, thisVal, context, sock)) {
321         return false;
322     }
323     context->SetExecOK(true);
324     return true;
325 }
326 
MakeMulticastUdpSocket(napi_env env,napi_value thisVal,MulticastMembershipContext * context)327 static bool MakeMulticastUdpSocket(napi_env env, napi_value thisVal, MulticastMembershipContext *context)
328 {
329     if (!CommonUtils::HasInternetPermission()) {
330         context->SetPermissionDenied(true);
331         return false;
332     }
333     if (context->GetSocketFd() > 0) {
334         NETSTACK_LOGI("socket exist: %{public}d", context->GetSocketFd());
335         return false;
336     }
337     if (!context->IsParseOK()) {
338         context->SetErrorCode(PARSE_ERROR_CODE);
339         return false;
340     }
341     int sock = ExecCommonUtils::MakeUdpSocket(context->address_.GetSaFamily());
342     if (!SetSocket(env, thisVal, context, sock)) {
343         return false;
344     }
345     context->SetExecOK(true);
346     return true;
347 }
348 
SetSocketManager(napi_env env,napi_value thisVal,BaseContext * context,SocketBaseManager * mgr)349 static bool SetSocketManager(napi_env env, napi_value thisVal, BaseContext *context, SocketBaseManager *mgr)
350 {
351     if (mgr->sockfd_ <= 0) {
352         NETSTACK_LOGE("SetSocketManager sockfd < 0");
353         napi_value error = NapiUtils::CreateObject(env);
354         if (NapiUtils::GetValueType(env, error) != napi_object) {
355             return false;
356         }
357         NapiUtils::SetUint32Property(env, error, KEY_ERROR_CODE, errno);
358         context->EmitSharedManager(EVENT_ERROR, std::make_pair(NapiUtils::GetUndefined(env), error));
359         return false;
360     }
361     std::shared_ptr<EventManager> *sharedManager = nullptr;
362     if (napi_unwrap(env, thisVal, reinterpret_cast<void **>(&sharedManager)) != napi_ok || sharedManager == nullptr) {
363         NETSTACK_LOGE("SetSocketManager unwrap err");
364         return false;
365     }
366     auto manager = *sharedManager;
367     if (manager == nullptr) {
368         return false;
369     }
370     manager->SetData(reinterpret_cast<void *>(mgr));
371     NapiUtils::SetInt32Property(env, thisVal, KEY_SOCKET_FD, mgr->sockfd_);
372     return true;
373 }
374 
MakeLocalSocketBind(napi_env env,napi_value thisVal,LocalSocketBindContext * context)375 static bool MakeLocalSocketBind(napi_env env, napi_value thisVal, LocalSocketBindContext *context)
376 {
377     if (context == nullptr) {
378         return false;
379     }
380     if (context->GetSocketFd() > 0) {
381         NETSTACK_LOGI("socket exist: %{public}d", context->GetSocketFd());
382         return false;
383     }
384     int sock = ExecCommonUtils::MakeLocalSocket(SOCK_STREAM);
385     if (sock < 0) {
386         return false;
387     }
388     auto pManager = new (std::nothrow) LocalSocketManager(sock);
389     if (pManager == nullptr) {
390         return false;
391     }
392     if (!SetSocketManager(env, thisVal, context, pManager)) {
393         delete pManager;
394         return false;
395     }
396     context->SetExecOK(true);
397     return true;
398 }
399 
MakeLocalSocketConnect(napi_env env,napi_value thisVal,LocalSocketConnectContext * context)400 static bool MakeLocalSocketConnect(napi_env env, napi_value thisVal, LocalSocketConnectContext *context)
401 {
402     if (context == nullptr) {
403         return false;
404     }
405     if (context->GetSocketFd() > 0) {
406         NETSTACK_LOGI("socket exist: %{public}d", context->GetSocketFd());
407         return false;
408     }
409     int sock = ExecCommonUtils::MakeLocalSocket(SOCK_STREAM, false);
410     if (sock < 0) {
411         return false;
412     }
413     auto pManager = new (std::nothrow) LocalSocketManager(sock);
414     if (pManager == nullptr) {
415         return false;
416     }
417     if (!SetSocketManager(env, thisVal, context, pManager)) {
418         delete pManager;
419         return false;
420     }
421     context->SetExecOK(true);
422     return true;
423 }
424 
MakeLocalServerSocket(napi_env env,napi_value thisVal,LocalSocketServerListenContext * context)425 static bool MakeLocalServerSocket(napi_env env, napi_value thisVal, LocalSocketServerListenContext *context)
426 {
427     if (context == nullptr) {
428         return false;
429     }
430     if (int sock = context->GetSocketFd(); sock > 0) {
431         NETSTACK_LOGI("socket exist: %{public}d", sock);
432         return false;
433     }
434     int sock = ExecCommonUtils::MakeLocalSocket(SOCK_STREAM);
435     if (sock < 0) {
436         return false;
437     }
438     auto pManager = new (std::nothrow) LocalSocketServerManager(sock);
439     if (pManager == nullptr) {
440         return false;
441     }
442 #if !defined(MAC_PLATFORM) && !defined(IOS_PLATFORM)
443     if (pManager->StartEpoll() < 0) {
444         NETSTACK_LOGE("localsocket server start epoll err, sock: %{public}d", sock);
445         close(sock);
446         delete pManager;
447         return false;
448     }
449 #endif
450     if (!SetSocketManager(env, thisVal, context, pManager)) {
451 #if !defined(MAC_PLATFORM) && !defined(IOS_PLATFORM)
452         close(sock);
453         close(pManager->epollFd_);
454 #endif
455         delete pManager;
456         return false;
457     }
458     context->SetExecOK(true);
459     return true;
460 }
461 
InitSocketModule(napi_env env,napi_value exports)462 napi_value SocketModuleExports::InitSocketModule(napi_env env, napi_value exports)
463 {
464     TlsSocket::TLSSocketModuleExports::InitTLSSocketModule(env, exports);
465     TlsSocketServer::TLSSocketServerModuleExports::InitTLSSocketServerModule(env, exports);
466     DefineUDPSocketClass(env, exports);
467     DefineMulticastSocketClass(env, exports);
468     DefineTCPServerSocketClass(env, exports);
469     DefineTCPSocketClass(env, exports);
470     DefineLocalSocketClass(env, exports);
471     DefineLocalSocketServerClass(env, exports);
472     InitSocketProxyProperties(env, exports);
473     InitSocketProperties(env, exports);
474     NapiUtils::SetEnvValid(env);
475     auto envWrapper = new (std::nothrow)napi_env;
476     if (envWrapper == nullptr) {
477         return exports;
478     }
479     *envWrapper = env;
480     napi_add_env_cleanup_hook(env, NapiUtils::HookForEnvCleanup, envWrapper);
481     return exports;
482 }
483 
ConstructUDPSocketInstance(napi_env env,napi_callback_info info)484 napi_value SocketModuleExports::ConstructUDPSocketInstance(napi_env env, napi_callback_info info)
485 {
486     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_UDP_SOCKET, Finalize);
487 }
488 
ConstructMulticastSocketInstance(napi_env env,napi_callback_info info)489 napi_value SocketModuleExports::ConstructMulticastSocketInstance(napi_env env, napi_callback_info info)
490 {
491     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_MULTICAST_SOCKET, Finalize);
492 }
493 
ConstructLocalSocketInstance(napi_env env,napi_callback_info info)494 napi_value SocketModuleExports::ConstructLocalSocketInstance(napi_env env, napi_callback_info info)
495 {
496     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_LOCAL_SOCKET, FinalizeLocalSocket);
497 }
498 
ConstructLocalSocketServerInstance(napi_env env,napi_callback_info info)499 napi_value SocketModuleExports::ConstructLocalSocketServerInstance(napi_env env, napi_callback_info info)
500 {
501     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_LOCAL_SOCKET_SERVER,
502         FinalizeLocalsocketServer);
503 }
504 
DefineUDPSocketClass(napi_env env,napi_value exports)505 void SocketModuleExports::DefineUDPSocketClass(napi_env env, napi_value exports)
506 {
507     std::initializer_list<napi_property_descriptor> properties = {
508         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_BIND, UDPSocket::Bind),
509         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_SEND, UDPSocket::Send),
510         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_CLOSE, UDPSocket::Close),
511         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_STATE, UDPSocket::GetState),
512         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_LOCAL_ADDRESS, UDPSocket::GetLocalAddress),
513         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_SET_EXTRA_OPTIONS, UDPSocket::SetExtraOptions),
514         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_SOCKET_FD, UDPSocket::GetSocketFd),
515         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_ON, UDPSocket::On),
516         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_OFF, UDPSocket::Off),
517     };
518     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_UDP_SOCKET);
519 }
520 
DefineMulticastSocketClass(napi_env env,napi_value exports)521 void SocketModuleExports::DefineMulticastSocketClass(napi_env env, napi_value exports)
522 {
523     std::initializer_list<napi_property_descriptor> properties = {
524         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_BIND, MulticastSocket::Bind),
525         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SEND, MulticastSocket::Send),
526         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_CLOSE, MulticastSocket::Close),
527         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_STATE, MulticastSocket::GetState),
528         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SET_EXTRA_OPTIONS, MulticastSocket::SetExtraOptions),
529         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_SOCKET_FD, MulticastSocket::GetSocketFd),
530         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_LOCAL_ADDRESS, MulticastSocket::GetLocalAddress),
531         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_ON, MulticastSocket::On),
532         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_OFF, MulticastSocket::Off),
533         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_ADD_MEMBER_SHIP, MulticastSocket::AddMembership),
534         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_DROP_MEMBER_SHIP, MulticastSocket::DropMembership),
535         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SET_MULTICAST_TTL, MulticastSocket::SetMulticastTTL),
536         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_MULTICAST_TTL, MulticastSocket::GetMulticastTTL),
537         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SET_LOOPBACK_MODE, MulticastSocket::SetLoopbackMode),
538         DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_LOOPBACK_MODE, MulticastSocket::GetLoopbackMode),
539     };
540     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_MULTICAST_SOCKET);
541 }
542 
ConstructTCPSocketInstance(napi_env env,napi_callback_info info)543 napi_value SocketModuleExports::ConstructTCPSocketInstance(napi_env env, napi_callback_info info)
544 {
545     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_TCP_SOCKET, Finalize);
546 }
547 
DefineTCPSocketClass(napi_env env,napi_value exports)548 void SocketModuleExports::DefineTCPSocketClass(napi_env env, napi_value exports)
549 {
550     std::initializer_list<napi_property_descriptor> properties = {
551         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_BIND, TCPSocket::Bind),
552         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CONNECT, TCPSocket::Connect),
553         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SEND, TCPSocket::Send),
554         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CLOSE, TCPSocket::Close),
555         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_REMOTE_ADDRESS, TCPSocket::GetRemoteAddress),
556         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_LOCAL_ADDRESS, TCPSocket::GetLocalAddress),
557         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_STATE, TCPSocket::GetState),
558         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPSocket::SetExtraOptions),
559         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_SOCKET_FD, TCPSocket::GetSocketFd),
560         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_ON, TCPSocket::On),
561         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_OFF, TCPSocket::Off),
562     };
563     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_TCP_SOCKET);
564 }
565 
DefineLocalSocketClass(napi_env env,napi_value exports)566 void SocketModuleExports::DefineLocalSocketClass(napi_env env, napi_value exports)
567 {
568     std::initializer_list<napi_property_descriptor> properties = {
569         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_BIND, LocalSocket::Bind),
570         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_CONNECT, LocalSocket::Connect),
571         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_SEND, LocalSocket::Send),
572         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_CLOSE, LocalSocket::Close),
573         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_STATE, LocalSocket::GetState),
574         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_LOCAL_ADDRESS, LocalSocket::GetLocalAddress),
575         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_SET_EXTRA_OPTIONS, LocalSocket::SetExtraOptions),
576         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_EXTRA_OPTIONS, LocalSocket::GetExtraOptions),
577         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_SOCKET_FD, LocalSocket::GetSocketFd),
578         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_ON, LocalSocket::On),
579         DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_OFF, LocalSocket::Off),
580     };
581     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_LOCAL_SOCKET);
582 }
583 
DefineLocalSocketServerClass(napi_env env,napi_value exports)584 void SocketModuleExports::DefineLocalSocketServerClass(napi_env env, napi_value exports)
585 {
586     std::initializer_list<napi_property_descriptor> properties = {
587         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_LISTEN, LocalSocketServer::Listen),
588         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_CLOSE, LocalSocketServer::Close),
589         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_GET_STATE, LocalSocketServer::GetState),
590         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_GET_LOCAL_ADDRESS, LocalSocketServer::GetLocalAddress),
591         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_SET_EXTRA_OPTIONS, LocalSocketServer::SetExtraOptions),
592         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_GET_EXTRA_OPTIONS, LocalSocketServer::GetExtraOptions),
593         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_ON, LocalSocketServer::On),
594         DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_OFF, LocalSocketServer::Off),
595     };
596     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_LOCAL_SOCKET_SERVER);
597 }
598 
ConstructTCPSocketServerInstance(napi_env env,napi_callback_info info)599 napi_value SocketModuleExports::ConstructTCPSocketServerInstance(napi_env env, napi_callback_info info)
600 {
601     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_TCP_SOCKET_SERVER,
602         FinalizeTcpSocketServer);
603 }
604 
CloseServer(napi_env env,napi_callback_info info)605 static napi_value CloseServer(napi_env env, napi_callback_info info)
606 {
607     napi_value thisVal = nullptr;
608     if (napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr) != napi_ok) {
609         return NapiUtils::GetUndefined(env);
610     }
611     std::shared_ptr<EventManager> *sharedManager = nullptr;
612     napi_unwrap(env, thisVal, reinterpret_cast<void**>(&sharedManager));
613     if (sharedManager != nullptr && *sharedManager != nullptr) {
614         auto manager = *sharedManager;
615         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData()));
616         if (sock != -1) {
617             SocketExec::SingletonSocketConfig::GetInstance().RemoveServerSocket(sock);
618             NETSTACK_LOGI("Close TcpSocketServer");
619             shutdown(sock, SHUT_RDWR);
620             manager->SetData(reinterpret_cast<void *>(-1));
621         }
622     }
623     return NapiUtils::GetUndefined(env);
624 }
625 
DefineTCPServerSocketClass(napi_env env,napi_value exports)626 void SocketModuleExports::DefineTCPServerSocketClass(napi_env env, napi_value exports)
627 {
628     std::initializer_list<napi_property_descriptor> properties = {
629         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_LISTEN, TCPServerSocket::Listen),
630         DECLARE_NAPI_FUNCTION("close", CloseServer),
631         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_GET_STATE, TCPServerSocket::GetState),
632         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_GET_LOCAL_ADDRESS, TCPServerSocket::GetLocalAddress),
633         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPServerSocket::SetExtraOptions),
634         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_ON, TCPServerSocket::On),
635         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_OFF, TCPServerSocket::Off),
636     };
637     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_TCP_SOCKET_SERVER);
638 }
639 
InitSocketProxyProperties(napi_env env,napi_value exports)640 void SocketModuleExports::InitSocketProxyProperties(napi_env env, napi_value exports)
641 {
642     NapiUtils::DefineProperties(env, exports, {
643         DECLARE_NAPI_STATIC_PROPERTY(SOCKETPROXYTYPE_NONE,
644             NapiUtils::CreateUint32(env, static_cast<uint32_t>(ProxyType::NONE))),
645         DECLARE_NAPI_STATIC_PROPERTY(SOCKETPROXYTYPE_SOCKS5,
646             NapiUtils::CreateUint32(env, static_cast<uint32_t>(ProxyType::SOCKS5))),
647     });
648 
649     std::initializer_list<napi_property_descriptor> properties = {
650         DECLARE_NAPI_STATIC_PROPERTY(SOCKETPROXYTYPE_NONE,
651             NapiUtils::CreateUint32(env, static_cast<uint32_t>(ProxyType::NONE))),
652         DECLARE_NAPI_STATIC_PROPERTY(SOCKETPROXYTYPE_SOCKS5,
653             NapiUtils::CreateUint32(env, static_cast<uint32_t>(ProxyType::SOCKS5))),
654     };
655 
656     napi_value socks5Properties = NapiUtils::CreateObject(env);
657     NapiUtils::DefineProperties(env, socks5Properties, properties);
658 
659     NapiUtils::SetNamedProperty(env, exports, SOCKETPROXYTYPE, socks5Properties);
660 }
661 
InitSocketProperties(napi_env env,napi_value exports)662 void SocketModuleExports::InitSocketProperties(napi_env env, napi_value exports)
663 {
664     std::initializer_list<napi_property_descriptor> properties = {
665         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_UDP_SOCKET_INSTANCE, ConstructUDPSocketInstance),
666         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_MULTICAST_SOCKET_INSTANCE, ConstructMulticastSocketInstance),
667         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TCP_SOCKET_SERVER_INSTANCE, ConstructTCPSocketServerInstance),
668         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TCP_SOCKET_INSTANCE, ConstructTCPSocketInstance),
669         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_LOCAL_SOCKET_INSTANCE, ConstructLocalSocketInstance),
670         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_LOCAL_SOCKET_SERVER_INSTANCE, ConstructLocalSocketServerInstance),
671     };
672     NapiUtils::DefineProperties(env, exports, properties);
673 }
674 
675 /* udp async works */
Bind(napi_env env,napi_callback_info info)676 napi_value SocketModuleExports::UDPSocket::Bind(napi_env env, napi_callback_info info)
677 {
678     return SOCKET_INTERFACE(BindContext, ExecUdpBind, BindCallback, MakeUdpSocket, UDP_BIND_NAME);
679 }
680 
Send(napi_env env,napi_callback_info info)681 napi_value SocketModuleExports::UDPSocket::Send(napi_env env, napi_callback_info info)
682 {
683     return ModuleTemplate::InterfaceWithOutAsyncWorkWithSharedManager<UdpSendContext>(
684         env, info,
685         [](napi_env, napi_value, UdpSendContext *context) -> bool {
686             SocketAsyncWork::ExecUdpSend(context->GetEnv(), context);
687             return true;
688         },
689         UDP_SEND_NAME, SocketAsyncWork::ExecUdpSend, SocketAsyncWork::UdpSendCallback);
690 }
691 
Close(napi_env env,napi_callback_info info)692 napi_value SocketModuleExports::UDPSocket::Close(napi_env env, napi_callback_info info)
693 {
694     return SOCKET_INTERFACE(CloseContext, ExecClose, CloseCallback, nullptr, UDP_CLOSE_NAME);
695 }
696 
GetState(napi_env env,napi_callback_info info)697 napi_value SocketModuleExports::UDPSocket::GetState(napi_env env, napi_callback_info info)
698 {
699     return SOCKET_INTERFACE(GetStateContext, ExecGetState, GetStateCallback, nullptr, UDP_GET_STATE);
700 }
701 
GetLocalAddress(napi_env env,napi_callback_info info)702 napi_value SocketModuleExports::UDPSocket::GetLocalAddress(napi_env env, napi_callback_info info)
703 {
704     return SOCKET_INTERFACE(GetLocalAddressContext, ExecGetLocalAddress, GetLocalAddressCallback, nullptr,
705                             UDP_GET_LOCAL_ADDRESS);
706 }
707 
SetExtraOptions(napi_env env,napi_callback_info info)708 napi_value SocketModuleExports::UDPSocket::SetExtraOptions(napi_env env, napi_callback_info info)
709 {
710     return SOCKET_INTERFACE(UdpSetExtraOptionsContext, ExecUdpSetExtraOptions, UdpSetExtraOptionsCallback, nullptr,
711                             UDP_SET_EXTRA_OPTIONS_NAME);
712 }
713 
GetSocketFd(napi_env env,napi_callback_info info)714 napi_value SocketModuleExports::UDPSocket::GetSocketFd(napi_env env, napi_callback_info info)
715 {
716     return SOCKET_INTERFACE(GetSocketFdContext, ExecUdpGetSocketFd, UdpGetSocketFdCallback, nullptr, UDP_GET_SOCKET_FD);
717 }
718 
On(napi_env env,napi_callback_info info)719 napi_value SocketModuleExports::UDPSocket::On(napi_env env, napi_callback_info info)
720 {
721     return ModuleTemplate::OnSharedManager(env, info,
722         {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE}, false);
723 }
724 
Off(napi_env env,napi_callback_info info)725 napi_value SocketModuleExports::UDPSocket::Off(napi_env env, napi_callback_info info)
726 {
727     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE});
728 }
729 
730 /* udp multicast */
AddMembership(napi_env env,napi_callback_info info)731 napi_value SocketModuleExports::MulticastSocket::AddMembership(napi_env env, napi_callback_info info)
732 {
733     return SOCKET_INTERFACE(MulticastMembershipContext, ExecUdpAddMembership, UdpAddMembershipCallback,
734                             MakeMulticastUdpSocket, UDP_ADD_MEMBERSHIP);
735 }
736 
DropMembership(napi_env env,napi_callback_info info)737 napi_value SocketModuleExports::MulticastSocket::DropMembership(napi_env env, napi_callback_info info)
738 {
739     return SOCKET_INTERFACE(MulticastMembershipContext, ExecUdpDropMembership, UdpDropMembershipCallback, nullptr,
740                             UDP_DROP_MEMBERSHIP);
741 }
742 
GetLocalAddress(napi_env env,napi_callback_info info)743 napi_value SocketModuleExports::MulticastSocket::GetLocalAddress(napi_env env, napi_callback_info info)
744 {
745     return SOCKET_INTERFACE(GetLocalAddressContext, ExecGetLocalAddress, GetLocalAddressCallback, nullptr,
746                             UDP_GET_LOCAL_ADDRESS);
747 }
748 
SetMulticastTTL(napi_env env,napi_callback_info info)749 napi_value SocketModuleExports::MulticastSocket::SetMulticastTTL(napi_env env, napi_callback_info info)
750 {
751     return SOCKET_INTERFACE(MulticastSetTTLContext, ExecSetMulticastTTL, UdpSetMulticastTTLCallback, nullptr,
752                             UDP_SET_MULTICAST_TTL);
753 }
754 
GetMulticastTTL(napi_env env,napi_callback_info info)755 napi_value SocketModuleExports::MulticastSocket::GetMulticastTTL(napi_env env, napi_callback_info info)
756 {
757     return SOCKET_INTERFACE(MulticastGetTTLContext, ExecGetMulticastTTL, UdpGetMulticastTTLCallback, nullptr,
758                             UDP_GET_MULTICAST_TTL);
759 }
760 
SetLoopbackMode(napi_env env,napi_callback_info info)761 napi_value SocketModuleExports::MulticastSocket::SetLoopbackMode(napi_env env, napi_callback_info info)
762 {
763     return SOCKET_INTERFACE(MulticastSetLoopbackContext, ExecSetLoopbackMode, UdpSetLoopbackModeCallback, nullptr,
764                             UDP_SET_LOOPBACK_MODE);
765 }
766 
GetLoopbackMode(napi_env env,napi_callback_info info)767 napi_value SocketModuleExports::MulticastSocket::GetLoopbackMode(napi_env env, napi_callback_info info)
768 {
769     return SOCKET_INTERFACE(MulticastGetLoopbackContext, ExecGetLoopbackMode, UdpGetLoopbackModeCallback, nullptr,
770                             UDP_GET_LOOPBACK_MODE);
771 }
772 
773 /* tcp async works */
Bind(napi_env env,napi_callback_info info)774 napi_value SocketModuleExports::TCPSocket::Bind(napi_env env, napi_callback_info info)
775 {
776     return SOCKET_INTERFACE(BindContext, ExecTcpBind, BindCallback, MakeTcpClientBindSocket, TCP_BIND_NAME);
777 }
778 
Connect(napi_env env,napi_callback_info info)779 napi_value SocketModuleExports::TCPSocket::Connect(napi_env env, napi_callback_info info)
780 {
781     return SOCKET_INTERFACE(ConnectContext, ExecConnect, ConnectCallback, MakeTcpClientConnectSocket, TCP_CONNECT_NAME);
782 }
783 
Send(napi_env env,napi_callback_info info)784 napi_value SocketModuleExports::TCPSocket::Send(napi_env env, napi_callback_info info)
785 {
786     return ModuleTemplate::InterfaceWithOutAsyncWorkWithSharedManager<TcpSendContext>(
787         env, info,
788         [](napi_env, napi_value, TcpSendContext *context) -> bool {
789             SocketAsyncWork::ExecTcpSend(context->GetEnv(), context);
790             return true;
791         },
792         TCP_SEND_NAME, SocketAsyncWork::ExecTcpSend, SocketAsyncWork::TcpSendCallback);
793 }
794 
Close(napi_env env,napi_callback_info info)795 napi_value SocketModuleExports::TCPSocket::Close(napi_env env, napi_callback_info info)
796 {
797     return SOCKET_INTERFACE(CloseContext, ExecClose, CloseCallback, nullptr, TCP_CLOSE_NAME);
798 }
799 
GetRemoteAddress(napi_env env,napi_callback_info info)800 napi_value SocketModuleExports::TCPSocket::GetRemoteAddress(napi_env env, napi_callback_info info)
801 {
802     return SOCKET_INTERFACE(GetRemoteAddressContext, ExecGetRemoteAddress, GetRemoteAddressCallback, nullptr,
803                             TCP_GET_REMOTE_ADDRESS);
804 }
805 
GetLocalAddress(napi_env env,napi_callback_info info)806 napi_value SocketModuleExports::TCPSocket::GetLocalAddress(napi_env env, napi_callback_info info)
807 {
808     return SOCKET_INTERFACE(GetLocalAddressContext, ExecGetLocalAddress, GetLocalAddressCallback, nullptr,
809                             TCP_GET_LOCAL_ADDRESS);
810 }
811 
GetState(napi_env env,napi_callback_info info)812 napi_value SocketModuleExports::TCPSocket::GetState(napi_env env, napi_callback_info info)
813 {
814     return SOCKET_INTERFACE(GetStateContext, ExecGetState, GetStateCallback, nullptr, TCP_GET_STATE);
815 }
816 
SetExtraOptions(napi_env env,napi_callback_info info)817 napi_value SocketModuleExports::TCPSocket::SetExtraOptions(napi_env env, napi_callback_info info)
818 {
819     return SOCKET_INTERFACE(TcpSetExtraOptionsContext, ExecTcpSetExtraOptions, TcpSetExtraOptionsCallback, nullptr,
820                             TCP_SET_EXTRA_OPTIONS_NAME);
821 }
822 
GetSocketFd(napi_env env,napi_callback_info info)823 napi_value SocketModuleExports::TCPSocket::GetSocketFd(napi_env env, napi_callback_info info)
824 {
825     return SOCKET_INTERFACE(GetSocketFdContext, ExecTcpGetSocketFd, TcpGetSocketFdCallback, nullptr, TCP_GET_SOCKET_FD);
826 }
827 
On(napi_env env,napi_callback_info info)828 napi_value SocketModuleExports::TCPSocket::On(napi_env env, napi_callback_info info)
829 {
830     return ModuleTemplate::OnSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
831 }
832 
Off(napi_env env,napi_callback_info info)833 napi_value SocketModuleExports::TCPSocket::Off(napi_env env, napi_callback_info info)
834 {
835     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
836 }
837 
838 /* tcp connection async works */
Send(napi_env env,napi_callback_info info)839 napi_value SocketModuleExports::TCPConnection::Send(napi_env env, napi_callback_info info)
840 {
841     return SOCKET_INTERFACE(
842         TcpServerSendContext, ExecTcpConnectionSend, TcpConnectionSendCallback,
843         [](napi_env theEnv, napi_value thisVal, TcpServerSendContext *context) -> bool {
844             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
845             return true;
846         },
847         TCP_CONNECTION_SEND_NAME);
848 }
849 
Close(napi_env env,napi_callback_info info)850 napi_value SocketModuleExports::TCPConnection::Close(napi_env env, napi_callback_info info)
851 {
852     return SOCKET_INTERFACE(
853         TcpServerCloseContext, ExecTcpConnectionClose, TcpConnectionCloseCallback,
854         [](napi_env theEnv, napi_value thisVal, TcpServerCloseContext *context) -> bool {
855             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
856             return true;
857         },
858         TCP_CONNECTION_CLOSE_NAME);
859 }
860 
GetRemoteAddress(napi_env env,napi_callback_info info)861 napi_value SocketModuleExports::TCPConnection::GetRemoteAddress(napi_env env, napi_callback_info info)
862 {
863     return SOCKET_INTERFACE(
864         TcpServerGetRemoteAddressContext, ExecTcpConnectionGetRemoteAddress, TcpConnectionGetRemoteAddressCallback,
865         [](napi_env theEnv, napi_value thisVal, TcpServerGetRemoteAddressContext *context) -> bool {
866             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
867             return true;
868         },
869         TCP_CONNECTION_GET_REMOTE_ADDRESS);
870 }
871 
GetLocalAddress(napi_env env,napi_callback_info info)872 napi_value SocketModuleExports::TCPConnection::GetLocalAddress(napi_env env, napi_callback_info info)
873 {
874     return SOCKET_INTERFACE(
875         TcpConnectionGetLocalAddressContext, ExecTcpConnectionGetLocalAddress, TcpConnectionGetLocalAddressCallback,
876         [](napi_env theEnv, napi_value thisVal, TcpServerGetLocalAddressContext *context) -> bool {
877             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
878             return true;
879         },
880         TCP_CONNECTION_GET_LOCAL_ADDRESS);
881 }
882 
On(napi_env env,napi_callback_info info)883 napi_value SocketModuleExports::TCPConnection::On(napi_env env, napi_callback_info info)
884 {
885     napi_value ret = ModuleTemplate::OnSharedManager(env, info,
886         {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
887     SocketExec::NotifyRegisterEvent();
888     return ret;
889 }
890 
Off(napi_env env,napi_callback_info info)891 napi_value SocketModuleExports::TCPConnection::Off(napi_env env, napi_callback_info info)
892 {
893     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
894 }
895 
896 /* tcp server async works */
Listen(napi_env env,napi_callback_info info)897 napi_value SocketModuleExports::TCPServerSocket::Listen(napi_env env, napi_callback_info info)
898 {
899     return SOCKET_INTERFACE(TcpServerListenContext, ExecTcpServerListen, ListenCallback, MakeTcpServerSocket,
900                             TCP_SERVER_LISTEN_NAME);
901 }
902 
GetState(napi_env env,napi_callback_info info)903 napi_value SocketModuleExports::TCPServerSocket::GetState(napi_env env, napi_callback_info info)
904 {
905     return SOCKET_INTERFACE(TcpServerGetStateContext, ExecTcpServerGetState, TcpServerGetStateCallback, nullptr,
906                             TCP_SERVER_GET_STATE);
907 }
908 
GetLocalAddress(napi_env env,napi_callback_info info)909 napi_value SocketModuleExports::TCPServerSocket::GetLocalAddress(napi_env env, napi_callback_info info)
910 {
911     return SOCKET_INTERFACE(TcpServerGetLocalAddressContext, ExecTcpServerGetLocalAddress,
912                             TcpServerGetLocalAddressCallback, nullptr, TCP_SERVER_GET_LOCAL_ADDRESS);
913 }
914 
SetExtraOptions(napi_env env,napi_callback_info info)915 napi_value SocketModuleExports::TCPServerSocket::SetExtraOptions(napi_env env, napi_callback_info info)
916 {
917     return SOCKET_INTERFACE(TcpServerSetExtraOptionsContext, ExecTcpServerSetExtraOptions,
918                             TcpServerSetExtraOptionsCallback, nullptr, TCP_SERVER_SET_EXTRA_OPTIONS_NAME);
919 }
920 
On(napi_env env,napi_callback_info info)921 napi_value SocketModuleExports::TCPServerSocket::On(napi_env env, napi_callback_info info)
922 {
923     return ModuleTemplate::OnSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
924 }
925 
Off(napi_env env,napi_callback_info info)926 napi_value SocketModuleExports::TCPServerSocket::Off(napi_env env, napi_callback_info info)
927 {
928     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
929 }
930 
931 /* local socket */
Bind(napi_env env,napi_callback_info info)932 napi_value SocketModuleExports::LocalSocket::Bind(napi_env env, napi_callback_info info)
933 {
934     return SOCKET_INTERFACE(LocalSocketBindContext, ExecLocalSocketBind, LocalSocketBindCallback, MakeLocalSocketBind,
935                             LOCAL_SOCKET_BIND);
936 }
937 
Connect(napi_env env,napi_callback_info info)938 napi_value SocketModuleExports::LocalSocket::Connect(napi_env env, napi_callback_info info)
939 {
940     return SOCKET_INTERFACE(LocalSocketConnectContext, ExecLocalSocketConnect, LocalSocketConnectCallback,
941                             MakeLocalSocketConnect, LOCAL_SOCKET_CONNECT);
942 }
943 
Send(napi_env env,napi_callback_info info)944 napi_value SocketModuleExports::LocalSocket::Send(napi_env env, napi_callback_info info)
945 {
946     return ModuleTemplate::InterfaceWithOutAsyncWorkWithSharedManager<LocalSocketSendContext>(
947         env, info,
948         [](napi_env, napi_value, LocalSocketSendContext *context) -> bool {
949             SocketAsyncWork::ExecLocalSocketSend(context->GetEnv(), context);
950             return true;
951         },
952         LOCAL_SOCKET_SEND, SocketAsyncWork::ExecLocalSocketSend, SocketAsyncWork::LocalSocketSendCallback);
953 }
954 
Close(napi_env env,napi_callback_info info)955 napi_value SocketModuleExports::LocalSocket::Close(napi_env env, napi_callback_info info)
956 {
957     return SOCKET_INTERFACE(LocalSocketCloseContext, ExecLocalSocketClose, LocalSocketCloseCallback, nullptr,
958                             LOCAL_SOCKET_CLOSE);
959 }
960 
GetState(napi_env env,napi_callback_info info)961 napi_value SocketModuleExports::LocalSocket::GetState(napi_env env, napi_callback_info info)
962 {
963     return SOCKET_INTERFACE(LocalSocketGetStateContext, ExecLocalSocketGetState, LocalSocketGetStateCallback, nullptr,
964                             LOCAL_SOCKET_GET_STATE);
965 }
966 
GetLocalAddress(napi_env env,napi_callback_info info)967 napi_value SocketModuleExports::LocalSocket::GetLocalAddress(napi_env env, napi_callback_info info)
968 {
969     return SOCKET_INTERFACE(LocalSocketGetLocalAddressContext, ExecLocalSocketGetLocalAddress,
970                             LocalSocketGetLocalAddressCallback, nullptr, LOCAL_SOCKET_GET_LOCAL_ADDRESS);
971 }
972 
GetSocketFd(napi_env env,napi_callback_info info)973 napi_value SocketModuleExports::LocalSocket::GetSocketFd(napi_env env, napi_callback_info info)
974 {
975     return SOCKET_INTERFACE(LocalSocketGetSocketFdContext, ExecLocalSocketGetSocketFd, LocalSocketGetSocketFdCallback,
976                             nullptr, LOCAL_SOCKET_GET_SOCKET_FD);
977 }
978 
SetExtraOptions(napi_env env,napi_callback_info info)979 napi_value SocketModuleExports::LocalSocket::SetExtraOptions(napi_env env, napi_callback_info info)
980 {
981     return SOCKET_INTERFACE(LocalSocketSetExtraOptionsContext, ExecLocalSocketSetExtraOptions,
982                             LocalSocketSetExtraOptionsCallback, nullptr, LOCAL_SOCKET_SET_EXTRA_OPTIONS);
983 }
984 
GetExtraOptions(napi_env env,napi_callback_info info)985 napi_value SocketModuleExports::LocalSocket::GetExtraOptions(napi_env env, napi_callback_info info)
986 {
987     return SOCKET_INTERFACE(LocalSocketGetExtraOptionsContext, ExecLocalSocketGetExtraOptions,
988                             LocalSocketGetExtraOptionsCallback, nullptr, LOCAL_SOCKET_GET_EXTRA_OPTIONS);
989 }
990 
On(napi_env env,napi_callback_info info)991 napi_value SocketModuleExports::LocalSocket::On(napi_env env, napi_callback_info info)
992 {
993     return ModuleTemplate::OnSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
994 }
995 
Off(napi_env env,napi_callback_info info)996 napi_value SocketModuleExports::LocalSocket::Off(napi_env env, napi_callback_info info)
997 {
998     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
999 }
1000 
1001 /* local socket server */
Listen(napi_env env,napi_callback_info info)1002 napi_value SocketModuleExports::LocalSocketServer::Listen(napi_env env, napi_callback_info info)
1003 {
1004     return SOCKET_INTERFACE(LocalSocketServerListenContext, ExecLocalSocketServerListen,
1005                             LocalSocketServerListenCallback, MakeLocalServerSocket, LOCAL_SOCKET_SERVER_LISTEN);
1006 }
1007 
Close(napi_env env,napi_callback_info info)1008 napi_value SocketModuleExports::LocalSocketServer::Close(napi_env env, napi_callback_info info)
1009 {
1010     return SOCKET_INTERFACE(LocalSocketServerEndContext, ExecLocalSocketServerEnd,
1011                             LocalSocketServerEndCallback, nullptr, LOCAL_SOCKET_SERVER_END);
1012 }
1013 
GetState(napi_env env,napi_callback_info info)1014 napi_value SocketModuleExports::LocalSocketServer::GetState(napi_env env, napi_callback_info info)
1015 {
1016     return SOCKET_INTERFACE(LocalSocketServerGetStateContext, ExecLocalSocketServerGetState,
1017                             LocalSocketServerGetStateCallback, nullptr, LOCAL_SOCKET_SERVER_GET_STATE);
1018 }
1019 
GetLocalAddress(napi_env env,napi_callback_info info)1020 napi_value SocketModuleExports::LocalSocketServer::GetLocalAddress(napi_env env, napi_callback_info info)
1021 {
1022     return SOCKET_INTERFACE(LocalSocketServerGetLocalAddressContext, ExecLocalSocketServerGetLocalAddress,
1023                             LocalSocketServerGetLocalAddressCallback, nullptr, LOCAL_SOCKET_SERVER_GET_LOCAL_ADDRESS);
1024 }
1025 
SetExtraOptions(napi_env env,napi_callback_info info)1026 napi_value SocketModuleExports::LocalSocketServer::SetExtraOptions(napi_env env, napi_callback_info info)
1027 {
1028     return SOCKET_INTERFACE(LocalSocketServerSetExtraOptionsContext, ExecLocalSocketServerSetExtraOptions,
1029                             LocalSocketServerSetExtraOptionsCallback, nullptr, LOCAL_SOCKET_SERVER_SET_EXTRA_OPTIONS);
1030 }
1031 
GetExtraOptions(napi_env env,napi_callback_info info)1032 napi_value SocketModuleExports::LocalSocketServer::GetExtraOptions(napi_env env, napi_callback_info info)
1033 {
1034     return SOCKET_INTERFACE(LocalSocketServerGetExtraOptionsContext, ExecLocalSocketServerGetExtraOptions,
1035                             LocalSocketServerGetExtraOptionsCallback, nullptr, LOCAL_SOCKET_SERVER_GET_EXTRA_OPTIONS);
1036 }
1037 
On(napi_env env,napi_callback_info info)1038 napi_value SocketModuleExports::LocalSocketServer::On(napi_env env, napi_callback_info info)
1039 {
1040     return ModuleTemplate::OnSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
1041 }
1042 
Off(napi_env env,napi_callback_info info)1043 napi_value SocketModuleExports::LocalSocketServer::Off(napi_env env, napi_callback_info info)
1044 {
1045     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
1046 }
1047 
1048 /* localsocket connection */
Send(napi_env env,napi_callback_info info)1049 napi_value SocketModuleExports::LocalSocketConnection::Send(napi_env env, napi_callback_info info)
1050 {
1051     return SOCKET_INTERFACE(
1052         LocalSocketServerSendContext, ExecLocalSocketConnectionSend, LocalSocketConnectionSendCallback,
1053         [](napi_env theEnv, napi_value thisVal, LocalSocketServerSendContext *context) -> bool {
1054             context->SetClientId(NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID));
1055             return true;
1056         },
1057         LOCAL_SOCKET_CONNECTION_SEND);
1058 }
1059 
Close(napi_env env,napi_callback_info info)1060 napi_value SocketModuleExports::LocalSocketConnection::Close(napi_env env, napi_callback_info info)
1061 {
1062     return SOCKET_INTERFACE(
1063         LocalSocketServerCloseContext, ExecLocalSocketConnectionClose, LocalSocketConnectionCloseCallback,
1064         [](napi_env theEnv, napi_value thisVal, LocalSocketServerCloseContext *context) -> bool {
1065             context->SetClientId(NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID));
1066             return true;
1067         },
1068         LOCAL_SOCKET_CONNECTION_CLOSE);
1069 }
1070 
GetLocalAddress(napi_env env,napi_callback_info info)1071 napi_value SocketModuleExports::LocalSocketConnection::GetLocalAddress(napi_env env, napi_callback_info info)
1072 {
1073     return SOCKET_INTERFACE(
1074         LocalSocketServerGetLocalAddressContext, ExecLocalSocketConnectionGetLocalAddress,
1075         LocalSocketConnectionGetLocalAddressCallback,
1076         [](napi_env theEnv, napi_value thisVal, LocalSocketServerGetLocalAddressContext *context) -> bool {
1077             context->SetClientId(NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID));
1078             return true;
1079         }, LOCAL_SOCKET_CONNECTION_GET_LOCAL_ADDRESS);
1080 }
1081 
On(napi_env env,napi_callback_info info)1082 napi_value SocketModuleExports::LocalSocketConnection::On(napi_env env, napi_callback_info info)
1083 {
1084     napi_value thisVal = nullptr;
1085     size_t paramsCount = MAX_PARAM_NUM;
1086     napi_value params[MAX_PARAM_NUM] = {nullptr};
1087     NAPI_CALL(env, napi_get_cb_info(env, info, &paramsCount, params, &thisVal, nullptr));
1088 
1089     if (paramsCount != PARAM_COUNT_TWO || NapiUtils::GetValueType(env, params[0]) != napi_string ||
1090         NapiUtils::GetValueType(env, params[PARAM_COUNT_TWO - 1]) != napi_function) {
1091         NETSTACK_LOGE("localsocket connection on, err param");
1092         napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG);
1093         return NapiUtils::GetUndefined(env);
1094     }
1095     std::initializer_list<std::string> events = {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE};
1096     std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
1097     if (std::find(events.begin(), events.end(), event) == events.end()) {
1098         return NapiUtils::GetUndefined(env);
1099     }
1100     std::shared_ptr<EventManager> *sharedManager = nullptr;
1101     napi_unwrap(env, thisVal, reinterpret_cast<void **>(&sharedManager));
1102     if (sharedManager == nullptr || *sharedManager == nullptr) {
1103         NETSTACK_LOGE("failed to unwrap");
1104         return NapiUtils::GetUndefined(env);
1105     }
1106     auto manager = *sharedManager;
1107     manager->AddListener(env, event, params[PARAM_COUNT_TWO - 1], false, false);
1108     if (event == EVENT_MESSAGE) {
1109         if (auto mgr = reinterpret_cast<LocalSocketExec::LocalSocketConnectionData *>(manager->GetData());
1110             mgr != nullptr) {
1111             mgr->serverManager_->NotifyRegisterEvent();
1112         }
1113     }
1114     return NapiUtils::GetUndefined(env);
1115 }
1116 
Off(napi_env env,napi_callback_info info)1117 napi_value SocketModuleExports::LocalSocketConnection::Off(napi_env env, napi_callback_info info)
1118 {
1119     return ModuleTemplate::OffSharedManager(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
1120 }
1121 
1122 static napi_module g_socketModule = {
1123     .nm_version = 1,
1124     .nm_flags = 0,
1125     .nm_filename = nullptr,
1126     .nm_register_func = SocketModuleExports::InitSocketModule,
1127     .nm_modname = SOCKET_MODULE_NAME,
1128     .nm_priv = nullptr,
1129     .reserved = {nullptr},
1130 };
1131 /*
1132  * Module register function
1133  */
RegisterSocketModule(void)1134 extern "C" __attribute__((constructor)) void RegisterSocketModule(void)
1135 {
1136     napi_module_register(&g_socketModule);
1137 }
1138 } // namespace OHOS::NetStack::Socket
1139