diff --git a/frameworks/js/napi/socket/async_work/include/socket_async_work.h b/frameworks/js/napi/socket/async_work/include/socket_async_work.h index 3e8753d546f46fce8c56fac4fc4ef7b7155e1c78..1f4848a620dc4e6ec9b3d9ec1ad90014705f7ecb 100644 --- a/frameworks/js/napi/socket/async_work/include/socket_async_work.h +++ b/frameworks/js/napi/socket/async_work/include/socket_async_work.h @@ -73,6 +73,8 @@ public: static void ExecTcpServerListen(napi_env env, void *data); + static void ExecTcpServerClose(napi_env env, void *data); + static void ExecTcpServerSetExtraOptions(napi_env env, void *data); static void ExecTcpServerGetState(napi_env env, void *data); @@ -162,6 +164,8 @@ public: static void ListenCallback(napi_env env, napi_status status, void *data); + static void TcpServerCloseCallback(napi_env env, napi_status status, void *data); + static void TcpServerSetExtraOptionsCallback(napi_env env, napi_status status, void *data); static void TcpServerGetStateCallback(napi_env env, napi_status status, void *data); diff --git a/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp b/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp index 995d552a10257b46352c5cc0d915be5758d1ab29..8dd23641a28bd99106d4063731a211075201582a 100644 --- a/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp +++ b/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp @@ -160,6 +160,11 @@ void SocketAsyncWork::ExecTcpServerListen(napi_env env, void *data) BaseAsyncWork::ExecAsyncWork(env, data); } +void SocketAsyncWork::ExecTcpServerClose(napi_env env, void *data) +{ + BaseAsyncWork::ExecAsyncWork(env, data); +} + void SocketAsyncWork::ExecTcpServerSetExtraOptions(napi_env env, void *data) { BaseAsyncWork::ExecAsyncWork(env, data); @@ -399,6 +404,11 @@ void SocketAsyncWork::ListenCallback(napi_env env, napi_status status, void *dat BaseAsyncWork::AsyncWorkCallback(env, status, data); } +void SocketAsyncWork::TcpServerCloseCallback(napi_env env, napi_status status, void *data) +{ + BaseAsyncWork::AsyncWorkCallback(env, status, data); +} + void SocketAsyncWork::TcpServerSetExtraOptionsCallback(napi_env env, napi_status status, void *data) { BaseAsyncWork::AsyncWorkCallback( diff --git a/frameworks/js/napi/socket/socket_exec/include/socket_exec.h b/frameworks/js/napi/socket/socket_exec/include/socket_exec.h index 1513bb492f78192207bcbb09dc343be7735d82bd..552efc06a0f46b7788b2892526183bb2942531ec 100644 --- a/frameworks/js/napi/socket/socket_exec/include/socket_exec.h +++ b/frameworks/js/napi/socket/socket_exec/include/socket_exec.h @@ -89,6 +89,8 @@ bool ExecTcpConnectionClose(TcpServerCloseContext *context); bool ExecTcpServerListen(TcpServerListenContext *context); +bool ExecTcpServerClose(TcpServerCloseContext *context); + bool ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext *context); bool ExecTcpServerGetState(TcpServerGetStateContext *context); @@ -140,6 +142,8 @@ napi_value TcpConnectionGetLocalAddressCallback(TcpServerGetLocalAddressContext napi_value ListenCallback(TcpServerListenContext *context); +napi_value TcpServerCloseCallback(TcpServerCloseContext *context); + napi_value TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext *context); napi_value TcpServerGetStateCallback(TcpServerGetStateContext *context); diff --git a/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp b/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp index 37c15fecc5aefc4f2c07750a0bade667b2b0c8ed..3e7145fbc55831aedefdc42ab3e7c84676adafbe 100644 --- a/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp +++ b/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp @@ -72,6 +72,8 @@ static constexpr const int ERRNO_BAD_FD = 9; static constexpr const int UNIT_CONVERSION_1000 = 1000; +static constexpr const int SYSTEM_INTERNAL_ERROR = 2300002; + static constexpr const char *TCP_SOCKET_CONNECTION = "TCPSocketConnection"; static constexpr const char *TCP_SERVER_ACCEPT_RECV_DATA = "OS_NET_SockRD"; @@ -86,6 +88,8 @@ static constexpr const char *SOCKET_RECV_FROM_MULTI_CAST = "OS_NET_SockMPRD"; static constexpr const char *WILD_ADDRESS = "0.0.0.0"; +static constexpr const char *SYSTEM_INTERNAL_ERROR_MESSAGE = "System internal error"; + namespace OHOS::NetStack::Socket::SocketExec { #define ERROR_RETURN(context, ...) \ do { \ @@ -473,7 +477,7 @@ public: void OnTcpConnectionMessage(int32_t id) const override { - if (manager_->HasEventListener(EVENT_CONNECT)) { + if (manager_ != nullptr && manager_->HasEventListener(EVENT_CONNECT)) { manager_->EmitByUvWithoutCheckShared(EVENT_CONNECT, new TcpConnection(id), ModuleTemplate::CallbackTemplate); } @@ -2242,6 +2246,38 @@ bool ExecTcpServerListen(TcpServerListenContext *context) return true; } +bool ExecTcpServerClose(TcpServerCloseContext *context) +{ + if (!CommonUtils::HasInternetPermission()) { + context->SetPermissionDenied(true); + return false; + } + int sock = context->GetSocketFd(); + if (sock == -1) { + NETSTACK_LOGI("TCPServer socket was closed before"); + return true; + } + // close all connection + auto clients = SingletonSocketConfig::GetInstance().GetClients(context->GetSocketFd()); + for (const int fd : clients) { + if (!IsClientFdClosed(fd)) { + shutdown(fd, SHUT_RDWR); + NETSTACK_LOGI("close connection in server, listenfd: %{public}d, clientFd: %{public}d", sock, fd); + } + } + g_clientFDs.clear(); + SocketExec::SingletonSocketConfig::GetInstance().RemoveServerSocket(sock); + + if (shutdown(sock, SHUT_RDWR) < 0) { + NETSTACK_LOGE("close tcp server failed, errno: %{public}d, message: %{public}s", + errno, strerror(errno)); + context->SetError(SYSTEM_INTERNAL_ERROR, SYSTEM_INTERNAL_ERROR_MESSAGE); + return false; + } + context->SetSocketFd(-1); + return true; +} + bool ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext *context) { if (!CommonUtils::HasInternetPermission()) { @@ -2505,6 +2541,11 @@ napi_value ListenCallback(TcpServerListenContext *context) return NapiUtils::GetUndefined(context->GetEnv()); } +napi_value TcpServerCloseCallback(TcpServerCloseContext *context) +{ + return NapiUtils::GetUndefined(context->GetEnv()); +} + napi_value TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext *context) { return NapiUtils::GetUndefined(context->GetEnv()); diff --git a/frameworks/js/napi/socket/socket_module/include/socket_module.h b/frameworks/js/napi/socket/socket_module/include/socket_module.h index 37cdcfb28211557d69489940a09eae0be08c081f..6d31bea01b817d7bded1bbf4cabd959072fa4f2c 100644 --- a/frameworks/js/napi/socket/socket_module/include/socket_module.h +++ b/frameworks/js/napi/socket/socket_module/include/socket_module.h @@ -173,6 +173,7 @@ public: class TCPServerSocket { public: static constexpr const char *FUNCTION_LISTEN = "listen"; + static constexpr const char *FUNCTION_CLOSE = "close"; static constexpr const char *FUNCTION_GET_STATE = "getState"; static constexpr const char *FUNCTION_GET_LOCAL_ADDRESS = "getLocalAddress"; static constexpr const char *FUNCTION_SET_EXTRA_OPTIONS = "setExtraOptions"; @@ -180,6 +181,7 @@ public: static constexpr const char *FUNCTION_OFF = "off"; static napi_value Listen(napi_env env, napi_callback_info info); + static napi_value Close(napi_env env, napi_callback_info info); static napi_value GetState(napi_env env, napi_callback_info info); static napi_value GetLocalAddress(napi_env env, napi_callback_info info); static napi_value SetExtraOptions(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/socket/socket_module/src/socket_module.cpp b/frameworks/js/napi/socket/socket_module/src/socket_module.cpp index bfbcad5edd3d55770c99ac60ccf2774b542dc439..f1186ab1c75593a22fe7ba477380da94e29bb933 100644 --- a/frameworks/js/napi/socket/socket_module/src/socket_module.cpp +++ b/frameworks/js/napi/socket/socket_module/src/socket_module.cpp @@ -106,6 +106,7 @@ static const char *TCP_SET_EXTRA_OPTIONS_NAME = "TcpSetExtraOptions"; static constexpr const char *TCP_GET_SOCKET_FD = "TcpGetSocketFd"; static constexpr const char *TCP_SERVER_LISTEN_NAME = "TcpServerListen"; +static constexpr const char *TCP_SERVER_CLOSE_NAME = "TcpServerClose"; static constexpr const char *TCP_SERVER_GET_STATE = "TcpServerGetState"; static constexpr const char *TCP_SERVER_GET_LOCAL_ADDRESS = "TcpServerGetLocalAddress"; static constexpr const char *TCP_SERVER_SET_EXTRA_OPTIONS_NAME = "TcpServerSetExtraOptions"; @@ -606,32 +607,11 @@ napi_value SocketModuleExports::ConstructTCPSocketServerInstance(napi_env env, n FinalizeTcpSocketServer); } -static napi_value CloseServer(napi_env env, napi_callback_info info) -{ - napi_value thisVal = nullptr; - if (napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr) != napi_ok) { - return NapiUtils::GetUndefined(env); - } - std::shared_ptr *sharedManager = nullptr; - napi_unwrap(env, thisVal, reinterpret_cast(&sharedManager)); - if (sharedManager != nullptr && *sharedManager != nullptr) { - auto manager = *sharedManager; - int sock = static_cast(reinterpret_cast(manager->GetData())); - if (sock != -1) { - SocketExec::SingletonSocketConfig::GetInstance().RemoveServerSocket(sock); - NETSTACK_LOGI("Close TcpSocketServer"); - shutdown(sock, SHUT_RDWR); - manager->SetData(reinterpret_cast(-1)); - } - } - return NapiUtils::GetUndefined(env); -} - void SocketModuleExports::DefineTCPServerSocketClass(napi_env env, napi_value exports) { std::initializer_list properties = { DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_LISTEN, TCPServerSocket::Listen), - DECLARE_NAPI_FUNCTION("close", CloseServer), + DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_CLOSE, TCPServerSocket::Close), DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_GET_STATE, TCPServerSocket::GetState), DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_GET_LOCAL_ADDRESS, TCPServerSocket::GetLocalAddress), DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPServerSocket::SetExtraOptions), @@ -904,6 +884,12 @@ napi_value SocketModuleExports::TCPServerSocket::Listen(napi_env env, napi_callb TCP_SERVER_LISTEN_NAME); } +napi_value SocketModuleExports::TCPServerSocket::Close(napi_env env, napi_callback_info info) +{ + return SOCKET_INTERFACE(TcpServerCloseContext, ExecTcpServerClose, TcpServerCloseCallback, nullptr, + TCP_SERVER_CLOSE_NAME); +} + napi_value SocketModuleExports::TCPServerSocket::GetState(napi_env env, napi_callback_info info) { return SOCKET_INTERFACE(TcpServerGetStateContext, ExecTcpServerGetState, TcpServerGetStateCallback, nullptr, diff --git a/frameworks/js/napi/tls/include/tlssocketserver_module.h b/frameworks/js/napi/tls/include/tlssocketserver_module.h index 5f8b4289bd35d81cb7314818a76c5abd109bb975..64d6a268056213762a494cb5f18c73bff64e40dc 100644 --- a/frameworks/js/napi/tls/include/tlssocketserver_module.h +++ b/frameworks/js/napi/tls/include/tlssocketserver_module.h @@ -26,6 +26,7 @@ public: class TLSSocketServer { public: static constexpr const char *FUNCTION_LISTEN = "listen"; + static constexpr const char *FUNCTION_STOP = "close"; static constexpr const char *FUNCTION_GET_STATE = "getState"; static constexpr const char *FUNCTION_GET_LOCAL_ADDRESS = "getLocalAddress"; static constexpr const char *FUNCTION_SET_EXTRA_OPTIONS = "setExtraOptions"; @@ -37,6 +38,7 @@ public: static napi_value GetCertificate(napi_env env, napi_callback_info info); static napi_value GetProtocol(napi_env env, napi_callback_info info); static napi_value Listen(napi_env env, napi_callback_info info); + static napi_value Stop(napi_env env, napi_callback_info info); static napi_value GetState(napi_env env, napi_callback_info info); static napi_value GetLocalAddress(napi_env env, napi_callback_info info); static napi_value SetExtraOptions(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/tls/src/tlssocketserver_module.cpp b/frameworks/js/napi/tls/src/tlssocketserver_module.cpp index 2e1a868dbaa8ce093b3da87aac1a240f7ea28a53..34b47f54329d9ca3a6201747d8d24a2b0db6e3df 100644 --- a/frameworks/js/napi/tls/src/tlssocketserver_module.cpp +++ b/frameworks/js/napi/tls/src/tlssocketserver_module.cpp @@ -40,6 +40,7 @@ namespace TlsSocketServer { namespace { static constexpr const char *PROTOCOL_TLSV13 = "TLSv13"; static constexpr const char *PROTOCOL_TLSV12 = "TLSv12"; +static constexpr const char *NAME_STOP_TLSSERVER = "closeTLSServer" void Finalize(napi_env, void *data, void *) { @@ -69,6 +70,13 @@ napi_value TLSSocketServerModuleExports::TLSSocketServer::Listen(napi_env env, n TLSSocketServerAsyncWork::ListenCallback); } +napi_value TLSSocketServerModuleExports::TLSSocketServer::Stop(napi_env env, napi_callback_info info) +{ + return ModuleTemplate::InterfaceWithSharedManager(env, info, NAME_STOP_SERVER, nullptr, + TLSSocketServerAsyncWork::ExecStop, + TLSSocketServerAsyncWork::StopCallback); +} + napi_value TLSSocketServerModuleExports::TLSSocketConnection::Send(napi_env env, napi_callback_info info) { return ModuleTemplate::InterfaceWithSharedManager( @@ -200,6 +208,7 @@ void TLSSocketServerModuleExports::DefineTLSSocketServerClass(napi_env env, napi { std::initializer_list functions = { DECLARE_NAPI_FUNCTION(TLSSocketServer::FUNCTION_LISTEN, TLSSocketServer::Listen), + DECLARE_NAPI_FUNCTION(TLSSocketServer::FUNCTION_STOP, TLSSocketServer::Stop), DECLARE_NAPI_FUNCTION(TLSSocketServer::FUNCTION_GET_STATE, TLSSocketServer::GetState), DECLARE_NAPI_FUNCTION(TLSSocketServer::FUNCTION_GET_LOCAL_ADDRESS, TLSSocketServer::GetLocalAddress), DECLARE_NAPI_FUNCTION(TLSSocketServer::FUNCTION_SET_EXTRA_OPTIONS, TLSSocketServer::SetExtraOptions),