18e745fdaSopenharmony_ci/* 28e745fdaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 38e745fdaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48e745fdaSopenharmony_ci * you may not use this file except in compliance with the License. 58e745fdaSopenharmony_ci * You may obtain a copy of the License at 68e745fdaSopenharmony_ci * 78e745fdaSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88e745fdaSopenharmony_ci * 98e745fdaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108e745fdaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118e745fdaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128e745fdaSopenharmony_ci * See the License for the specific language governing permissions and 138e745fdaSopenharmony_ci * limitations under the License. 148e745fdaSopenharmony_ci */ 158e745fdaSopenharmony_ci 168e745fdaSopenharmony_ci#include "mdns_protocol_impl.h" 178e745fdaSopenharmony_ci 188e745fdaSopenharmony_ci#include <arpa/inet.h> 198e745fdaSopenharmony_ci#include <cstddef> 208e745fdaSopenharmony_ci#include <iostream> 218e745fdaSopenharmony_ci#include <random> 228e745fdaSopenharmony_ci#include <sys/types.h> 238e745fdaSopenharmony_ci#include <unistd.h> 248e745fdaSopenharmony_ci#include <fcntl.h> 258e745fdaSopenharmony_ci 268e745fdaSopenharmony_ci#include "mdns_manager.h" 278e745fdaSopenharmony_ci#include "mdns_packet_parser.h" 288e745fdaSopenharmony_ci#include "net_conn_client.h" 298e745fdaSopenharmony_ci#include "netmgr_ext_log_wrapper.h" 308e745fdaSopenharmony_ci 318e745fdaSopenharmony_ci#include "securec.h" 328e745fdaSopenharmony_ci 338e745fdaSopenharmony_cinamespace OHOS { 348e745fdaSopenharmony_cinamespace NetManagerStandard { 358e745fdaSopenharmony_ci 368e745fdaSopenharmony_ciconstexpr uint32_t DEFAULT_INTEVAL_MS = 2000; 378e745fdaSopenharmony_ciconstexpr uint32_t DEFAULT_LOST_MS = 10000; 388e745fdaSopenharmony_ciconstexpr uint32_t DEFAULT_TTL = 120; 398e745fdaSopenharmony_ciconstexpr uint16_t MDNS_FLUSH_CACHE_BIT = 0x8000; 408e745fdaSopenharmony_ci 418e745fdaSopenharmony_ciconstexpr int PHASE_PTR = 1; 428e745fdaSopenharmony_ciconstexpr int PHASE_SRV = 2; 438e745fdaSopenharmony_ciconstexpr int PHASE_DOMAIN = 3; 448e745fdaSopenharmony_ci 458e745fdaSopenharmony_cistd::string AddrToString(const std::any &addr) 468e745fdaSopenharmony_ci{ 478e745fdaSopenharmony_ci char buf[INET6_ADDRSTRLEN] = {0}; 488e745fdaSopenharmony_ci if (std::any_cast<in_addr>(&addr)) { 498e745fdaSopenharmony_ci if (inet_ntop(AF_INET, std::any_cast<in_addr>(&addr), buf, sizeof(buf)) == nullptr) { 508e745fdaSopenharmony_ci return std::string{}; 518e745fdaSopenharmony_ci } 528e745fdaSopenharmony_ci } else if (std::any_cast<in6_addr>(&addr)) { 538e745fdaSopenharmony_ci if (inet_ntop(AF_INET6, std::any_cast<in6_addr>(&addr), buf, sizeof(buf)) == nullptr) { 548e745fdaSopenharmony_ci return std::string{}; 558e745fdaSopenharmony_ci } 568e745fdaSopenharmony_ci } 578e745fdaSopenharmony_ci return std::string(buf); 588e745fdaSopenharmony_ci} 598e745fdaSopenharmony_ci 608e745fdaSopenharmony_ciint64_t MilliSecondsSinceEpoch() 618e745fdaSopenharmony_ci{ 628e745fdaSopenharmony_ci return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()) 638e745fdaSopenharmony_ci .count(); 648e745fdaSopenharmony_ci} 658e745fdaSopenharmony_ci 668e745fdaSopenharmony_ciMDnsProtocolImpl::MDnsProtocolImpl() 678e745fdaSopenharmony_ci{ 688e745fdaSopenharmony_ci Init(); 698e745fdaSopenharmony_ci} 708e745fdaSopenharmony_ci 718e745fdaSopenharmony_civoid MDnsProtocolImpl::Init() 728e745fdaSopenharmony_ci{ 738e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log MDnsProtocolImpl init"); 748e745fdaSopenharmony_ci listener_.Stop(); 758e745fdaSopenharmony_ci listener_.CloseAllSocket(); 768e745fdaSopenharmony_ci 778e745fdaSopenharmony_ci if (config_.configAllIface) { 788e745fdaSopenharmony_ci listener_.OpenSocketForEachIface(config_.ipv6Support, config_.configLo); 798e745fdaSopenharmony_ci } else { 808e745fdaSopenharmony_ci listener_.OpenSocketForDefault(config_.ipv6Support); 818e745fdaSopenharmony_ci } 828e745fdaSopenharmony_ci listener_.SetReceiveHandler( 838e745fdaSopenharmony_ci [this](int sock, const MDnsPayload &payload) { return this->ReceivePacket(sock, payload); }); 848e745fdaSopenharmony_ci listener_.SetFinishedHandler([this](int sock) { 858e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 868e745fdaSopenharmony_ci RunTaskQueue(taskQueue_); 878e745fdaSopenharmony_ci }); 888e745fdaSopenharmony_ci listener_.Start(); 898e745fdaSopenharmony_ci 908e745fdaSopenharmony_ci taskQueue_.clear(); 918e745fdaSopenharmony_ci taskOnChange_.clear(); 928e745fdaSopenharmony_ci AddTask([this]() { return Browse(); }, false); 938e745fdaSopenharmony_ci} 948e745fdaSopenharmony_ci 958e745fdaSopenharmony_cibool MDnsProtocolImpl::Browse() 968e745fdaSopenharmony_ci{ 978e745fdaSopenharmony_ci if (lastRunTime != -1 && MilliSecondsSinceEpoch() - lastRunTime < DEFAULT_INTEVAL_MS) { 988e745fdaSopenharmony_ci return false; 998e745fdaSopenharmony_ci } 1008e745fdaSopenharmony_ci lastRunTime = MilliSecondsSinceEpoch(); 1018e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 1028e745fdaSopenharmony_ci for (auto &&[key, res] : browserMap_) { 1038e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Browse browserMap_ key[%{public}s] res.size[%{public}zu]", key.c_str(), res.size()); 1048e745fdaSopenharmony_ci if (nameCbMap_.find(key) != nameCbMap_.end() && 1058e745fdaSopenharmony_ci !MDnsManager::GetInstance().IsAvailableCallback(nameCbMap_[key])) { 1068e745fdaSopenharmony_ci continue; 1078e745fdaSopenharmony_ci } 1088e745fdaSopenharmony_ci handleOfflineService(key, res); 1098e745fdaSopenharmony_ci MDnsPayloadParser parser; 1108e745fdaSopenharmony_ci MDnsMessage msg{}; 1118e745fdaSopenharmony_ci msg.questions.emplace_back(DNSProto::Question{ 1128e745fdaSopenharmony_ci .name = key, 1138e745fdaSopenharmony_ci .qtype = DNSProto::RRTYPE_PTR, 1148e745fdaSopenharmony_ci .qclass = DNSProto::RRCLASS_IN, 1158e745fdaSopenharmony_ci }); 1168e745fdaSopenharmony_ci listener_.MulticastAll(parser.ToBytes(msg)); 1178e745fdaSopenharmony_ci } 1188e745fdaSopenharmony_ci return false; 1198e745fdaSopenharmony_ci} 1208e745fdaSopenharmony_ci 1218e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::ConnectControl(int32_t sockfd, sockaddr* serverAddr) 1228e745fdaSopenharmony_ci{ 1238e745fdaSopenharmony_ci uint32_t flags = static_cast<uint32_t>(fcntl(sockfd, F_GETFL, 0)); 1248e745fdaSopenharmony_ci fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); 1258e745fdaSopenharmony_ci int32_t ret = connect(sockfd, serverAddr, sizeof(sockaddr)); 1268e745fdaSopenharmony_ci if ((ret < 0) && (errno != EINPROGRESS)) { 1278e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("connect error: %{public}d", errno); 1288e745fdaSopenharmony_ci return NETMANAGER_EXT_ERR_INTERNAL; 1298e745fdaSopenharmony_ci } 1308e745fdaSopenharmony_ci if (ret == 0) { 1318e745fdaSopenharmony_ci fcntl(sockfd, F_SETFL, flags); /* restore file status flags */ 1328e745fdaSopenharmony_ci NETMGR_EXT_LOG_I("connect success."); 1338e745fdaSopenharmony_ci return NETMANAGER_EXT_SUCCESS; 1348e745fdaSopenharmony_ci } 1358e745fdaSopenharmony_ci 1368e745fdaSopenharmony_ci fd_set rset; 1378e745fdaSopenharmony_ci FD_ZERO(&rset); 1388e745fdaSopenharmony_ci FD_SET(sockfd, &rset); 1398e745fdaSopenharmony_ci fd_set wset = rset; 1408e745fdaSopenharmony_ci timeval tval {1, 0}; 1418e745fdaSopenharmony_ci ret = select(sockfd + 1, &rset, &wset, NULL, &tval); 1428e745fdaSopenharmony_ci if (ret < 0) { // select error. 1438e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("select error: %{public}d", errno); 1448e745fdaSopenharmony_ci return NETMANAGER_EXT_ERR_INTERNAL; 1458e745fdaSopenharmony_ci } 1468e745fdaSopenharmony_ci if (ret == 0) { // timeout 1478e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("connect timeout..."); 1488e745fdaSopenharmony_ci return NETMANAGER_EXT_ERR_INTERNAL; 1498e745fdaSopenharmony_ci } 1508e745fdaSopenharmony_ci if (!FD_ISSET(sockfd, &rset) && !FD_ISSET(sockfd, &wset)) { 1518e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("select error: sockfd not set"); 1528e745fdaSopenharmony_ci return NETMANAGER_EXT_ERR_INTERNAL; 1538e745fdaSopenharmony_ci } 1548e745fdaSopenharmony_ci 1558e745fdaSopenharmony_ci int32_t result = NETMANAGER_EXT_ERR_INTERNAL; 1568e745fdaSopenharmony_ci socklen_t len = sizeof(result); 1578e745fdaSopenharmony_ci if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &result, &len) < 0) { 1588e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("getsockopt error: %{public}d", errno); 1598e745fdaSopenharmony_ci return NETMANAGER_EXT_ERR_INTERNAL; 1608e745fdaSopenharmony_ci } 1618e745fdaSopenharmony_ci if (result != 0) { // connect failed. 1628e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("connect failed. error: %{public}d", result); 1638e745fdaSopenharmony_ci return NETMANAGER_EXT_ERR_INTERNAL; 1648e745fdaSopenharmony_ci } 1658e745fdaSopenharmony_ci fcntl(sockfd, F_SETFL, flags); /* restore file status flags */ 1668e745fdaSopenharmony_ci NETMGR_EXT_LOG_I("lost but connect success."); 1678e745fdaSopenharmony_ci return NETMANAGER_EXT_SUCCESS; 1688e745fdaSopenharmony_ci} 1698e745fdaSopenharmony_ci 1708e745fdaSopenharmony_cibool MDnsProtocolImpl::IsConnectivity(const std::string &ip, int32_t port) 1718e745fdaSopenharmony_ci{ 1728e745fdaSopenharmony_ci if (ip.empty()) { 1738e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("ip is empty"); 1748e745fdaSopenharmony_ci return false; 1758e745fdaSopenharmony_ci } 1768e745fdaSopenharmony_ci 1778e745fdaSopenharmony_ci int32_t sockfd = socket(AF_INET, SOCK_STREAM, 0); 1788e745fdaSopenharmony_ci if (sockfd < 0) { 1798e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("create socket error: %{public}d", errno); 1808e745fdaSopenharmony_ci return false; 1818e745fdaSopenharmony_ci } 1828e745fdaSopenharmony_ci 1838e745fdaSopenharmony_ci struct sockaddr_in serverAddr; 1848e745fdaSopenharmony_ci if (memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr)) != EOK) { 1858e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("memset_s serverAddr failed!"); 1868e745fdaSopenharmony_ci close(sockfd); 1878e745fdaSopenharmony_ci return false; 1888e745fdaSopenharmony_ci } 1898e745fdaSopenharmony_ci 1908e745fdaSopenharmony_ci serverAddr.sin_family = AF_INET; 1918e745fdaSopenharmony_ci serverAddr.sin_addr.s_addr = inet_addr(ip.c_str()); 1928e745fdaSopenharmony_ci serverAddr.sin_port = htons(port); 1938e745fdaSopenharmony_ci if (ConnectControl(sockfd, (struct sockaddr*)&serverAddr) != NETMANAGER_EXT_SUCCESS) { 1948e745fdaSopenharmony_ci NETMGR_EXT_LOG_I("connect error: %{public}d", errno); 1958e745fdaSopenharmony_ci close(sockfd); 1968e745fdaSopenharmony_ci return false; 1978e745fdaSopenharmony_ci } 1988e745fdaSopenharmony_ci 1998e745fdaSopenharmony_ci close(sockfd); 2008e745fdaSopenharmony_ci return true; 2018e745fdaSopenharmony_ci} 2028e745fdaSopenharmony_ci 2038e745fdaSopenharmony_civoid MDnsProtocolImpl::handleOfflineService(const std::string &key, std::vector<Result> &res) 2048e745fdaSopenharmony_ci{ 2058e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log handleOfflineService key:[%{public}s]", key.c_str()); 2068e745fdaSopenharmony_ci for (auto it = res.begin(); it != res.end();) { 2078e745fdaSopenharmony_ci if (lastRunTime - it->refrehTime > DEFAULT_LOST_MS && it->state == State::LIVE) { 2088e745fdaSopenharmony_ci std::string fullName = Decorated(it->serviceName + MDNS_DOMAIN_SPLITER_STR + it->serviceType); 2098e745fdaSopenharmony_ci if ((cacheMap_.find(fullName) != cacheMap_.end()) && 2108e745fdaSopenharmony_ci IsConnectivity(cacheMap_[fullName].addr, cacheMap_[fullName].port)) { 2118e745fdaSopenharmony_ci it++; 2128e745fdaSopenharmony_ci continue; 2138e745fdaSopenharmony_ci } 2148e745fdaSopenharmony_ci 2158e745fdaSopenharmony_ci it->state = State::DEAD; 2168e745fdaSopenharmony_ci if (nameCbMap_.find(key) != nameCbMap_.end() && nameCbMap_[key] != nullptr) { 2178e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log HandleServiceLost"); 2188e745fdaSopenharmony_ci nameCbMap_[key]->HandleServiceLost(ConvertResultToInfo(*it), NETMANAGER_EXT_SUCCESS); 2198e745fdaSopenharmony_ci } 2208e745fdaSopenharmony_ci it = res.erase(it); 2218e745fdaSopenharmony_ci cacheMap_.erase(fullName); 2228e745fdaSopenharmony_ci } else { 2238e745fdaSopenharmony_ci it++; 2248e745fdaSopenharmony_ci } 2258e745fdaSopenharmony_ci } 2268e745fdaSopenharmony_ci} 2278e745fdaSopenharmony_ci 2288e745fdaSopenharmony_civoid MDnsProtocolImpl::SetConfig(const MDnsConfig &config) 2298e745fdaSopenharmony_ci{ 2308e745fdaSopenharmony_ci config_ = config; 2318e745fdaSopenharmony_ci} 2328e745fdaSopenharmony_ci 2338e745fdaSopenharmony_ciconst MDnsConfig &MDnsProtocolImpl::GetConfig() const 2348e745fdaSopenharmony_ci{ 2358e745fdaSopenharmony_ci return config_; 2368e745fdaSopenharmony_ci} 2378e745fdaSopenharmony_ci 2388e745fdaSopenharmony_cistd::string MDnsProtocolImpl::Decorated(const std::string &name) const 2398e745fdaSopenharmony_ci{ 2408e745fdaSopenharmony_ci return name + config_.topDomain; 2418e745fdaSopenharmony_ci} 2428e745fdaSopenharmony_ci 2438e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::Register(const Result &info) 2448e745fdaSopenharmony_ci{ 2458e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Register"); 2468e745fdaSopenharmony_ci if (!(IsNameValid(info.serviceName) && IsTypeValid(info.serviceType) && IsPortValid(info.port))) { 2478e745fdaSopenharmony_ci return NET_MDNS_ERR_ILLEGAL_ARGUMENT; 2488e745fdaSopenharmony_ci } 2498e745fdaSopenharmony_ci std::string name = Decorated(info.serviceName + MDNS_DOMAIN_SPLITER_STR + info.serviceType); 2508e745fdaSopenharmony_ci if (!IsDomainValid(name)) { 2518e745fdaSopenharmony_ci return NET_MDNS_ERR_ILLEGAL_ARGUMENT; 2528e745fdaSopenharmony_ci } 2538e745fdaSopenharmony_ci { 2548e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 2558e745fdaSopenharmony_ci if (srvMap_.find(name) != srvMap_.end()) { 2568e745fdaSopenharmony_ci return NET_MDNS_ERR_SERVICE_INSTANCE_DUPLICATE; 2578e745fdaSopenharmony_ci } 2588e745fdaSopenharmony_ci srvMap_.emplace(name, info); 2598e745fdaSopenharmony_ci } 2608e745fdaSopenharmony_ci return Announce(info, false); 2618e745fdaSopenharmony_ci} 2628e745fdaSopenharmony_ci 2638e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::UnRegister(const std::string &key) 2648e745fdaSopenharmony_ci{ 2658e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log UnRegister"); 2668e745fdaSopenharmony_ci std::string name = Decorated(key); 2678e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 2688e745fdaSopenharmony_ci if (srvMap_.find(name) != srvMap_.end()) { 2698e745fdaSopenharmony_ci Announce(srvMap_[name], true); 2708e745fdaSopenharmony_ci srvMap_.erase(name); 2718e745fdaSopenharmony_ci return NETMANAGER_EXT_SUCCESS; 2728e745fdaSopenharmony_ci } 2738e745fdaSopenharmony_ci return NET_MDNS_ERR_SERVICE_INSTANCE_NOT_FOUND; 2748e745fdaSopenharmony_ci} 2758e745fdaSopenharmony_ci 2768e745fdaSopenharmony_cibool MDnsProtocolImpl::DiscoveryFromCache(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb) 2778e745fdaSopenharmony_ci{ 2788e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log DiscoveryFromCache"); 2798e745fdaSopenharmony_ci std::string name = Decorated(serviceType); 2808e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 2818e745fdaSopenharmony_ci if (!IsBrowserAvailable(name)) { 2828e745fdaSopenharmony_ci return false; 2838e745fdaSopenharmony_ci } 2848e745fdaSopenharmony_ci 2858e745fdaSopenharmony_ci if (browserMap_.find(name) == browserMap_.end()) { 2868e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log DiscoveryFromCache browserMap_ not find name"); 2878e745fdaSopenharmony_ci return false; 2888e745fdaSopenharmony_ci } 2898e745fdaSopenharmony_ci 2908e745fdaSopenharmony_ci for (auto &res : browserMap_[name]) { 2918e745fdaSopenharmony_ci if (res.state == State::REMOVE || res.state == State::DEAD) { 2928e745fdaSopenharmony_ci continue; 2938e745fdaSopenharmony_ci } 2948e745fdaSopenharmony_ci AddTask([cb, info = ConvertResultToInfo(res)]() { 2958e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log DiscoveryFromCache ConvertResultToInfo HandleServiceFound"); 2968e745fdaSopenharmony_ci if (MDnsManager::GetInstance().IsAvailableCallback(cb)) { 2978e745fdaSopenharmony_ci cb->HandleServiceFound(info, NETMANAGER_EXT_SUCCESS); 2988e745fdaSopenharmony_ci } 2998e745fdaSopenharmony_ci return true; 3008e745fdaSopenharmony_ci }); 3018e745fdaSopenharmony_ci } 3028e745fdaSopenharmony_ci return true; 3038e745fdaSopenharmony_ci} 3048e745fdaSopenharmony_ci 3058e745fdaSopenharmony_cibool MDnsProtocolImpl::DiscoveryFromNet(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb) 3068e745fdaSopenharmony_ci{ 3078e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log DiscoveryFromNet"); 3088e745fdaSopenharmony_ci std::string name = Decorated(serviceType); 3098e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 3108e745fdaSopenharmony_ci browserMap_.insert({name, std::vector<Result>{}}); 3118e745fdaSopenharmony_ci nameCbMap_[name] = cb; 3128e745fdaSopenharmony_ci // key is serviceTYpe 3138e745fdaSopenharmony_ci AddEvent(name, [this, name, cb]() { 3148e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 3158e745fdaSopenharmony_ci if (!IsBrowserAvailable(name)) { 3168e745fdaSopenharmony_ci return false; 3178e745fdaSopenharmony_ci } 3188e745fdaSopenharmony_ci if (!MDnsManager::GetInstance().IsAvailableCallback(cb)) { 3198e745fdaSopenharmony_ci return true; 3208e745fdaSopenharmony_ci } 3218e745fdaSopenharmony_ci for (auto &res : browserMap_[name]) { 3228e745fdaSopenharmony_ci std::string fullName = Decorated(res.serviceName + MDNS_DOMAIN_SPLITER_STR + res.serviceType); 3238e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log DiscoveryFromNet name:[%{public}s] fullName:[%{public}s]", name.c_str(), 3248e745fdaSopenharmony_ci fullName.c_str()); 3258e745fdaSopenharmony_ci if (cacheMap_.find(fullName) == cacheMap_.end() || 3268e745fdaSopenharmony_ci (res.state == State::ADD || res.state == State::REFRESH)) { 3278e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log HandleServiceFound"); 3288e745fdaSopenharmony_ci cb->HandleServiceFound(ConvertResultToInfo(res), NETMANAGER_EXT_SUCCESS); 3298e745fdaSopenharmony_ci res.state = State::LIVE; 3308e745fdaSopenharmony_ci } 3318e745fdaSopenharmony_ci if (res.state == State::REMOVE) { 3328e745fdaSopenharmony_ci res.state = State::DEAD; 3338e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log HandleServiceLost"); 3348e745fdaSopenharmony_ci cb->HandleServiceLost(ConvertResultToInfo(res), NETMANAGER_EXT_SUCCESS); 3358e745fdaSopenharmony_ci if (cacheMap_.find(fullName) != cacheMap_.end()) { 3368e745fdaSopenharmony_ci cacheMap_.erase(fullName); 3378e745fdaSopenharmony_ci } 3388e745fdaSopenharmony_ci } 3398e745fdaSopenharmony_ci } 3408e745fdaSopenharmony_ci return false; 3418e745fdaSopenharmony_ci }); 3428e745fdaSopenharmony_ci 3438e745fdaSopenharmony_ci AddTask([=]() { 3448e745fdaSopenharmony_ci MDnsPayloadParser parser; 3458e745fdaSopenharmony_ci MDnsMessage msg{}; 3468e745fdaSopenharmony_ci msg.questions.emplace_back(DNSProto::Question{ 3478e745fdaSopenharmony_ci .name = name, 3488e745fdaSopenharmony_ci .qtype = DNSProto::RRTYPE_PTR, 3498e745fdaSopenharmony_ci .qclass = DNSProto::RRCLASS_IN, 3508e745fdaSopenharmony_ci }); 3518e745fdaSopenharmony_ci listener_.MulticastAll(parser.ToBytes(msg)); 3528e745fdaSopenharmony_ci return true; 3538e745fdaSopenharmony_ci }, false); 3548e745fdaSopenharmony_ci return true; 3558e745fdaSopenharmony_ci} 3568e745fdaSopenharmony_ci 3578e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::Discovery(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb) 3588e745fdaSopenharmony_ci{ 3598e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Discovery"); 3608e745fdaSopenharmony_ci DiscoveryFromCache(serviceType, cb); 3618e745fdaSopenharmony_ci DiscoveryFromNet(serviceType, cb); 3628e745fdaSopenharmony_ci return NETMANAGER_EXT_SUCCESS; 3638e745fdaSopenharmony_ci} 3648e745fdaSopenharmony_ci 3658e745fdaSopenharmony_cibool MDnsProtocolImpl::ResolveInstanceFromCache(const std::string &name, const sptr<IResolveCallback> &cb) 3668e745fdaSopenharmony_ci{ 3678e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log ResolveInstanceFromCache"); 3688e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 3698e745fdaSopenharmony_ci if (!IsInstanceCacheAvailable(name)) { 3708e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log ResolveInstanceFromCache cacheMap_ has no element [%{public}s]", name.c_str()); 3718e745fdaSopenharmony_ci return false; 3728e745fdaSopenharmony_ci } 3738e745fdaSopenharmony_ci 3748e745fdaSopenharmony_ci NETMGR_EXT_LOG_I("mdns_log rr.name : [%{public}s]", name.c_str()); 3758e745fdaSopenharmony_ci Result r = cacheMap_[name]; 3768e745fdaSopenharmony_ci if (IsDomainCacheAvailable(r.domain)) { 3778e745fdaSopenharmony_ci r.ipv6 = cacheMap_[r.domain].ipv6; 3788e745fdaSopenharmony_ci r.addr = cacheMap_[r.domain].addr; 3798e745fdaSopenharmony_ci 3808e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Add Task DomainCache Available, [%{public}s]", r.domain.c_str()); 3818e745fdaSopenharmony_ci AddTask([cb, info = ConvertResultToInfo(r)]() { 3828e745fdaSopenharmony_ci if (nullptr != cb) { 3838e745fdaSopenharmony_ci cb->HandleResolveResult(info, NETMANAGER_EXT_SUCCESS); 3848e745fdaSopenharmony_ci } 3858e745fdaSopenharmony_ci return true; 3868e745fdaSopenharmony_ci }); 3878e745fdaSopenharmony_ci } else { 3888e745fdaSopenharmony_ci ResolveFromNet(r.domain, nullptr); 3898e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Add Event DomainCache UnAvailable, [%{public}s]", r.domain.c_str()); 3908e745fdaSopenharmony_ci AddEvent(r.domain, [this, cb, r]() mutable { 3918e745fdaSopenharmony_ci if (!IsDomainCacheAvailable(r.domain)) { 3928e745fdaSopenharmony_ci return false; 3938e745fdaSopenharmony_ci } 3948e745fdaSopenharmony_ci r.ipv6 = cacheMap_[r.domain].ipv6; 3958e745fdaSopenharmony_ci r.addr = cacheMap_[r.domain].addr; 3968e745fdaSopenharmony_ci if (nullptr != cb) { 3978e745fdaSopenharmony_ci cb->HandleResolveResult(ConvertResultToInfo(r), NETMANAGER_EXT_SUCCESS); 3988e745fdaSopenharmony_ci } 3998e745fdaSopenharmony_ci return true; 4008e745fdaSopenharmony_ci }); 4018e745fdaSopenharmony_ci } 4028e745fdaSopenharmony_ci return true; 4038e745fdaSopenharmony_ci} 4048e745fdaSopenharmony_ci 4058e745fdaSopenharmony_cibool MDnsProtocolImpl::ResolveInstanceFromNet(const std::string &name, const sptr<IResolveCallback> &cb) 4068e745fdaSopenharmony_ci{ 4078e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log ResolveInstanceFromNet"); 4088e745fdaSopenharmony_ci { 4098e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 4108e745fdaSopenharmony_ci cacheMap_[name].state = State::ADD; 4118e745fdaSopenharmony_ci ExtractNameAndType(name, cacheMap_[name].serviceName, cacheMap_[name].serviceType); 4128e745fdaSopenharmony_ci } 4138e745fdaSopenharmony_ci MDnsPayloadParser parser; 4148e745fdaSopenharmony_ci MDnsMessage msg{}; 4158e745fdaSopenharmony_ci msg.questions.emplace_back(DNSProto::Question{ 4168e745fdaSopenharmony_ci .name = name, 4178e745fdaSopenharmony_ci .qtype = DNSProto::RRTYPE_SRV, 4188e745fdaSopenharmony_ci .qclass = DNSProto::RRCLASS_IN, 4198e745fdaSopenharmony_ci }); 4208e745fdaSopenharmony_ci msg.questions.emplace_back(DNSProto::Question{ 4218e745fdaSopenharmony_ci .name = name, 4228e745fdaSopenharmony_ci .qtype = DNSProto::RRTYPE_TXT, 4238e745fdaSopenharmony_ci .qclass = DNSProto::RRCLASS_IN, 4248e745fdaSopenharmony_ci }); 4258e745fdaSopenharmony_ci msg.header.qdcount = msg.questions.size(); 4268e745fdaSopenharmony_ci AddEvent(name, [this, name, cb]() { return ResolveInstanceFromCache(name, cb); }); 4278e745fdaSopenharmony_ci ssize_t size = listener_.MulticastAll(parser.ToBytes(msg)); 4288e745fdaSopenharmony_ci return size > 0; 4298e745fdaSopenharmony_ci} 4308e745fdaSopenharmony_ci 4318e745fdaSopenharmony_cibool MDnsProtocolImpl::ResolveFromCache(const std::string &domain, const sptr<IResolveCallback> &cb) 4328e745fdaSopenharmony_ci{ 4338e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log ResolveFromCache"); 4348e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 4358e745fdaSopenharmony_ci if (!IsDomainCacheAvailable(domain)) { 4368e745fdaSopenharmony_ci return false; 4378e745fdaSopenharmony_ci } 4388e745fdaSopenharmony_ci AddTask([this, cb, info = ConvertResultToInfo(cacheMap_[domain])]() { 4398e745fdaSopenharmony_ci if (nullptr != cb) { 4408e745fdaSopenharmony_ci cb->HandleResolveResult(info, NETMANAGER_EXT_SUCCESS); 4418e745fdaSopenharmony_ci } 4428e745fdaSopenharmony_ci return true; 4438e745fdaSopenharmony_ci }); 4448e745fdaSopenharmony_ci return true; 4458e745fdaSopenharmony_ci} 4468e745fdaSopenharmony_ci 4478e745fdaSopenharmony_cibool MDnsProtocolImpl::ResolveFromNet(const std::string &domain, const sptr<IResolveCallback> &cb) 4488e745fdaSopenharmony_ci{ 4498e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log ResolveFromNet"); 4508e745fdaSopenharmony_ci { 4518e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 4528e745fdaSopenharmony_ci cacheMap_[domain]; 4538e745fdaSopenharmony_ci cacheMap_[domain].domain = domain; 4548e745fdaSopenharmony_ci } 4558e745fdaSopenharmony_ci MDnsPayloadParser parser; 4568e745fdaSopenharmony_ci MDnsMessage msg{}; 4578e745fdaSopenharmony_ci msg.questions.emplace_back(DNSProto::Question{ 4588e745fdaSopenharmony_ci .name = domain, 4598e745fdaSopenharmony_ci .qtype = DNSProto::RRTYPE_A, 4608e745fdaSopenharmony_ci .qclass = DNSProto::RRCLASS_IN, 4618e745fdaSopenharmony_ci }); 4628e745fdaSopenharmony_ci msg.questions.emplace_back(DNSProto::Question{ 4638e745fdaSopenharmony_ci .name = domain, 4648e745fdaSopenharmony_ci .qtype = DNSProto::RRTYPE_AAAA, 4658e745fdaSopenharmony_ci .qclass = DNSProto::RRCLASS_IN, 4668e745fdaSopenharmony_ci }); 4678e745fdaSopenharmony_ci // key is serviceName 4688e745fdaSopenharmony_ci AddEvent(domain, [this, cb, domain]() { return ResolveFromCache(domain, cb); }); 4698e745fdaSopenharmony_ci ssize_t size = listener_.MulticastAll(parser.ToBytes(msg)); 4708e745fdaSopenharmony_ci return size > 0; 4718e745fdaSopenharmony_ci} 4728e745fdaSopenharmony_ci 4738e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::ResolveInstance(const std::string &instance, const sptr<IResolveCallback> &cb) 4748e745fdaSopenharmony_ci{ 4758e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log execute ResolveInstance"); 4768e745fdaSopenharmony_ci if (!IsInstanceValid(instance)) { 4778e745fdaSopenharmony_ci return NET_MDNS_ERR_ILLEGAL_ARGUMENT; 4788e745fdaSopenharmony_ci } 4798e745fdaSopenharmony_ci std::string name = Decorated(instance); 4808e745fdaSopenharmony_ci if (!IsDomainValid(name)) { 4818e745fdaSopenharmony_ci return NET_MDNS_ERR_ILLEGAL_ARGUMENT; 4828e745fdaSopenharmony_ci } 4838e745fdaSopenharmony_ci if (ResolveInstanceFromCache(name, cb)) { 4848e745fdaSopenharmony_ci return NETMANAGER_EXT_SUCCESS; 4858e745fdaSopenharmony_ci } 4868e745fdaSopenharmony_ci return ResolveInstanceFromNet(name, cb) ? NETMANAGER_EXT_SUCCESS : NET_MDNS_ERR_SEND; 4878e745fdaSopenharmony_ci} 4888e745fdaSopenharmony_ci 4898e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::Announce(const Result &info, bool off) 4908e745fdaSopenharmony_ci{ 4918e745fdaSopenharmony_ci NETMGR_EXT_LOG_I("mdns_log Announce message"); 4928e745fdaSopenharmony_ci MDnsMessage response{}; 4938e745fdaSopenharmony_ci response.header.flags = DNSProto::MDNS_ANSWER_FLAGS; 4948e745fdaSopenharmony_ci std::string name = Decorated(info.serviceName + MDNS_DOMAIN_SPLITER_STR + info.serviceType); 4958e745fdaSopenharmony_ci response.answers.emplace_back(DNSProto::ResourceRecord{.name = Decorated(info.serviceType), 4968e745fdaSopenharmony_ci .rtype = static_cast<uint16_t>(DNSProto::RRTYPE_PTR), 4978e745fdaSopenharmony_ci .rclass = DNSProto::RRCLASS_IN | MDNS_FLUSH_CACHE_BIT, 4988e745fdaSopenharmony_ci .ttl = off ? 0U : DEFAULT_TTL, 4998e745fdaSopenharmony_ci .rdata = name}); 5008e745fdaSopenharmony_ci response.answers.emplace_back(DNSProto::ResourceRecord{.name = name, 5018e745fdaSopenharmony_ci .rtype = static_cast<uint16_t>(DNSProto::RRTYPE_SRV), 5028e745fdaSopenharmony_ci .rclass = DNSProto::RRCLASS_IN | MDNS_FLUSH_CACHE_BIT, 5038e745fdaSopenharmony_ci .ttl = off ? 0U : DEFAULT_TTL, 5048e745fdaSopenharmony_ci .rdata = DNSProto::RDataSrv{ 5058e745fdaSopenharmony_ci .priority = 0, 5068e745fdaSopenharmony_ci .weight = 0, 5078e745fdaSopenharmony_ci .port = static_cast<uint16_t>(info.port), 5088e745fdaSopenharmony_ci .name = GetHostDomain(), 5098e745fdaSopenharmony_ci }}); 5108e745fdaSopenharmony_ci response.answers.emplace_back(DNSProto::ResourceRecord{.name = name, 5118e745fdaSopenharmony_ci .rtype = static_cast<uint16_t>(DNSProto::RRTYPE_TXT), 5128e745fdaSopenharmony_ci .rclass = DNSProto::RRCLASS_IN | MDNS_FLUSH_CACHE_BIT, 5138e745fdaSopenharmony_ci .ttl = off ? 0U : DEFAULT_TTL, 5148e745fdaSopenharmony_ci .rdata = info.txt}); 5158e745fdaSopenharmony_ci MDnsPayloadParser parser; 5168e745fdaSopenharmony_ci ssize_t size = listener_.MulticastAll(parser.ToBytes(response)); 5178e745fdaSopenharmony_ci return size > 0 ? NETMANAGER_EXT_SUCCESS : NET_MDNS_ERR_SEND; 5188e745fdaSopenharmony_ci} 5198e745fdaSopenharmony_ci 5208e745fdaSopenharmony_civoid MDnsProtocolImpl::ReceivePacket(int sock, const MDnsPayload &payload) 5218e745fdaSopenharmony_ci{ 5228e745fdaSopenharmony_ci if (payload.size() == 0) { 5238e745fdaSopenharmony_ci return; 5248e745fdaSopenharmony_ci } 5258e745fdaSopenharmony_ci MDnsPayloadParser parser; 5268e745fdaSopenharmony_ci MDnsMessage msg = parser.FromBytes(payload); 5278e745fdaSopenharmony_ci if (parser.GetError() != 0) { 5288e745fdaSopenharmony_ci NETMGR_EXT_LOG_E("parser payload failed"); 5298e745fdaSopenharmony_ci return; 5308e745fdaSopenharmony_ci } 5318e745fdaSopenharmony_ci if ((msg.header.flags & DNSProto::HEADER_FLAGS_QR_MASK) == 0) { 5328e745fdaSopenharmony_ci ProcessQuestion(sock, msg); 5338e745fdaSopenharmony_ci } else { 5348e745fdaSopenharmony_ci ProcessAnswer(sock, msg); 5358e745fdaSopenharmony_ci } 5368e745fdaSopenharmony_ci} 5378e745fdaSopenharmony_ci 5388e745fdaSopenharmony_civoid MDnsProtocolImpl::AppendRecord(std::vector<DNSProto::ResourceRecord> &rrlist, DNSProto::RRType type, 5398e745fdaSopenharmony_ci const std::string &name, const std::any &rdata) 5408e745fdaSopenharmony_ci{ 5418e745fdaSopenharmony_ci rrlist.emplace_back(DNSProto::ResourceRecord{.name = name, 5428e745fdaSopenharmony_ci .rtype = static_cast<uint16_t>(type), 5438e745fdaSopenharmony_ci .rclass = DNSProto::RRCLASS_IN | MDNS_FLUSH_CACHE_BIT, 5448e745fdaSopenharmony_ci .ttl = DEFAULT_TTL, 5458e745fdaSopenharmony_ci .rdata = rdata}); 5468e745fdaSopenharmony_ci} 5478e745fdaSopenharmony_ci 5488e745fdaSopenharmony_civoid MDnsProtocolImpl::ProcessQuestion(int sock, const MDnsMessage &msg) 5498e745fdaSopenharmony_ci{ 5508e745fdaSopenharmony_ci const sockaddr *saddrIf = listener_.GetSockAddr(sock); 5518e745fdaSopenharmony_ci if (saddrIf == nullptr) { 5528e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log ProcessQuestion saddrIf is null"); 5538e745fdaSopenharmony_ci return; 5548e745fdaSopenharmony_ci } 5558e745fdaSopenharmony_ci std::any anyAddr; 5568e745fdaSopenharmony_ci DNSProto::RRType anyAddrType; 5578e745fdaSopenharmony_ci if (saddrIf->sa_family == AF_INET6) { 5588e745fdaSopenharmony_ci anyAddr = reinterpret_cast<const sockaddr_in6 *>(saddrIf)->sin6_addr; 5598e745fdaSopenharmony_ci anyAddrType = DNSProto::RRTYPE_AAAA; 5608e745fdaSopenharmony_ci } else { 5618e745fdaSopenharmony_ci anyAddr = reinterpret_cast<const sockaddr_in *>(saddrIf)->sin_addr; 5628e745fdaSopenharmony_ci anyAddrType = DNSProto::RRTYPE_A; 5638e745fdaSopenharmony_ci } 5648e745fdaSopenharmony_ci int phase = 0; 5658e745fdaSopenharmony_ci MDnsMessage response{}; 5668e745fdaSopenharmony_ci response.header.flags = DNSProto::MDNS_ANSWER_FLAGS; 5678e745fdaSopenharmony_ci for (size_t i = 0; i < msg.header.qdcount; ++i) { 5688e745fdaSopenharmony_ci ProcessQuestionRecord(anyAddr, anyAddrType, msg.questions[i], phase, response); 5698e745fdaSopenharmony_ci } 5708e745fdaSopenharmony_ci if (phase < PHASE_DOMAIN) { 5718e745fdaSopenharmony_ci AppendRecord(response.additional, anyAddrType, GetHostDomain(), anyAddr); 5728e745fdaSopenharmony_ci } 5738e745fdaSopenharmony_ci 5748e745fdaSopenharmony_ci if (phase != 0 && response.answers.size() > 0) { 5758e745fdaSopenharmony_ci listener_.Multicast(sock, MDnsPayloadParser().ToBytes(response)); 5768e745fdaSopenharmony_ci } 5778e745fdaSopenharmony_ci} 5788e745fdaSopenharmony_ci 5798e745fdaSopenharmony_civoid MDnsProtocolImpl::ProcessQuestionRecord(const std::any &anyAddr, const DNSProto::RRType &anyAddrType, 5808e745fdaSopenharmony_ci const DNSProto::Question &qu, int &phase, MDnsMessage &response) 5818e745fdaSopenharmony_ci{ 5828e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log ProcessQuestionRecord"); 5838e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 5848e745fdaSopenharmony_ci std::string name = qu.name; 5858e745fdaSopenharmony_ci if (qu.qtype == DNSProto::RRTYPE_ANY || qu.qtype == DNSProto::RRTYPE_PTR) { 5868e745fdaSopenharmony_ci std::for_each(srvMap_.begin(), srvMap_.end(), [&](const auto &elem) -> void { 5878e745fdaSopenharmony_ci if (EndsWith(elem.first, name)) { 5888e745fdaSopenharmony_ci AppendRecord(response.answers, DNSProto::RRTYPE_PTR, name, elem.first); 5898e745fdaSopenharmony_ci AppendRecord(response.additional, DNSProto::RRTYPE_SRV, elem.first, 5908e745fdaSopenharmony_ci DNSProto::RDataSrv{ 5918e745fdaSopenharmony_ci .priority = 0, 5928e745fdaSopenharmony_ci .weight = 0, 5938e745fdaSopenharmony_ci .port = static_cast<uint16_t>(elem.second.port), 5948e745fdaSopenharmony_ci .name = GetHostDomain(), 5958e745fdaSopenharmony_ci }); 5968e745fdaSopenharmony_ci AppendRecord(response.additional, DNSProto::RRTYPE_TXT, elem.first, elem.second.txt); 5978e745fdaSopenharmony_ci } 5988e745fdaSopenharmony_ci }); 5998e745fdaSopenharmony_ci phase = std::max(phase, PHASE_PTR); 6008e745fdaSopenharmony_ci } 6018e745fdaSopenharmony_ci if (qu.qtype == DNSProto::RRTYPE_ANY || qu.qtype == DNSProto::RRTYPE_SRV) { 6028e745fdaSopenharmony_ci auto iter = srvMap_.find(name); 6038e745fdaSopenharmony_ci if (iter == srvMap_.end()) { 6048e745fdaSopenharmony_ci return; 6058e745fdaSopenharmony_ci } 6068e745fdaSopenharmony_ci AppendRecord(response.answers, DNSProto::RRTYPE_SRV, name, 6078e745fdaSopenharmony_ci DNSProto::RDataSrv{ 6088e745fdaSopenharmony_ci .priority = 0, 6098e745fdaSopenharmony_ci .weight = 0, 6108e745fdaSopenharmony_ci .port = static_cast<uint16_t>(iter->second.port), 6118e745fdaSopenharmony_ci .name = GetHostDomain(), 6128e745fdaSopenharmony_ci }); 6138e745fdaSopenharmony_ci phase = std::max(phase, PHASE_SRV); 6148e745fdaSopenharmony_ci } 6158e745fdaSopenharmony_ci if (qu.qtype == DNSProto::RRTYPE_ANY || qu.qtype == DNSProto::RRTYPE_TXT) { 6168e745fdaSopenharmony_ci auto iter = srvMap_.find(name); 6178e745fdaSopenharmony_ci if (iter == srvMap_.end()) { 6188e745fdaSopenharmony_ci return; 6198e745fdaSopenharmony_ci } 6208e745fdaSopenharmony_ci AppendRecord(response.answers, DNSProto::RRTYPE_TXT, name, iter->second.txt); 6218e745fdaSopenharmony_ci phase = std::max(phase, PHASE_SRV); 6228e745fdaSopenharmony_ci } 6238e745fdaSopenharmony_ci if (qu.qtype == DNSProto::RRTYPE_ANY || qu.qtype == DNSProto::RRTYPE_A || qu.qtype == DNSProto::RRTYPE_AAAA) { 6248e745fdaSopenharmony_ci if (name != GetHostDomain() || (qu.qtype != DNSProto::RRTYPE_ANY && anyAddrType != qu.qtype)) { 6258e745fdaSopenharmony_ci return; 6268e745fdaSopenharmony_ci } 6278e745fdaSopenharmony_ci AppendRecord(response.answers, anyAddrType, name, anyAddr); 6288e745fdaSopenharmony_ci phase = std::max(phase, PHASE_DOMAIN); 6298e745fdaSopenharmony_ci } 6308e745fdaSopenharmony_ci} 6318e745fdaSopenharmony_ci 6328e745fdaSopenharmony_civoid MDnsProtocolImpl::ProcessAnswer(int sock, const MDnsMessage &msg) 6338e745fdaSopenharmony_ci{ 6348e745fdaSopenharmony_ci const sockaddr *saddrIf = listener_.GetSockAddr(sock); 6358e745fdaSopenharmony_ci if (saddrIf == nullptr) { 6368e745fdaSopenharmony_ci return; 6378e745fdaSopenharmony_ci } 6388e745fdaSopenharmony_ci bool v6 = (saddrIf->sa_family == AF_INET6); 6398e745fdaSopenharmony_ci std::set<std::string> changed; 6408e745fdaSopenharmony_ci for (const auto &answer : msg.answers) { 6418e745fdaSopenharmony_ci ProcessAnswerRecord(v6, answer, changed); 6428e745fdaSopenharmony_ci } 6438e745fdaSopenharmony_ci for (const auto &i : msg.additional) { 6448e745fdaSopenharmony_ci ProcessAnswerRecord(v6, i, changed); 6458e745fdaSopenharmony_ci } 6468e745fdaSopenharmony_ci for (const auto &i : changed) { 6478e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 6488e745fdaSopenharmony_ci RunTaskQueue(taskOnChange_[i]); 6498e745fdaSopenharmony_ci KillCache(i); 6508e745fdaSopenharmony_ci } 6518e745fdaSopenharmony_ci} 6528e745fdaSopenharmony_ci 6538e745fdaSopenharmony_civoid MDnsProtocolImpl::UpdatePtr(bool v6, const DNSProto::ResourceRecord &rr, std::set<std::string> &changed) 6548e745fdaSopenharmony_ci{ 6558e745fdaSopenharmony_ci const std::string *data = std::any_cast<std::string>(&rr.rdata); 6568e745fdaSopenharmony_ci if (data == nullptr) { 6578e745fdaSopenharmony_ci return; 6588e745fdaSopenharmony_ci } 6598e745fdaSopenharmony_ci 6608e745fdaSopenharmony_ci std::string name = rr.name; 6618e745fdaSopenharmony_ci if (browserMap_.find(name) == browserMap_.end()) { 6628e745fdaSopenharmony_ci return; 6638e745fdaSopenharmony_ci } 6648e745fdaSopenharmony_ci auto &results = browserMap_[name]; 6658e745fdaSopenharmony_ci std::string srvName; 6668e745fdaSopenharmony_ci std::string srvType; 6678e745fdaSopenharmony_ci ExtractNameAndType(*data, srvName, srvType); 6688e745fdaSopenharmony_ci if (srvName.empty() || srvType.empty()) { 6698e745fdaSopenharmony_ci return; 6708e745fdaSopenharmony_ci } 6718e745fdaSopenharmony_ci auto res = 6728e745fdaSopenharmony_ci std::find_if(results.begin(), results.end(), [&](const auto &elem) { return elem.serviceName == srvName; }); 6738e745fdaSopenharmony_ci if (res == results.end()) { 6748e745fdaSopenharmony_ci results.emplace_back(Result{ 6758e745fdaSopenharmony_ci .serviceName = srvName, 6768e745fdaSopenharmony_ci .serviceType = srvType, 6778e745fdaSopenharmony_ci .state = State::ADD, 6788e745fdaSopenharmony_ci }); 6798e745fdaSopenharmony_ci } 6808e745fdaSopenharmony_ci res = std::find_if(results.begin(), results.end(), [&](const auto &elem) { return elem.serviceName == srvName; }); 6818e745fdaSopenharmony_ci if (res->serviceName != srvName || res->state == State::DEAD) { 6828e745fdaSopenharmony_ci res->state = State::REFRESH; 6838e745fdaSopenharmony_ci res->serviceName = srvName; 6848e745fdaSopenharmony_ci } 6858e745fdaSopenharmony_ci if (rr.ttl == 0) { 6868e745fdaSopenharmony_ci res->state = State::REMOVE; 6878e745fdaSopenharmony_ci } 6888e745fdaSopenharmony_ci if (res->state != State::LIVE && res->state != State::DEAD) { 6898e745fdaSopenharmony_ci changed.emplace(name); 6908e745fdaSopenharmony_ci } 6918e745fdaSopenharmony_ci res->ttl = rr.ttl; 6928e745fdaSopenharmony_ci res->refrehTime = MilliSecondsSinceEpoch(); 6938e745fdaSopenharmony_ci} 6948e745fdaSopenharmony_ci 6958e745fdaSopenharmony_civoid MDnsProtocolImpl::UpdateSrv(bool v6, const DNSProto::ResourceRecord &rr, std::set<std::string> &changed) 6968e745fdaSopenharmony_ci{ 6978e745fdaSopenharmony_ci const DNSProto::RDataSrv *srv = std::any_cast<DNSProto::RDataSrv>(&rr.rdata); 6988e745fdaSopenharmony_ci if (srv == nullptr) { 6998e745fdaSopenharmony_ci return; 7008e745fdaSopenharmony_ci } 7018e745fdaSopenharmony_ci std::string name = rr.name; 7028e745fdaSopenharmony_ci if (cacheMap_.find(name) == cacheMap_.end()) { 7038e745fdaSopenharmony_ci ExtractNameAndType(name, cacheMap_[name].serviceName, cacheMap_[name].serviceType); 7048e745fdaSopenharmony_ci cacheMap_[name].state = State::ADD; 7058e745fdaSopenharmony_ci cacheMap_[name].domain = srv->name; 7068e745fdaSopenharmony_ci cacheMap_[name].port = srv->port; 7078e745fdaSopenharmony_ci } 7088e745fdaSopenharmony_ci Result &result = cacheMap_[name]; 7098e745fdaSopenharmony_ci if (result.domain != srv->name || result.port != srv->port || result.state == State::DEAD) { 7108e745fdaSopenharmony_ci if (result.state != State::ADD) { 7118e745fdaSopenharmony_ci result.state = State::REFRESH; 7128e745fdaSopenharmony_ci } 7138e745fdaSopenharmony_ci result.domain = srv->name; 7148e745fdaSopenharmony_ci result.port = srv->port; 7158e745fdaSopenharmony_ci } 7168e745fdaSopenharmony_ci if (rr.ttl == 0) { 7178e745fdaSopenharmony_ci result.state = State::REMOVE; 7188e745fdaSopenharmony_ci } 7198e745fdaSopenharmony_ci if (result.state != State::LIVE && result.state != State::DEAD) { 7208e745fdaSopenharmony_ci changed.emplace(name); 7218e745fdaSopenharmony_ci } 7228e745fdaSopenharmony_ci result.ttl = rr.ttl; 7238e745fdaSopenharmony_ci result.refrehTime = MilliSecondsSinceEpoch(); 7248e745fdaSopenharmony_ci} 7258e745fdaSopenharmony_ci 7268e745fdaSopenharmony_civoid MDnsProtocolImpl::UpdateTxt(bool v6, const DNSProto::ResourceRecord &rr, std::set<std::string> &changed) 7278e745fdaSopenharmony_ci{ 7288e745fdaSopenharmony_ci const TxtRecordEncoded *txt = std::any_cast<TxtRecordEncoded>(&rr.rdata); 7298e745fdaSopenharmony_ci if (txt == nullptr) { 7308e745fdaSopenharmony_ci return; 7318e745fdaSopenharmony_ci } 7328e745fdaSopenharmony_ci std::string name = rr.name; 7338e745fdaSopenharmony_ci if (cacheMap_.find(name) == cacheMap_.end()) { 7348e745fdaSopenharmony_ci ExtractNameAndType(name, cacheMap_[name].serviceName, cacheMap_[name].serviceType); 7358e745fdaSopenharmony_ci cacheMap_[name].state = State::ADD; 7368e745fdaSopenharmony_ci cacheMap_[name].txt = *txt; 7378e745fdaSopenharmony_ci } 7388e745fdaSopenharmony_ci Result &result = cacheMap_[name]; 7398e745fdaSopenharmony_ci if (result.txt != *txt || result.state == State::DEAD) { 7408e745fdaSopenharmony_ci if (result.state != State::ADD) { 7418e745fdaSopenharmony_ci result.state = State::REFRESH; 7428e745fdaSopenharmony_ci } 7438e745fdaSopenharmony_ci result.txt = *txt; 7448e745fdaSopenharmony_ci } 7458e745fdaSopenharmony_ci if (rr.ttl == 0) { 7468e745fdaSopenharmony_ci result.state = State::REMOVE; 7478e745fdaSopenharmony_ci } 7488e745fdaSopenharmony_ci if (result.state != State::LIVE && result.state != State::DEAD) { 7498e745fdaSopenharmony_ci changed.emplace(name); 7508e745fdaSopenharmony_ci } 7518e745fdaSopenharmony_ci result.ttl = rr.ttl; 7528e745fdaSopenharmony_ci result.refrehTime = MilliSecondsSinceEpoch(); 7538e745fdaSopenharmony_ci} 7548e745fdaSopenharmony_ci 7558e745fdaSopenharmony_civoid MDnsProtocolImpl::UpdateAddr(bool v6, const DNSProto::ResourceRecord &rr, std::set<std::string> &changed) 7568e745fdaSopenharmony_ci{ 7578e745fdaSopenharmony_ci if (v6 != (rr.rtype == DNSProto::RRTYPE_AAAA)) { 7588e745fdaSopenharmony_ci return; 7598e745fdaSopenharmony_ci } 7608e745fdaSopenharmony_ci const std::string addr = AddrToString(rr.rdata); 7618e745fdaSopenharmony_ci bool v6rr = (rr.rtype == DNSProto::RRTYPE_AAAA); 7628e745fdaSopenharmony_ci if (addr.empty()) { 7638e745fdaSopenharmony_ci return; 7648e745fdaSopenharmony_ci } 7658e745fdaSopenharmony_ci std::string name = rr.name; 7668e745fdaSopenharmony_ci if (cacheMap_.find(name) == cacheMap_.end()) { 7678e745fdaSopenharmony_ci ExtractNameAndType(name, cacheMap_[name].serviceName, cacheMap_[name].serviceType); 7688e745fdaSopenharmony_ci cacheMap_[name].state = State::ADD; 7698e745fdaSopenharmony_ci cacheMap_[name].ipv6 = v6rr; 7708e745fdaSopenharmony_ci cacheMap_[name].addr = addr; 7718e745fdaSopenharmony_ci } 7728e745fdaSopenharmony_ci Result &result = cacheMap_[name]; 7738e745fdaSopenharmony_ci if (result.addr != addr || result.ipv6 != v6rr || result.state == State::DEAD) { 7748e745fdaSopenharmony_ci result.state = State::REFRESH; 7758e745fdaSopenharmony_ci result.addr = addr; 7768e745fdaSopenharmony_ci result.ipv6 = v6rr; 7778e745fdaSopenharmony_ci } 7788e745fdaSopenharmony_ci if (rr.ttl == 0) { 7798e745fdaSopenharmony_ci result.state = State::REMOVE; 7808e745fdaSopenharmony_ci } 7818e745fdaSopenharmony_ci if (result.state != State::LIVE && result.state != State::DEAD) { 7828e745fdaSopenharmony_ci changed.emplace(name); 7838e745fdaSopenharmony_ci } 7848e745fdaSopenharmony_ci result.ttl = rr.ttl; 7858e745fdaSopenharmony_ci result.refrehTime = MilliSecondsSinceEpoch(); 7868e745fdaSopenharmony_ci} 7878e745fdaSopenharmony_ci 7888e745fdaSopenharmony_civoid MDnsProtocolImpl::ProcessAnswerRecord(bool v6, const DNSProto::ResourceRecord &rr, std::set<std::string> &changed) 7898e745fdaSopenharmony_ci{ 7908e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log ProcessAnswerRecord, type=[%{public}d]", rr.rtype); 7918e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 7928e745fdaSopenharmony_ci std::string name = rr.name; 7938e745fdaSopenharmony_ci if (cacheMap_.find(name) == cacheMap_.end() && browserMap_.find(name) == browserMap_.end() && 7948e745fdaSopenharmony_ci srvMap_.find(name) != srvMap_.end()) { 7958e745fdaSopenharmony_ci return; 7968e745fdaSopenharmony_ci } 7978e745fdaSopenharmony_ci if (rr.rtype == DNSProto::RRTYPE_PTR) { 7988e745fdaSopenharmony_ci UpdatePtr(v6, rr, changed); 7998e745fdaSopenharmony_ci } else if (rr.rtype == DNSProto::RRTYPE_SRV) { 8008e745fdaSopenharmony_ci UpdateSrv(v6, rr, changed); 8018e745fdaSopenharmony_ci } else if (rr.rtype == DNSProto::RRTYPE_TXT) { 8028e745fdaSopenharmony_ci UpdateTxt(v6, rr, changed); 8038e745fdaSopenharmony_ci } else if (rr.rtype == DNSProto::RRTYPE_A || rr.rtype == DNSProto::RRTYPE_AAAA) { 8048e745fdaSopenharmony_ci UpdateAddr(v6, rr, changed); 8058e745fdaSopenharmony_ci } else { 8068e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log Unknown packet received, type=[%{public}d]", rr.rtype); 8078e745fdaSopenharmony_ci } 8088e745fdaSopenharmony_ci} 8098e745fdaSopenharmony_ci 8108e745fdaSopenharmony_cistd::string MDnsProtocolImpl::GetHostDomain() 8118e745fdaSopenharmony_ci{ 8128e745fdaSopenharmony_ci if (config_.hostname.empty()) { 8138e745fdaSopenharmony_ci char buffer[MDNS_MAX_DOMAIN_LABEL]; 8148e745fdaSopenharmony_ci if (gethostname(buffer, sizeof(buffer)) == 0) { 8158e745fdaSopenharmony_ci config_.hostname = buffer; 8168e745fdaSopenharmony_ci static auto uid = []() { 8178e745fdaSopenharmony_ci std::random_device rd; 8188e745fdaSopenharmony_ci return rd(); 8198e745fdaSopenharmony_ci }(); 8208e745fdaSopenharmony_ci config_.hostname += std::to_string(uid); 8218e745fdaSopenharmony_ci } 8228e745fdaSopenharmony_ci } 8238e745fdaSopenharmony_ci return Decorated(config_.hostname); 8248e745fdaSopenharmony_ci} 8258e745fdaSopenharmony_ci 8268e745fdaSopenharmony_civoid MDnsProtocolImpl::AddTask(const Task &task, bool atonce) 8278e745fdaSopenharmony_ci{ 8288e745fdaSopenharmony_ci { 8298e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 8308e745fdaSopenharmony_ci taskQueue_.emplace_back(task); 8318e745fdaSopenharmony_ci } 8328e745fdaSopenharmony_ci if (atonce) { 8338e745fdaSopenharmony_ci listener_.TriggerRefresh(); 8348e745fdaSopenharmony_ci } 8358e745fdaSopenharmony_ci} 8368e745fdaSopenharmony_ci 8378e745fdaSopenharmony_ciMDnsServiceInfo MDnsProtocolImpl::ConvertResultToInfo(const MDnsProtocolImpl::Result &result) 8388e745fdaSopenharmony_ci{ 8398e745fdaSopenharmony_ci MDnsServiceInfo info; 8408e745fdaSopenharmony_ci info.name = result.serviceName; 8418e745fdaSopenharmony_ci info.type = result.serviceType; 8428e745fdaSopenharmony_ci if (!result.addr.empty()) { 8438e745fdaSopenharmony_ci info.family = result.ipv6 ? MDnsServiceInfo::IPV6 : MDnsServiceInfo::IPV4; 8448e745fdaSopenharmony_ci } 8458e745fdaSopenharmony_ci info.addr = result.addr; 8468e745fdaSopenharmony_ci info.port = result.port; 8478e745fdaSopenharmony_ci info.txtRecord = result.txt; 8488e745fdaSopenharmony_ci return info; 8498e745fdaSopenharmony_ci} 8508e745fdaSopenharmony_ci 8518e745fdaSopenharmony_cibool MDnsProtocolImpl::IsCacheAvailable(const std::string &key) 8528e745fdaSopenharmony_ci{ 8538e745fdaSopenharmony_ci constexpr int64_t ms2S = 1000LL; 8548e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log IsCacheAvailable, ttl=[%{public}u]", cacheMap_[key].ttl); 8558e745fdaSopenharmony_ci return cacheMap_.find(key) != cacheMap_.end() && 8568e745fdaSopenharmony_ci (ms2S * cacheMap_[key].ttl) > static_cast<uint32_t>(MilliSecondsSinceEpoch() - cacheMap_[key].refrehTime); 8578e745fdaSopenharmony_ci} 8588e745fdaSopenharmony_ci 8598e745fdaSopenharmony_cibool MDnsProtocolImpl::IsDomainCacheAvailable(const std::string &key) 8608e745fdaSopenharmony_ci{ 8618e745fdaSopenharmony_ci return IsCacheAvailable(key) && !cacheMap_[key].addr.empty(); 8628e745fdaSopenharmony_ci} 8638e745fdaSopenharmony_ci 8648e745fdaSopenharmony_cibool MDnsProtocolImpl::IsInstanceCacheAvailable(const std::string &key) 8658e745fdaSopenharmony_ci{ 8668e745fdaSopenharmony_ci return IsCacheAvailable(key) && !cacheMap_[key].domain.empty(); 8678e745fdaSopenharmony_ci} 8688e745fdaSopenharmony_ci 8698e745fdaSopenharmony_cibool MDnsProtocolImpl::IsBrowserAvailable(const std::string &key) 8708e745fdaSopenharmony_ci{ 8718e745fdaSopenharmony_ci return browserMap_.find(key) != browserMap_.end() && !browserMap_[key].empty(); 8728e745fdaSopenharmony_ci} 8738e745fdaSopenharmony_ci 8748e745fdaSopenharmony_civoid MDnsProtocolImpl::AddEvent(const std::string &key, const Task &task) 8758e745fdaSopenharmony_ci{ 8768e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 8778e745fdaSopenharmony_ci taskOnChange_[key].emplace_back(task); 8788e745fdaSopenharmony_ci} 8798e745fdaSopenharmony_ci 8808e745fdaSopenharmony_civoid MDnsProtocolImpl::RunTaskQueue(std::list<Task> &queue) 8818e745fdaSopenharmony_ci{ 8828e745fdaSopenharmony_ci std::list<Task> tmp; 8838e745fdaSopenharmony_ci for (auto &&func : queue) { 8848e745fdaSopenharmony_ci if (!func()) { 8858e745fdaSopenharmony_ci tmp.emplace_back(func); 8868e745fdaSopenharmony_ci } 8878e745fdaSopenharmony_ci } 8888e745fdaSopenharmony_ci tmp.swap(queue); 8898e745fdaSopenharmony_ci} 8908e745fdaSopenharmony_ci 8918e745fdaSopenharmony_civoid MDnsProtocolImpl::KillCache(const std::string &key) 8928e745fdaSopenharmony_ci{ 8938e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log KillCache"); 8948e745fdaSopenharmony_ci if (IsBrowserAvailable(key) && browserMap_.find(key) != browserMap_.end()) { 8958e745fdaSopenharmony_ci for (auto it = browserMap_[key].begin(); it != browserMap_[key].end();) { 8968e745fdaSopenharmony_ci KillBrowseCache(key, it); 8978e745fdaSopenharmony_ci } 8988e745fdaSopenharmony_ci } 8998e745fdaSopenharmony_ci if (IsCacheAvailable(key)) { 9008e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 9018e745fdaSopenharmony_ci auto &elem = cacheMap_[key]; 9028e745fdaSopenharmony_ci if (elem.state == State::REMOVE) { 9038e745fdaSopenharmony_ci elem.state = State::DEAD; 9048e745fdaSopenharmony_ci cacheMap_.erase(key); 9058e745fdaSopenharmony_ci } else if (elem.state == State::ADD || elem.state == State::REFRESH) { 9068e745fdaSopenharmony_ci elem.state = State::LIVE; 9078e745fdaSopenharmony_ci } 9088e745fdaSopenharmony_ci } 9098e745fdaSopenharmony_ci} 9108e745fdaSopenharmony_ci 9118e745fdaSopenharmony_civoid MDnsProtocolImpl::KillBrowseCache(const std::string &key, std::vector<Result>::iterator &it) 9128e745fdaSopenharmony_ci{ 9138e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log KillBrowseCache"); 9148e745fdaSopenharmony_ci if (it->state == State::REMOVE) { 9158e745fdaSopenharmony_ci it->state = State::DEAD; 9168e745fdaSopenharmony_ci if (nameCbMap_.find(key) != nameCbMap_.end()) { 9178e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log HandleServiceLost"); 9188e745fdaSopenharmony_ci nameCbMap_[key]->HandleServiceLost(ConvertResultToInfo(*it), NETMANAGER_EXT_SUCCESS); 9198e745fdaSopenharmony_ci } 9208e745fdaSopenharmony_ci std::string fullName = Decorated(it->serviceName + MDNS_DOMAIN_SPLITER_STR + it->serviceType); 9218e745fdaSopenharmony_ci cacheMap_.erase(fullName); 9228e745fdaSopenharmony_ci it = browserMap_[key].erase(it); 9238e745fdaSopenharmony_ci } else if (it->state == State::ADD || it->state == State::REFRESH) { 9248e745fdaSopenharmony_ci it->state = State::LIVE; 9258e745fdaSopenharmony_ci it++; 9268e745fdaSopenharmony_ci } else { 9278e745fdaSopenharmony_ci it++; 9288e745fdaSopenharmony_ci } 9298e745fdaSopenharmony_ci} 9308e745fdaSopenharmony_ci 9318e745fdaSopenharmony_ciint32_t MDnsProtocolImpl::StopCbMap(const std::string &serviceType) 9328e745fdaSopenharmony_ci{ 9338e745fdaSopenharmony_ci NETMGR_EXT_LOG_D("mdns_log StopCbMap"); 9348e745fdaSopenharmony_ci std::lock_guard<std::recursive_mutex> guard(mutex_); 9358e745fdaSopenharmony_ci std::string name = Decorated(serviceType); 9368e745fdaSopenharmony_ci sptr<IDiscoveryCallback> cb = nullptr; 9378e745fdaSopenharmony_ci if (nameCbMap_.find(name) != nameCbMap_.end()) { 9388e745fdaSopenharmony_ci cb = nameCbMap_[name]; 9398e745fdaSopenharmony_ci nameCbMap_.erase(name); 9408e745fdaSopenharmony_ci } 9418e745fdaSopenharmony_ci taskOnChange_.erase(name); 9428e745fdaSopenharmony_ci auto it = browserMap_.find(name); 9438e745fdaSopenharmony_ci if (it != browserMap_.end()) { 9448e745fdaSopenharmony_ci if (cb != nullptr) { 9458e745fdaSopenharmony_ci NETMGR_EXT_LOG_I("mdns_log StopCbMap res size:[%{public}zu]", it->second.size()); 9468e745fdaSopenharmony_ci for (auto &&res : it->second) { 9478e745fdaSopenharmony_ci NETMGR_EXT_LOG_W("mdns_log HandleServiceLost"); 9488e745fdaSopenharmony_ci cb->HandleServiceLost(ConvertResultToInfo(res), NETMANAGER_EXT_SUCCESS); 9498e745fdaSopenharmony_ci } 9508e745fdaSopenharmony_ci } 9518e745fdaSopenharmony_ci browserMap_.erase(name); 9528e745fdaSopenharmony_ci } 9538e745fdaSopenharmony_ci return NETMANAGER_SUCCESS; 9548e745fdaSopenharmony_ci} 9558e745fdaSopenharmony_ci} // namespace NetManagerStandard 9568e745fdaSopenharmony_ci} // namespace OHOS 957