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
MDnsManager()26 MDnsManager::MDnsManager()
27 {
28 InitHandler();
29 }
30
RegisterService(const MDnsServiceInfo & serviceInfo,const sptr<IRegistrationCallback> & cb)31 int32_t MDnsManager::RegisterService(const MDnsServiceInfo &serviceInfo, const sptr<IRegistrationCallback> &cb)
32 {
33 if (cb == nullptr || cb->AsObject() == nullptr) {
34 NETMGR_EXT_LOG_E("callback is nullptr");
35 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
36 }
37 std::lock_guard<std::mutex> guard(mutex_);
38 if (std::find_if(registerMap_.begin(), registerMap_.end(), [cb](const auto &elem) {
39 return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
40 }) != registerMap_.end()) {
41 return NET_MDNS_ERR_CALLBACK_DUPLICATED;
42 }
43 MDnsProtocolImpl::Result result{.serviceName = serviceInfo.name,
44 .serviceType = serviceInfo.type,
45 .port = serviceInfo.port,
46 .txt = serviceInfo.txtRecord};
47 int32_t err = impl.Register(result);
48 impl.RunTaskLater([this, cb, serviceInfo, err]() {
49 cb->HandleRegisterResult(serviceInfo, err);
50 return true;
51 });
52 if (err == NETMANAGER_EXT_SUCCESS) {
53 registerMap_.emplace_back(cb, serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type);
54 }
55 return err;
56 }
57
UnRegisterService(const sptr<IRegistrationCallback> & cb)58 int32_t MDnsManager::UnRegisterService(const sptr<IRegistrationCallback> &cb)
59 {
60 if (cb == nullptr || cb->AsObject() == nullptr) {
61 NETMGR_EXT_LOG_E("callback is nullptr");
62 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
63 }
64 std::lock_guard<std::mutex> guard(mutex_);
65 auto local = std::find_if(registerMap_.begin(), registerMap_.end(), [cb](const auto &elem) {
66 return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
67 });
68 if (local == registerMap_.end()) {
69 return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
70 }
71 int32_t err = impl.UnRegister(local->second);
72 if (err == NETMANAGER_EXT_SUCCESS) {
73 registerMap_.erase(local);
74 }
75 return err;
76 }
77
StartDiscoverService(const std::string & serviceType,const sptr<IDiscoveryCallback> & cb)78 int32_t MDnsManager::StartDiscoverService(const std::string &serviceType, const sptr<IDiscoveryCallback> &cb)
79 {
80 if (cb == nullptr || cb->AsObject() == nullptr) {
81 NETMGR_EXT_LOG_E("callback is nullptr");
82 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
83 }
84 std::lock_guard<std::mutex> guard(mutex_);
85 if (std::find_if(discoveryMap_.begin(), discoveryMap_.end(), [cb](const auto &elem) {
86 return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
87 }) != discoveryMap_.end()) {
88 return NET_MDNS_ERR_CALLBACK_DUPLICATED;
89 }
90 int32_t err = impl.Discovery(serviceType);
91 if (err == NETMANAGER_EXT_SUCCESS) {
92 discoveryMap_.emplace_back(cb, serviceType);
93 }
94 return err;
95 }
96
StopDiscoverService(const sptr<IDiscoveryCallback> & cb)97 int32_t MDnsManager::StopDiscoverService(const sptr<IDiscoveryCallback> &cb)
98 {
99 if (cb == nullptr || cb->AsObject() == nullptr) {
100 NETMGR_EXT_LOG_E("callback is nullptr");
101 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
102 }
103 std::lock_guard<std::mutex> guard(mutex_);
104 auto local = std::find_if(discoveryMap_.begin(), discoveryMap_.end(), [cb](const auto &elem) {
105 return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
106 });
107 if (local == discoveryMap_.end()) {
108 return NET_MDNS_ERR_CALLBACK_NOT_FOUND;
109 }
110 int32_t err = impl.StopDiscovery(local->second);
111 if (err == NETMANAGER_EXT_SUCCESS) {
112 discoveryMap_.erase(local);
113 }
114 return err;
115 }
116
ResolveService(const MDnsServiceInfo & serviceInfo,const sptr<IResolveCallback> & cb)117 int32_t MDnsManager::ResolveService(const MDnsServiceInfo &serviceInfo, const sptr<IResolveCallback> &cb)
118 {
119 if (cb == nullptr || cb->AsObject() == nullptr) {
120 NETMGR_EXT_LOG_E("callback is nullptr");
121 return NET_MDNS_ERR_ILLEGAL_ARGUMENT;
122 }
123 std::lock_guard<std::mutex> guard(mutex_);
124 if (std::find_if(resolveMap_.begin(), resolveMap_.end(), [cb](const auto &elem) {
125 return elem.first->AsObject().GetRefPtr() == cb->AsObject().GetRefPtr();
126 }) != resolveMap_.end()) {
127 return NET_MDNS_ERR_CALLBACK_DUPLICATED;
128 }
129 std::string instance = serviceInfo.name + MDNS_DOMAIN_SPLITER_STR + serviceInfo.type;
130 int32_t err = impl.ResolveInstance(instance);
131 if (err == NETMANAGER_EXT_SUCCESS) {
132 resolveMap_.emplace_back(cb, instance);
133 }
134 cb->HandleResolveResult(serviceInfo, err);
135 return err;
136 }
137
InitHandler()138 void MDnsManager::InitHandler()
139 {
140 static auto handle = [this](const MDnsProtocolImpl::Result &result, int32_t error) {
141 ReceiveResult(result, error);
142 };
143 impl.SetHandler(handle);
144 }
145
ReceiveResult(const MDnsProtocolImpl::Result & result,int32_t error)146 void MDnsManager::ReceiveResult(const MDnsProtocolImpl::Result &result, int32_t error)
147 {
148 NETMGR_EXT_LOG_D("ReceiveResult: %{public}d, error: %{public}d", result.type, error);
149 switch (result.type) {
150 case MDnsProtocolImpl::SERVICE_STARTED:
151 [[fallthrough]];
152 case MDnsProtocolImpl::SERVICE_STOPED:
153 return ReceiveRegister(result, error);
154 case MDnsProtocolImpl::SERVICE_FOUND:
155 [[fallthrough]];
156 case MDnsProtocolImpl::SERVICE_LOST:
157 return ReceiveDiscover(result, error);
158 case MDnsProtocolImpl::INSTANCE_RESOLVED:
159 return ReceiveInstanceResolve(result, error);
160 case MDnsProtocolImpl::DOMAIN_RESOLVED:
161 [[fallthrough]];
162 case MDnsProtocolImpl::UNKNOWN:
163 [[fallthrough]];
164 default:
165 return;
166 }
167 }
168
ReceiveRegister(const MDnsProtocolImpl::Result & result,int32_t error)169 void MDnsManager::ReceiveRegister(const MDnsProtocolImpl::Result &result, int32_t error) {}
170
ReceiveDiscover(const MDnsProtocolImpl::Result & result,int32_t error)171 void MDnsManager::ReceiveDiscover(const MDnsProtocolImpl::Result &result, int32_t error)
172 {
173 NETMGR_EXT_LOG_D("discoveryMap_ size: [%{public}zu]", discoveryMap_.size());
174 std::lock_guard<std::mutex> guard(mutex_);
175 for (auto iter = discoveryMap_.begin(); iter != discoveryMap_.end(); ++iter) {
176 if (iter->second != result.serviceType) {
177 continue;
178 }
179 auto cb = iter->first;
180 MDnsServiceInfo info;
181 info.name = result.serviceName;
182 info.type = result.serviceType;
183 if (result.type == MDnsProtocolImpl::SERVICE_FOUND) {
184 cb->HandleServiceFound(info, error);
185 }
186 if (result.type == MDnsProtocolImpl::SERVICE_LOST) {
187 cb->HandleServiceLost(info, error);
188 }
189 }
190 }
191
ReceiveInstanceResolve(const MDnsProtocolImpl::Result & result,int32_t error)192 void MDnsManager::ReceiveInstanceResolve(const MDnsProtocolImpl::Result &result, int32_t error)
193 {
194 NETMGR_EXT_LOG_D("resolveMap_ size: [%{public}zu]", resolveMap_.size());
195 std::lock_guard<std::mutex> guard(mutex_);
196 for (auto iter = resolveMap_.begin(); iter != resolveMap_.end();) {
197 if (iter->second != result.serviceName + MDNS_DOMAIN_SPLITER_STR + result.serviceType) {
198 ++iter;
199 continue;
200 }
201
202 if (result.addr.empty()|| result.domain.empty()) {
203 ++iter;
204 continue;
205 }
206
207 auto cb = iter->first;
208 impl.StopResolveInstance(result.serviceName + MDNS_DOMAIN_SPLITER_STR + result.serviceType);
209 cb->HandleResolveResult(ConvertResultToInfo(result), error);
210 iter = resolveMap_.erase(iter);
211 }
212 }
213
ConvertResultToInfo(const MDnsProtocolImpl::Result & result)214 MDnsServiceInfo MDnsManager::ConvertResultToInfo(const MDnsProtocolImpl::Result &result)
215 {
216 MDnsServiceInfo info;
217 info.name = result.serviceName;
218 info.type = result.serviceType;
219 if (!result.addr.empty()) {
220 info.family = result.ipv6 ? MDnsServiceInfo::IPV6 : MDnsServiceInfo::IPV4;
221 }
222 info.addr = result.addr;
223 info.port = result.port;
224 info.txtRecord = result.txt;
225 return info;
226 }
227
GetDumpMessage(std::string & message)228 void MDnsManager::GetDumpMessage(std::string &message)
229 {
230 message.append("mDNS Info:\n");
231 const auto &config = impl.GetConfig();
232 message.append("\tIPv6 Support: " + std::to_string(config.ipv6Support) + "\n");
233 message.append("\tAll Iface: " + std::to_string(config.configAllIface) + "\n");
234 message.append("\tTop Domain: " + config.topDomain + "\n");
235 message.append("\tHostname: " + config.hostname + "\n");
236 message.append("\tService Count: " + std::to_string(registerMap_.size()) + "\n");
237 }
238 } // namespace NetManagerStandard
239 } // namespace OHOS