diff --git a/services/netconnmanager/include/net_conn_service.h b/services/netconnmanager/include/net_conn_service.h index 231240ea7a3e61b31f36056815ea2b1d599f3ab3..90b906ade034f82c820a8b29253039cc7ce311ec 100644 --- a/services/netconnmanager/include/net_conn_service.h +++ b/services/netconnmanager/include/net_conn_service.h @@ -576,8 +576,12 @@ private: bool IsInRequestNetUids(int32_t uid); int32_t CheckAndCompareUid(sptr &supplier, int32_t callingUid); #ifdef FEATURE_SUPPORT_POWERMANAGER + void HandlePowerMgrEvent(int code); void StopAllNetDetection(); void StartAllNetDetection(); + void HandleForceSleepEvent(int code); + void DestroyAllNetSockets(); + int64_t sleepStartTime_ = 0; #endif void DecreaseNetActivatesForUid(const uint32_t callingUid, const sptr &callback); void DecreaseNetActivates(const uint32_t callingUid, const sptr &callback, uint32_t reqId); @@ -667,7 +671,6 @@ private: void RemoveALLClientDeathRecipient(); void OnReceiveEvent(const EventFwk::CommonEventData &data); void SubscribeCommonEvent(); - void HandlePowerMgrEvent(int code); void HandleScreenEvent(bool isScreenOn); std::mutex remoteMutex_; sptr deathRecipient_ = nullptr; diff --git a/services/netconnmanager/include/network.h b/services/netconnmanager/include/network.h index 11abb4b1fe9cf11556a485c77151c318f09a56d5..617f4359f5cb2bba3e425fb21e5d82de9542fa54 100644 --- a/services/netconnmanager/include/network.h +++ b/services/netconnmanager/include/network.h @@ -116,6 +116,7 @@ private: #ifdef FEATURE_SUPPORT_POWERMANAGER bool forbidDetectionFlag_ = false; + void DestroyNetSockets(); #endif bool isNeedResume_ = false; bool isScreenOn_ = true; diff --git a/services/netconnmanager/src/net_conn_service.cpp b/services/netconnmanager/src/net_conn_service.cpp index dd409f4da4fd56609e6ddc24eee8c72b3d2afd89..8f20243ee4ea9f2fe46e4d4f77c4448fa19b225e 100644 --- a/services/netconnmanager/src/net_conn_service.cpp +++ b/services/netconnmanager/src/net_conn_service.cpp @@ -54,6 +54,9 @@ namespace NetManagerStandard { namespace { constexpr uint32_t MAX_ALLOW_UID_NUM = 2000; constexpr uint32_t INVALID_SUPPLIER_ID = 0; +#ifdef FEATURE_SUPPORT_POWERMANAGER +static constexpr const unsigned int FORCE_SLEEP_TIMEOUT_TIME = 1 * 60 * 1000; // ms +#endif // hisysevent error messgae constexpr const char *ERROR_MSG_NULL_SUPPLIER_INFO = "Net supplier info is nullptr"; constexpr const char *ERROR_MSG_NULL_NET_LINK_INFO = "Net link info is nullptr"; @@ -751,6 +754,7 @@ void NetConnService::StartAllNetDetection() void NetConnService::HandlePowerMgrEvent(int code) { + HandleForceSleepEvent(code); if (code == STATE_ENTER_FORCESLEEP || code == STATE_ENTER_SLEEP_NOT_FORCE) { NETMGR_LOG_I("on receive enter sleep, code %{public}d.", code); if (netConnEventHandler_) { @@ -769,6 +773,39 @@ void NetConnService::HandlePowerMgrEvent(int code) isInSleep_.store(false); } } + +void NetConnService::HandleForceSleepEvent(int code) +{ + if (code == STATE_ENTER_FORCESLEEP) { + auto now = std::chrono::steady_clock::now(); + sleepStartTime_ = std::chrono::duration_cast(now.time_since_epoch()).count(); + NETMGR_LOG_D("enter force sleep, time = %{public}ld", sleepStartTime_); + } else if (code == STATE_EXIT_FORCESLEEP) { + if (sleepStartTime_ == 0) { // 未监听到ENTER_FORCE_SLEEP,不作处理 + return; + } + auto now = std::chrono::steady_clock::now(); + int64_t sleepExitTime = std::chrono::duration_cast(now.time_since_epoch()).count(); + if (sleepExitTime - sleepStartTime_ < FORCE_SLEEP_TIMEOUT_TIME) { + sleepStartTime_ = 0; + return; + } + NETMGR_LOG_I("sleep duration time: %{public}ld, ready to destroy all sockets", + sleepExitTime - sleepStartTime_); + DestroyAllNetSockets(); + sleepStartTime_ = 0; + } +} + +void NetConnService::DestroyAllNetSockets() +{ + NETMGR_LOG_D("enter DestroyAllNetSockets"); + for (const auto &network : networks_) { + if (network.second != nullptr && network.second->IsConnected()) { + network.second->DestroyNetSockets(); + } + } +} #endif void NetConnService::HandleScreenEvent(bool isScreenOn) diff --git a/services/netconnmanager/src/network.cpp b/services/netconnmanager/src/network.cpp index 2e63c6f0ba88b5b7f69e9ef021171d9b9aeeb875..09443cd9a4184a215ad683896c51f3213b221862 100644 --- a/services/netconnmanager/src/network.cpp +++ b/services/netconnmanager/src/network.cpp @@ -142,6 +142,27 @@ std::string Network::GetNetCapabilitiesAsString(const uint32_t supplierId) const return NetConnServiceIface().GetNetCapabilitiesAsString(supplierId); } +#ifdef FEATURE_SUPPORT_POWERMANAGER +void Network::DestroyNetSockets() +{ + if (!isPhyNetCreated_ && !isVirtualCreated_) { + NETMGR_LOG_E("physical and virtual network has not created"); + return; + } + std::string netCapabilities = GetNetCapabilitiesAsString(supplierId_); + NETMGR_LOG_D("Destroy sockets for network: supplierId %{public}u, netId %{public}d, netCapabilities %{public}s", + supplierId_, netId_, netCapabilities.c_str()); + std::shared_lock lock(netLinkInfoMutex_); + NetLinkInfo netLinkInfoBck = netLinkInfo_; + lock.unlock(); + for (const auto &inetAddr : netLinkInfoBck.netAddrList_) { + int32_t prefixLen = inetAddr.prefixlen_ == 0 ? Ipv4PrefixLen(inetAddr.netMask_) : inetAddr.prefixlen_; + NetsysController::GetInstance().DelInterfaceAddress(netLinkInfoBck.ifaceName_, inetAddr.address_, prefixLen, + netCapabilities); + } +} +#endif + bool Network::ReleaseBasicNetwork() { if (!isPhyNetCreated_) { diff --git a/services/netmanagernative/src/netsys/netlink_socket_diag.cpp b/services/netmanagernative/src/netsys/netlink_socket_diag.cpp index 1ee80e9aeb74fa23bd056ca609f355cf86d04fd9..fd6e60617d17e05ebbef0b633a588a01b3f0af9c 100644 --- a/services/netmanagernative/src/netsys/netlink_socket_diag.cpp +++ b/services/netmanagernative/src/netsys/netlink_socket_diag.cpp @@ -253,6 +253,8 @@ void NetLinkSocketDiag::SockDiagDumpCallback(uint8_t proto, const inet_diag_msg NETNATIVE_LOG_D("Socket is not associated with the network"); return; } + NETNATIVE_LOG_D("socket is closed, sport: %{public}u, dport: %{public}u, uid: %{public}u", + msg->id.idiag_sport, msg->id.idiag_dport, msg->idiag_uid); ExecuteDestroySocket(proto, msg); } diff --git a/test/netconnmanager/unittest/net_conn_manager_test/net_conn_service_test.cpp b/test/netconnmanager/unittest/net_conn_manager_test/net_conn_service_test.cpp index a69861bca70d4c0d6906662ee2048b4b041363bb..68a68fb9dde9af557575d33b937e491f8f6dce95 100644 --- a/test/netconnmanager/unittest/net_conn_manager_test/net_conn_service_test.cpp +++ b/test/netconnmanager/unittest/net_conn_manager_test/net_conn_service_test.cpp @@ -1831,5 +1831,44 @@ HWTEST_F(NetConnServiceTest, SetReuseSupplierIdTest001, TestSize.Level1) EXPECT_EQ(ret, NETMANAGER_SUCCESS); } +#ifdef FEATURE_SUPPORT_POWERMANAGER +HWTEST_F(NetConnServiceTest, HandleForceSleepEventTest001, TestSize.Level1) +{ + int code = STATE_ENTER_FORCESLEEP; + auto ret = NetConnService::GetInstance()->HandleForceSleepEvent(code); + ASSERT_NE(NetConnService::GetInstance()->sleepStartTime_, 0); +} + +HWTEST_F(NetConnServiceTest, HandleForceSleepEventTest002, TestSize.Level1) +{ + int code = STATE_EXIT_FORCESLEEP; + auto instance = NetConnService::GetInstance(); + auto now = std::chrono::steady_clock::now(); + instance->sleepStartTime_ = std::chrono::duration_cast(now.time_since_epoch()).count(); + auto ret = NetConnService::GetInstance()->HandleForceSleepEvent(code); + ASSERT_EQ(instance->sleepStartTime_, 0); +} + +HWTEST_F(NetConnServiceTest, HandleForceSleepEventTest003, TestSize.Level1) +{ + int code = STATE_EXIT_FORCESLEEP; + auto instance = NetConnService::GetInstance(); + auto now = std::chrono::steady_clock::now(); + instance->sleepStartTime_ = std::chrono::duration_cast( + now.time_since_epoch()).count() - 2 * FORCE_SLEEP_TIMEOUT_TIME; + auto ret = NetConnService::GetInstance()->HandleForceSleepEvent(code); + ASSERT_EQ(instance->sleepStartTime_, 0); +} + +HWTEST_F(NetConnServiceTest, HandleForceSleepEventTest004, TestSize.Level1) +{ + int code = STATE_EXIT_FORCESLEEP; + auto instance = NetConnService::GetInstance(); + instance->sleepStartTime_ = 0; + auto ret = NetConnService::GetInstance()->HandleForceSleepEvent(code); + ASSERT_EQ(instance->sleepStartTime_, 0); +} +#endif + } // namespace NetManagerStandard } // namespace OHOS