1 /*
2 * Copyright (c) 2022-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 <pthread.h>
17 #include <thread>
18
19 #include "dns_resolv_listen.h"
20 #include "netmanager_base_common_utils.h"
21 #include "netnative_log_wrapper.h"
22 #include "singleton.h"
23 #include "dns_quality_diag.h"
24
25 #include "dns_manager.h"
26 #include <netdb.h>
27
28 namespace OHOS {
29 namespace nmd {
30 using namespace OHOS::NetManagerStandard::CommonUtils;
31
StartListen()32 void StartListen()
33 {
34 NETNATIVE_LOG_D("Enter threadStart");
35 DnsResolvListen().StartListen();
36 }
37
DnsManager()38 DnsManager::DnsManager() : dnsProxyListen_(std::make_shared<DnsProxyListen>())
39 {
40 std::thread t(StartListen);
41 std::string threadName = "DnsMgerListen";
42 pthread_setname_np(t.native_handle(), threadName.c_str());
43 t.detach();
44 }
45
EnableIpv6(uint16_t netId,std::string & destination,const std::string & nextHop)46 void DnsManager::EnableIpv6(uint16_t netId, std::string &destination, const std::string &nextHop)
47 {
48 auto pos = destination.find("/");
49 if (pos != std::string::npos) {
50 destination = destination.substr(0, pos);
51 }
52 if (!IsValidIPV6(destination) || !IsValidIPV6(nextHop)) {
53 NETNATIVE_LOGE("check IsValidIPV6 faild");
54 return;
55 }
56 DnsParamCache::GetInstance().EnableIpv6(netId);
57 }
58
SetResolverConfig(uint16_t netId,uint16_t baseTimeoutMillis,uint8_t retryCount,const std::vector<std::string> & servers,const std::vector<std::string> & domains)59 int32_t DnsManager::SetResolverConfig(uint16_t netId, uint16_t baseTimeoutMillis, uint8_t retryCount,
60 const std::vector<std::string> &servers, const std::vector<std::string> &domains)
61 {
62 NETNATIVE_LOG_D("manager_SetResolverConfig netId[%{public}d]", netId);
63 return DnsParamCache::GetInstance().SetResolverConfig(netId, baseTimeoutMillis, retryCount, servers, domains);
64 }
65
GetResolverConfig(uint16_t netId,std::vector<std::string> & servers,std::vector<std::string> & domains,uint16_t & baseTimeoutMillis,uint8_t & retryCount)66 int32_t DnsManager::GetResolverConfig(uint16_t netId, std::vector<std::string> &servers,
67 std::vector<std::string> &domains, uint16_t &baseTimeoutMillis,
68 uint8_t &retryCount)
69 {
70 NETNATIVE_LOG_D("manager_GetResolverConfig netId[%{public}d]", netId);
71 return DnsParamCache::GetInstance().GetResolverConfig(netId, servers, domains, baseTimeoutMillis, retryCount);
72 }
73
CreateNetworkCache(uint16_t netId)74 int32_t DnsManager::CreateNetworkCache(uint16_t netId)
75 {
76 NETNATIVE_LOG_D("manager_CreateNetworkCache netId[%{public}d]", netId);
77 return DnsParamCache::GetInstance().CreateCacheForNet(netId);
78 }
79
DestroyNetworkCache(uint16_t netId)80 int32_t DnsManager::DestroyNetworkCache(uint16_t netId)
81 {
82 return DnsParamCache::GetInstance().DestroyNetworkCache(netId);
83 }
84
SetDefaultNetwork(uint16_t netId)85 void DnsManager::SetDefaultNetwork(uint16_t netId)
86 {
87 DnsParamCache::GetInstance().SetDefaultNetwork(netId);
88 }
89
StartProxyListen()90 void StartProxyListen()
91 {
92 NETNATIVE_LOG_D("begin StartProxyListen");
93 DnsProxyListen().StartListen();
94 }
95
ShareDnsSet(uint16_t netId)96 void DnsManager::ShareDnsSet(uint16_t netId)
97 {
98 dnsProxyListen_->SetParseNetId(netId);
99 }
100
StartDnsProxyListen()101 void DnsManager::StartDnsProxyListen()
102 {
103 dnsProxyListen_->OnListen();
104 std::thread t(StartProxyListen);
105 std::string threadName = "DnsPxyListen";
106 pthread_setname_np(t.native_handle(), threadName.c_str());
107 t.detach();
108 }
109
StopDnsProxyListen()110 void DnsManager::StopDnsProxyListen()
111 {
112 dnsProxyListen_->OffListen();
113 }
114
GetDumpInfo(std::string & info)115 void DnsManager::GetDumpInfo(std::string &info)
116 {
117 NETNATIVE_LOG_D("Get dump info");
118 DnsParamCache::GetInstance().GetDumpInfo(info);
119 }
120
GetAddrInfo(const std::string & hostName,const std::string & serverName,const AddrInfo & hints,uint16_t netId,std::vector<AddrInfo> & res)121 int32_t DnsManager::GetAddrInfo(const std::string &hostName, const std::string &serverName, const AddrInfo &hints,
122 uint16_t netId, std::vector<AddrInfo> &res)
123 {
124 if (netId == 0) {
125 netId = DnsParamCache::GetInstance().GetDefaultNetwork();
126 NETNATIVE_LOG_D("DnsManager DnsGetaddrinfo netId == 0 defaultNetId_ : %{public}d", netId);
127 }
128 struct addrinfo hint = {};
129 struct addrinfo *result;
130 struct queryparam qparam = {};
131
132 if ((hostName.size() == 0) && (serverName.size() == 0)) {
133 return -1;
134 }
135
136 qparam.qp_netid = netId;
137 qparam.qp_type = 0;
138
139 hint.ai_family = hints.aiFamily;
140 hint.ai_flags = hints.aiFlags;
141 hint.ai_protocol = hints.aiProtocol;
142 hint.ai_socktype = hints.aiSockType;
143
144 int32_t ret = getaddrinfo_ext(((hostName.size() == 0) ? NULL : hostName.c_str()),
145 ((serverName.size() == 0) ? NULL : serverName.c_str()),
146 &hint, &result, &qparam);
147 if (ret == 0) {
148 ret = FillAddrInfo(res, result);
149 freeaddrinfo(result);
150 }
151
152 return ret;
153 }
154
RegisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> & callback,uint32_t timeStep)155 int32_t DnsManager::RegisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> &callback,
156 uint32_t timeStep)
157 {
158 return DnsQualityDiag::GetInstance().RegisterResultListener(callback, timeStep);
159 }
160
UnregisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> & callback)161 int32_t DnsManager::UnregisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> &callback)
162 {
163 return DnsQualityDiag::GetInstance().UnregisterResultListener(callback);
164 }
165
RegisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> & callback)166 int32_t DnsManager::RegisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> &callback)
167 {
168 return DnsQualityDiag::GetInstance().RegisterHealthListener(callback);
169 }
170
UnregisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> & callback)171 int32_t DnsManager::UnregisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> &callback)
172 {
173 return DnsQualityDiag::GetInstance().UnregisterHealthListener(callback);
174 }
175
FillAddrInfo(std::vector<AddrInfo> & addrInfo,addrinfo * res)176 int32_t DnsManager::FillAddrInfo(std::vector<AddrInfo> &addrInfo, addrinfo *res)
177 {
178 int32_t resNum = 0;
179 addrinfo *tmp = res;
180
181 while (tmp) {
182 AddrInfo info;
183 info.aiFlags = tmp->ai_flags;
184 info.aiFamily = tmp->ai_family;
185 info.aiSockType = tmp->ai_socktype;
186 info.aiProtocol = tmp->ai_protocol;
187 info.aiAddrLen = tmp->ai_addrlen;
188 if (memcpy_s(&info.aiAddr, sizeof(info.aiAddr), tmp->ai_addr, tmp->ai_addrlen) != 0) {
189 NETNATIVE_LOGE("memcpy_s failed");
190 }
191 if (strcpy_s(info.aiCanonName, sizeof(info.aiCanonName), tmp->ai_canonname) != 0) {
192 NETNATIVE_LOGE("strcpy_s failed");
193 }
194
195 ++resNum;
196 addrInfo.emplace_back(info);
197 tmp = tmp->ai_next;
198 if (resNum >= MAX_RESULTS) {
199 break;
200 }
201 }
202 NETNATIVE_LOGI("FillAddrInfo %{public}d", resNum);
203 return 0;
204 }
205 } // namespace nmd
206 } // namespace OHOS
207