1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "mdns_manager.h"
17 
18 #include <unistd.h>
19 
20 #include "mdns_event_proxy.h"
21 #include "netmgr_ext_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace NetManagerStandard {
25 
GetInstance()26 MDnsManager &MDnsManager::GetInstance()
27 {
28     static MDnsManager sInstance;
29     return sInstance;
30 }
31 
MDnsManager()32 MDnsManager::MDnsManager() {}
33 
RestartMDnsProtocolImpl()34 void MDnsManager::RestartMDnsProtocolImpl()
35 {
36     NETMGR_EXT_LOG_D("mdns_log Network switching");
37     impl.Init();
38     RestartDiscoverService();
39 }
40 
IsSupportIpV6()41 bool MDnsManager::IsSupportIpV6()
42 {
43     return impl.GetConfig().ipv6Support;
44 }
45 
RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)46 int32_t MDnsManager::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)
47 {
48     NETMGR_EXT_LOG_D("mdns_log RegisterService");
49     if (cb == nullptr || cb->AsObject() == nullptr) {
50         NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
51         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
52     }
53 
54     MDnsProtocolImpl::Result result{.serviceName = serviceInfo.name,
55                                     .serviceType = serviceInfo.type,
56                                     .port = serviceInfo.port,
57                                     .txt = serviceInfo.txtRecord};
58 
59     int32_t err = impl.Register(result);
60     impl.AddTask([this, cb, serviceInfo, err]() {
61         cb->HandleRegisterResult(serviceInfo, err);
62         return true;
63     });
64 
65     if (err == NETMANAGER_EXT_SUCCESS) {
66         std::lock_guard<std::recursive_mutex> guard(registerMutex_);
67         registerMap_.emplace(cb, serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type);
68     }
69     return err;
70 }
71 
UnRegisterService(const sptr<IRegistrationCallback> &cb)72 int32_t MDnsManager::UnRegisterService(const sptr<IRegistrationCallback> &cb)
73 {
74     NETMGR_EXT_LOG_D("mdns_log UnRegisterService");
75     if (cb == nullptr || cb->AsObject() == nullptr) {
76         NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
77         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
78     }
79 
80     std::lock_guard<std::recursive_mutex> guard(registerMutex_);
81     auto itr = registerMap_.find(cb);
82     if (registerMap_.end() == itr) {
83         NETMGR_EXT_LOG_W("mdns_log find registrer map failed");
84         return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
85     }
86 
87     int32_t err = impl.UnRegister(itr->second);
88     if (err == NETMANAGER_EXT_SUCCESS) {
89         registerMap_.erase(itr);
90     }
91     return err;
92 }
93 
StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)94 int32_t MDnsManager::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)
95 {
96     NETMGR_EXT_LOG_D("mdns_log StartDiscoverService");
97     if (cb == nullptr || cb->AsObject() == nullptr) {
98         NETMGR_EXT_LOG_E("callback is nullptr");
99         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
100     }
101 
102     if (!IsTypeValid(serviceType)) {
103         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
104     }
105     std::string name = impl.Decorated(serviceType);
106     if (!IsDomainValid(name)) {
107         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
108     }
109 
110     {
111         std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
112         if (discoveryMap_.find(cb) != discoveryMap_.end()) {
113             return NET_MDNS_ERR_CALLBACK_DUPLICATED;
114         }
115         discoveryMap_.emplace(cb, serviceType);
116     }
117     return impl.Discovery(serviceType, cb);
118 }
119 
StopDiscoverService(const sptr<IDiscoveryCallback> &cb)120 int32_t MDnsManager::StopDiscoverService(const sptr<IDiscoveryCallback> &cb)
121 {
122     NETMGR_EXT_LOG_D("mdns_log StopDiscoverService");
123     if (cb == nullptr || cb->AsObject() == nullptr) {
124         NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
125         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
126     }
127     std::string key;
128     {
129         std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
130         auto local = discoveryMap_.find(cb);
131         if (local == discoveryMap_.end()) {
132             return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
133         }
134         key = local->second;
135         discoveryMap_.erase(local);
136     }
137     return impl.StopCbMap(key);
138 }
139 
RestartDiscoverService()140 void MDnsManager::RestartDiscoverService()
141 {
142     NETMGR_EXT_LOG_D("mdns_log RestartDiscoverService");
143     std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
144     for (const auto &it : discoveryMap_) {
145         auto cb = it.first;
146         if (cb == nullptr || cb->AsObject() == nullptr) {
147             NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
148             continue;
149         }
150         auto serviceType = it.second;
151         impl.StopCbMap(serviceType);
152         impl.Discovery(serviceType, cb);
153     }
154 }
155 
ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)156 int32_t MDnsManager::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)
157 {
158     NETMGR_EXT_LOG_D("mdns_log ResolveService");
159     if (cb == nullptr || cb->AsObject() == nullptr) {
160         NETMGR_EXT_LOG_E("mdns_log callback is nullptr");
161         return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
162     }
163 
164     std::string instance = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type;
165     return impl.ResolveInstance(instance, cb);
166 }
167 
GetDumpMessage(std::string &message)168 void MDnsManager::GetDumpMessage(std::string &message)
169 {
170     message.append("mDNS Info:\n");
171     const auto &config = impl.GetConfig();
172     message.append("\tIPv6 Support: " + std::to_string(config.ipv6Support) + "\n");
173     message.append("\tAll Iface: " + std::to_string(config.configAllIface) + "\n");
174     message.append("\tTop Domain: " + config.topDomain + "\n");
175     message.append("\tHostname: " + config.hostname + "\n");
176     message.append("\tImpl Service Count: " + std::to_string(impl.srvMap_.size()) + "\n");
177     message.append("\tDiscovery Count: " + std::to_string(discoveryMap_.size()) + "\n");
178 }
179 
IsAvailableCallback(const sptr<IDiscoveryCallback> &cb)180 bool MDnsManager::IsAvailableCallback(const sptr<IDiscoveryCallback> &cb)
181 {
182     std::lock_guard<std::recursive_mutex> guard(discoveryMutex_);
183     return cb != nullptr && discoveryMap_.find(cb) != discoveryMap_.end();
184 }
185 } // namespace NetManagerStandard
186 } // namespace OHOS