From 7f2936754c5e1378f6e36d998b5b55f1718b83ca Mon Sep 17 00:00:00 2001 From: fanqibing Date: Thu, 19 Jun 2025 23:22:54 +0800 Subject: [PATCH] add close interface for server Signed-off-by: fanqibing --- .../async_work/include/socket_async_work.h | 4 +++ .../async_work/src/socket_async_work.cpp | 10 ++++++ .../socket/socket_exec/include/socket_exec.h | 4 +++ .../socket_exec/src/local_socket_exec.cpp | 9 ----- .../socket/socket_exec/src/socket_exec.cpp | 34 ++++++++++++++++++- .../socket_module/include/socket_module.h | 2 ++ .../socket_module/src/socket_module.cpp | 30 +++++----------- .../napi/tls/include/tlssocketserver_module.h | 2 ++ .../js/napi/tls/src/tls_socket_server.cpp | 10 +++--- .../js/napi/tls/src/tlssocketserver_exec.cpp | 2 -- .../napi/tls/src/tlssocketserver_module.cpp | 9 +++++ 11 files changed, 78 insertions(+), 38 deletions(-) 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 3e8753d54..1f4848a62 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 995d552a1..8dd23641a 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 1513bb492..552efc06a 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/local_socket_exec.cpp b/frameworks/js/napi/socket/socket_exec/src/local_socket_exec.cpp index a8f315e8a..a0a20e725 100644 --- a/frameworks/js/napi/socket/socket_exec/src/local_socket_exec.cpp +++ b/frameworks/js/napi/socket/socket_exec/src/local_socket_exec.cpp @@ -1024,19 +1024,10 @@ bool ExecLocalSocketServerEnd(LocalSocketServerEndContext *context) context->SetErrorCode(UNKNOW_ERROR); return false; } - mgr->SetServerDestructStatus(true); - mgr->RemoveAllAccept(); if (mgr->sockfd_ > 0) { close(mgr->sockfd_); mgr->sockfd_ = -1; } - if (mgr->epollFd_ > 0) { - close(mgr->epollFd_); - mgr->epollFd_ = -1; - } - mgr->WaitForEndingLoop(); - delete mgr; - context->GetSharedManager()->SetData(nullptr); return true; } 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 a44ddf0b0..2d15d1cf7 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); } @@ -2264,6 +2268,29 @@ 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; + } + 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()) { @@ -2527,6 +2554,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 37cdcfb28..6d31bea01 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 bfbcad5ed..f1186ab1c 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 5f8b4289b..64d6a2680 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/tls_socket_server.cpp b/frameworks/js/napi/tls/src/tls_socket_server.cpp index fe719cb14..09aa9223c 100644 --- a/frameworks/js/napi/tls/src/tls_socket_server.cpp +++ b/frameworks/js/napi/tls/src/tls_socket_server.cpp @@ -231,6 +231,10 @@ bool TLSSocketServer::ExecBind(const Socket::NetAddress &address, const ListenCa CallListenCallback(ConvertErrno(), callback); return false; } + int reuse = 1; // 1 means enable reuseaddr feature + if (setsockopt(listenSocketFd_, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&reuse), sizeof(reuse)) < 0) { + NETSTACK_LOGE("failed to set tls server listen socket reuseaddr on, sockfd: %{public}d", listenSocketFd_); + } if (bind(listenSocketFd_, addr, len) < 0) { if (errno != EADDRINUSE) { NETSTACK_LOGE("bind error is %{public}s %{public}d", strerror(errno), errno); @@ -344,10 +348,6 @@ void TLSSocketServer::Close(const int socketFd, const TlsSocket::CloseCallback & void TLSSocketServer::Stop(const TlsSocket::CloseCallback &callback) { std::lock_guard its_lock(connectMutex_); - for (const auto &c : clientIdConnections_) { - c.second->Close(); - } - clientIdConnections_.clear(); close(listenSocketFd_); listenSocketFd_ = -1; callback(TlsSocket::TLSSOCKET_SUCCESS); @@ -729,6 +729,7 @@ const TlsSocket::X509CertRawData &TLSSocketServer::Connection::GetRemoteCertRawD TLSSocketServer::Connection::~Connection() { + NETSTACK_LOGI("TLSSocketServer ~conn"); Close(); } @@ -806,6 +807,7 @@ bool TLSSocketServer::Connection::Close() if (socketFd_ != -1) { shutdown(socketFd_, SHUT_RDWR); close(socketFd_); + NETSTACK_LOGI("close connection socketFd %{public}d", socketFd_); socketFd_ = -1; } if (!tlsContextServerPointer_) { diff --git a/frameworks/js/napi/tls/src/tlssocketserver_exec.cpp b/frameworks/js/napi/tls/src/tlssocketserver_exec.cpp index 2cc79f67c..24f131dcd 100644 --- a/frameworks/js/napi/tls/src/tlssocketserver_exec.cpp +++ b/frameworks/js/napi/tls/src/tlssocketserver_exec.cpp @@ -263,8 +263,6 @@ bool TLSSocketServerExec::ExecStop(TlsSocket::TLSNapiContext *context) context->SetError(errorNumber, TlsSocket::MakeErrorMessage(errorNumber)); } }); - delete tlsSocketServer; - manager->SetData(nullptr); return context->errorNumber_ == TlsSocket::TlsSocketError::TLSSOCKET_SUCCESS; } diff --git a/frameworks/js/napi/tls/src/tlssocketserver_module.cpp b/frameworks/js/napi/tls/src/tlssocketserver_module.cpp index 2e1a868db..35cc2e035 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_SERVER = "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), -- Gitee