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