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 #include <charconv>
19
20 #include "dns_resolv_listen.h"
21 #include "netmanager_base_common_utils.h"
22 #include "netnative_log_wrapper.h"
23 #include "singleton.h"
24 #include "dns_quality_diag.h"
25 #ifdef QOS_MANAGER_ENABLE
26 #include "qos.h"
27 #include "concurrent_task_client.h"
28 #include <sys/resource.h>
29 #endif
30
31 #include "dns_manager.h"
32 #include <netdb.h>
33
34 namespace OHOS {
35 namespace nmd {
36 using namespace OHOS::NetManagerStandard::CommonUtils;
37 constexpr const char *IPV6_DEFAULT_GATEWAY = "::";
StartListen()38 void StartListen()
39 {
40 NETNATIVE_LOG_D("Enter threadStart");
41 #ifdef QOS_MANAGER_ENABLE
42 std::unordered_map<std::string, std::string> payload;
43 payload["pid"] = std::to_string(getpid());
44 OHOS::ConcurrentTask::ConcurrentTaskClient::GetInstance().RequestAuth(payload);
45 if (SetThreadQos(QOS::QosLevel::QOS_USER_INITIATED) != 0) {
46 setpriority(PRIO_PROCESS, 0, PRIO_MIN);
47 }
48 NETNATIVE_LOGI("DnsMgerListen set qos end");
49 #endif
50 DnsResolvListen().StartListen();
51 }
52
DnsManager()53 DnsManager::DnsManager() : dnsProxyListen_(std::make_shared<DnsProxyListen>())
54 {
55 std::thread t(StartListen);
56 std::string threadName = "DnsMgerListen";
57 pthread_setname_np(t.native_handle(), threadName.c_str());
58 t.detach();
59 }
60
EnableIpv6(uint16_t netId,std::string & destination,const std::string & nextHop)61 void DnsManager::EnableIpv6(uint16_t netId, std::string &destination, const std::string &nextHop)
62 {
63 auto pos = destination.find("/");
64 if (pos == std::string::npos) {
65 return;
66 }
67 std::string ip = destination.substr(0, pos);
68 std::string prefixStr = destination.substr(pos + 1);
69 int prefix = -1;
70 auto result = std::from_chars(prefixStr.data(), prefixStr.data() + prefixStr.size(), prefix);
71 if (result.ec != std::errc()) {
72 return;
73 }
74
75 if ((IsValidIPV6(ip) && prefix == 0) && (IsValidIPV6(nextHop) || nextHop.empty())) {
76 DnsParamCache::GetInstance().EnableIpv6(netId);
77 }
78 }
79
SetResolverConfig(uint16_t netId,uint16_t baseTimeoutMillis,uint8_t retryCount,const std::vector<std::string> & servers,const std::vector<std::string> & domains)80 int32_t DnsManager::SetResolverConfig(uint16_t netId, uint16_t baseTimeoutMillis, uint8_t retryCount,
81 const std::vector<std::string> &servers, const std::vector<std::string> &domains)
82 {
83 NETNATIVE_LOG_D("manager_SetResolverConfig netId[%{public}d]", netId);
84 return DnsParamCache::GetInstance().SetResolverConfig(netId, baseTimeoutMillis, retryCount, servers, domains);
85 }
86
GetResolverConfig(uint16_t netId,std::vector<std::string> & servers,std::vector<std::string> & domains,uint16_t & baseTimeoutMillis,uint8_t & retryCount)87 int32_t DnsManager::GetResolverConfig(uint16_t netId, std::vector<std::string> &servers,
88 std::vector<std::string> &domains, uint16_t &baseTimeoutMillis,
89 uint8_t &retryCount)
90 {
91 NETNATIVE_LOG_D("manager_GetResolverConfig netId[%{public}d]", netId);
92 return DnsParamCache::GetInstance().GetResolverConfig(netId, servers, domains, baseTimeoutMillis, retryCount);
93 }
94
CreateNetworkCache(uint16_t netId,bool isVpnNet)95 int32_t DnsManager::CreateNetworkCache(uint16_t netId, bool isVpnNet)
96 {
97 NETNATIVE_LOG_D("manager_CreateNetworkCache netId[%{public}d]", netId);
98 return DnsParamCache::GetInstance().CreateCacheForNet(netId, isVpnNet);
99 }
100
DestroyNetworkCache(uint16_t netId,bool isVpnNet)101 int32_t DnsManager::DestroyNetworkCache(uint16_t netId, bool isVpnNet)
102 {
103 return DnsParamCache::GetInstance().DestroyNetworkCache(netId, isVpnNet);
104 }
105
SetDefaultNetwork(uint16_t netId)106 void DnsManager::SetDefaultNetwork(uint16_t netId)
107 {
108 DnsParamCache::GetInstance().SetDefaultNetwork(netId);
109 }
110
StartProxyListen()111 void StartProxyListen()
112 {
113 NETNATIVE_LOG_D("begin StartProxyListen");
114 DnsProxyListen().StartListen();
115 }
116
ShareDnsSet(uint16_t netId)117 void DnsManager::ShareDnsSet(uint16_t netId)
118 {
119 dnsProxyListen_->SetParseNetId(netId);
120 }
121
StartDnsProxyListen()122 void DnsManager::StartDnsProxyListen()
123 {
124 dnsProxyListen_->OnListen();
125 std::thread t(StartProxyListen);
126 std::string threadName = "DnsPxyListen";
127 pthread_setname_np(t.native_handle(), threadName.c_str());
128 t.detach();
129 }
130
StopDnsProxyListen()131 void DnsManager::StopDnsProxyListen()
132 {
133 dnsProxyListen_->OffListen();
134 }
135
GetDumpInfo(std::string & info)136 void DnsManager::GetDumpInfo(std::string &info)
137 {
138 NETNATIVE_LOG_D("Get dump info");
139 DnsParamCache::GetInstance().GetDumpInfo(info);
140 }
141
GetAddrInfo(const std::string & hostName,const std::string & serverName,const AddrInfo & hints,uint16_t netId,std::vector<AddrInfo> & res)142 int32_t DnsManager::GetAddrInfo(const std::string &hostName, const std::string &serverName, const AddrInfo &hints,
143 uint16_t netId, std::vector<AddrInfo> &res)
144 {
145 if (netId == 0) {
146 netId = DnsParamCache::GetInstance().GetDefaultNetwork();
147 NETNATIVE_LOG_D("DnsManager DnsGetaddrinfo netId == 0 defaultNetId_ : %{public}d", netId);
148 }
149 struct addrinfo hint = {};
150 struct addrinfo *result;
151 struct queryparam qparam = {};
152
153 if ((hostName.size() == 0) && (serverName.size() == 0)) {
154 return -1;
155 }
156
157 qparam.qp_netid = netId;
158 qparam.qp_type = 1;
159
160 hint.ai_family = hints.aiFamily;
161 hint.ai_flags = hints.aiFlags;
162 hint.ai_protocol = hints.aiProtocol;
163 hint.ai_socktype = hints.aiSockType;
164
165 int32_t ret = getaddrinfo_ext(((hostName.size() == 0) ? NULL : hostName.c_str()),
166 ((serverName.size() == 0) ? NULL : serverName.c_str()),
167 &hint, &result, &qparam);
168 if (ret == 0) {
169 ret = FillAddrInfo(res, result);
170 freeaddrinfo(result);
171 }
172
173 return ret;
174 }
175
RegisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> & callback,uint32_t timeStep)176 int32_t DnsManager::RegisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> &callback,
177 uint32_t timeStep)
178 {
179 return DnsQualityDiag::GetInstance().RegisterResultListener(callback, timeStep);
180 }
181
UnregisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> & callback)182 int32_t DnsManager::UnregisterDnsResultCallback(const sptr<NetsysNative::INetDnsResultCallback> &callback)
183 {
184 return DnsQualityDiag::GetInstance().UnregisterResultListener(callback);
185 }
186
RegisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> & callback)187 int32_t DnsManager::RegisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> &callback)
188 {
189 return DnsQualityDiag::GetInstance().RegisterHealthListener(callback);
190 }
191
UnregisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> & callback)192 int32_t DnsManager::UnregisterDnsHealthCallback(const sptr<NetsysNative::INetDnsHealthCallback> &callback)
193 {
194 return DnsQualityDiag::GetInstance().UnregisterHealthListener(callback);
195 }
196
AddUidRange(int32_t netId,const std::vector<NetManagerStandard::UidRange> & uidRanges)197 int32_t DnsManager::AddUidRange(int32_t netId, const std::vector<NetManagerStandard::UidRange> &uidRanges)
198 {
199 NETNATIVE_LOG_D("DnsManager::AddUidRange");
200 return DnsParamCache::GetInstance().AddUidRange(netId, uidRanges);
201 }
202
DelUidRange(int32_t netId,const std::vector<NetManagerStandard::UidRange> & uidRanges)203 int32_t DnsManager::DelUidRange(int32_t netId, const std::vector<NetManagerStandard::UidRange> &uidRanges)
204 {
205 NETNATIVE_LOG_D("DnsManager::DelUidRange");
206 return DnsParamCache::GetInstance().DelUidRange(netId, uidRanges);
207 }
208
FillAddrInfo(std::vector<AddrInfo> & addrInfo,addrinfo * res)209 int32_t DnsManager::FillAddrInfo(std::vector<AddrInfo> &addrInfo, addrinfo *res)
210 {
211 int32_t resNum = 0;
212 addrinfo *tmp = res;
213
214 while (tmp) {
215 AddrInfo info;
216 info.aiFlags = static_cast<int32_t>(tmp->ai_flags);
217 info.aiFamily = static_cast<int32_t>(tmp->ai_family);
218 info.aiSockType = static_cast<int32_t>(tmp->ai_socktype);
219 info.aiProtocol = static_cast<int32_t>(tmp->ai_protocol);
220 info.aiAddrLen = tmp->ai_addrlen;
221 if (memcpy_s(&info.aiAddr, sizeof(info.aiAddr), tmp->ai_addr, tmp->ai_addrlen) != 0) {
222 NETNATIVE_LOGE("memcpy_s failed");
223 }
224 if (strcpy_s(info.aiCanonName, sizeof(info.aiCanonName), tmp->ai_canonname) != 0) {
225 NETNATIVE_LOGE("strcpy_s failed");
226 }
227
228 ++resNum;
229 addrInfo.emplace_back(info);
230 tmp = tmp->ai_next;
231 if (resNum >= MAX_RESULTS) {
232 break;
233 }
234 }
235 NETNATIVE_LOGI("FillAddrInfo %{public}d", resNum);
236 return 0;
237 }
238
239 #ifdef FEATURE_NET_FIREWALL_ENABLE
SetFirewallDefaultAction(FirewallRuleAction inDefault,FirewallRuleAction outDefault)240 int32_t DnsManager::SetFirewallDefaultAction(FirewallRuleAction inDefault, FirewallRuleAction outDefault)
241 {
242 return DnsParamCache::GetInstance().SetFirewallDefaultAction(inDefault, outDefault);
243 }
244
SetFirewallCurrentUserId(int32_t userId)245 int32_t DnsManager::SetFirewallCurrentUserId(int32_t userId)
246 {
247 return DnsParamCache::GetInstance().SetFirewallCurrentUserId(userId);
248 }
249
SetFirewallRules(NetFirewallRuleType type,const std::vector<sptr<NetFirewallBaseRule>> & ruleList,bool isFinish)250 int32_t DnsManager::SetFirewallRules(NetFirewallRuleType type, const std::vector<sptr<NetFirewallBaseRule>> &ruleList,
251 bool isFinish)
252 {
253 return DnsParamCache::GetInstance().SetFirewallRules(type, ruleList, isFinish);
254 }
255
ClearFirewallRules(NetFirewallRuleType type)256 int32_t DnsManager::ClearFirewallRules(NetFirewallRuleType type)
257 {
258 return DnsParamCache::GetInstance().ClearFirewallRules(type);
259 }
260
RegisterNetFirewallCallback(const sptr<NetsysNative::INetFirewallCallback> & callback)261 int32_t DnsManager::RegisterNetFirewallCallback(const sptr<NetsysNative::INetFirewallCallback> &callback)
262 {
263 return DnsParamCache::GetInstance().RegisterNetFirewallCallback(callback);
264 }
UnRegisterNetFirewallCallback(const sptr<NetsysNative::INetFirewallCallback> & callback)265 int32_t DnsManager::UnRegisterNetFirewallCallback(const sptr<NetsysNative::INetFirewallCallback> &callback)
266 {
267 return DnsParamCache::GetInstance().UnRegisterNetFirewallCallback(callback);
268 }
269 #endif
270
SetUserDefinedServerFlag(uint16_t netId,bool flag)271 int32_t DnsManager::SetUserDefinedServerFlag(uint16_t netId, bool flag)
272 {
273 NETNATIVE_LOGI("manager_SetUserDefinedServerFlag netId[%{public}d] flag[%{public}d]", netId, flag);
274 return DnsParamCache::GetInstance().SetUserDefinedServerFlag(netId, flag);
275 }
276
FlushDnsCache(uint16_t netId)277 int32_t DnsManager::FlushDnsCache(uint16_t netId)
278 {
279 NETNATIVE_LOGI("manager_FlushDnsCache netId[%{public}d]", netId);
280 return DnsParamCache::GetInstance().FlushDnsCache(netId);
281 }
282
SetDnsCache(uint16_t netId,const std::string & hostName,const AddrInfo & addrInfo)283 int32_t DnsManager::SetDnsCache(uint16_t netId, const std::string &hostName, const AddrInfo &addrInfo)
284 {
285 DnsParamCache::GetInstance().SetDnsCache(netId, hostName, addrInfo);
286 return 0;
287 }
288 } // namespace nmd
289 } // namespace OHOS
290