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, ¶msCount, 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