1 /*
2 * Copyright (c) 2022 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 "dns_param_cache.h"
17
18 #include <algorithm>
19
20 #include "netmanager_base_common_utils.h"
21
22 namespace OHOS::nmd {
23 using namespace OHOS::NetManagerStandard::CommonUtils;
24 namespace {
GetVectorData(const std::vector<std::string> & data,std::string & result)25 void GetVectorData(const std::vector<std::string> &data, std::string &result)
26 {
27 result.append("{ ");
28 std::for_each(data.begin(), data.end(), [&result](const auto &str) { result.append(ToAnonymousIp(str) + ", "); });
29 result.append("}\n");
30 }
31 constexpr int RES_TIMEOUT = 5000; // min. milliseconds between retries
32 constexpr int RES_DEFAULT_RETRY = 2; // Default
33 } // namespace
34
DnsParamCache()35 DnsParamCache::DnsParamCache() : defaultNetId_(0) {}
36
GetInstance()37 DnsParamCache &DnsParamCache::GetInstance()
38 {
39 static DnsParamCache instance;
40 return instance;
41 }
42
SelectNameservers(const std::vector<std::string> & servers)43 std::vector<std::string> DnsParamCache::SelectNameservers(const std::vector<std::string> &servers)
44 {
45 std::vector<std::string> res = servers;
46 if (res.size() > MAX_SERVER_NUM) {
47 res.resize(MAX_SERVER_NUM);
48 }
49 return res;
50 }
51
CreateCacheForNet(uint16_t netId)52 int32_t DnsParamCache::CreateCacheForNet(uint16_t netId)
53 {
54 NETNATIVE_LOG_D("DnsParamCache::CreateCacheForNet, netid:%{public}d,", netId);
55 std::lock_guard<std::mutex> guard(cacheMutex_);
56 auto it = serverConfigMap_.find(netId);
57 if (it != serverConfigMap_.end()) {
58 NETNATIVE_LOGE("DnsParamCache::CreateCacheForNet, netid already exist, no need to create");
59 return -EEXIST;
60 }
61 serverConfigMap_[netId].SetNetId(netId);
62 return 0;
63 }
64
DestroyNetworkCache(uint16_t netId)65 int32_t DnsParamCache::DestroyNetworkCache(uint16_t netId)
66 {
67 NETNATIVE_LOG_D("DnsParamCache::CreateCacheForNet, netid:%{public}d,", netId);
68 std::lock_guard<std::mutex> guard(cacheMutex_);
69 auto it = serverConfigMap_.find(netId);
70 if (it == serverConfigMap_.end()) {
71 return -ENOENT;
72 }
73 serverConfigMap_.erase(it);
74 if (defaultNetId_ == netId) {
75 defaultNetId_ = 0;
76 }
77 return 0;
78 }
79
SetResolverConfig(uint16_t netId,uint16_t baseTimeoutMsec,uint8_t retryCount,const std::vector<std::string> & servers,const std::vector<std::string> & domains)80 int32_t DnsParamCache::SetResolverConfig(uint16_t netId, uint16_t baseTimeoutMsec, uint8_t retryCount,
81 const std::vector<std::string> &servers,
82 const std::vector<std::string> &domains)
83 {
84 std::vector<std::string> nameservers = SelectNameservers(servers);
85 NETNATIVE_LOG_D("DnsParamCache::SetResolverConfig, netid:%{public}d, numServers:%{public}d,", netId,
86 static_cast<int>(nameservers.size()));
87
88 std::lock_guard<std::mutex> guard(cacheMutex_);
89
90 // select_domains
91 auto it = serverConfigMap_.find(netId);
92 if (it == serverConfigMap_.end()) {
93 NETNATIVE_LOGE("DnsParamCache::SetResolverConfig failed, netid is non-existent");
94 return -ENOENT;
95 }
96
97 auto oldDnsServers = it->second.GetServers();
98 std::sort(oldDnsServers.begin(), oldDnsServers.end());
99
100 auto newDnsServers = servers;
101 std::sort(newDnsServers.begin(), newDnsServers.end());
102
103 if (oldDnsServers != newDnsServers) {
104 it->second.GetCache().Clear();
105 }
106
107 it->second.SetNetId(netId);
108 it->second.SetServers(servers);
109 it->second.SetDomains(domains);
110 if (retryCount == 0) {
111 it->second.SetRetryCount(RES_DEFAULT_RETRY);
112 } else {
113 it->second.SetRetryCount(retryCount);
114 }
115 if (baseTimeoutMsec == 0) {
116 it->second.SetTimeoutMsec(RES_TIMEOUT);
117 } else {
118 it->second.SetTimeoutMsec(baseTimeoutMsec);
119 }
120 return 0;
121 }
122
SetDefaultNetwork(uint16_t netId)123 void DnsParamCache::SetDefaultNetwork(uint16_t netId)
124 {
125 defaultNetId_ = netId;
126 }
127
EnableIpv6(uint16_t netId)128 void DnsParamCache::EnableIpv6(uint16_t netId)
129 {
130 std::lock_guard<std::mutex> guard(cacheMutex_);
131 auto it = serverConfigMap_.find(netId);
132 if (it == serverConfigMap_.end()) {
133 DNS_CONFIG_PRINT("get Config failed: netid is not have netid:%{public}d,", netId);
134 return;
135 }
136
137 it->second.EnableIpv6();
138 }
139
IsIpv6Enable(uint16_t netId)140 bool DnsParamCache::IsIpv6Enable(uint16_t netId)
141 {
142 if (netId == 0) {
143 netId = defaultNetId_;
144 }
145
146 std::lock_guard<std::mutex> guard(cacheMutex_);
147 auto it = serverConfigMap_.find(netId);
148 if (it == serverConfigMap_.end()) {
149 DNS_CONFIG_PRINT("get Config failed: netid is not have netid:%{public}d,", netId);
150 return false;
151 }
152
153 return it->second.IsIpv6Enable();
154 }
155
GetResolverConfig(uint16_t netId,std::vector<std::string> & servers,std::vector<std::string> & domains,uint16_t & baseTimeoutMsec,uint8_t & retryCount)156 int32_t DnsParamCache::GetResolverConfig(uint16_t netId, std::vector<std::string> &servers,
157 std::vector<std::string> &domains, uint16_t &baseTimeoutMsec,
158 uint8_t &retryCount)
159 {
160 if (netId == 0) {
161 netId = defaultNetId_;
162 }
163
164 std::lock_guard<std::mutex> guard(cacheMutex_);
165 auto it = serverConfigMap_.find(netId);
166 if (it == serverConfigMap_.end()) {
167 DNS_CONFIG_PRINT("get Config failed: netid is not have netid:%{public}d,", netId);
168 return -ENOENT;
169 }
170
171 servers = it->second.GetServers();
172 domains = it->second.GetDomains();
173 baseTimeoutMsec = it->second.GetTimeoutMsec();
174 retryCount = it->second.GetRetryCount();
175
176 return 0;
177 }
178
GetDefaultNetwork() const179 int32_t DnsParamCache::GetDefaultNetwork() const
180 {
181 return defaultNetId_;
182 }
183
SetDnsCache(uint16_t netId,const std::string & hostName,const AddrInfo & addrInfo)184 void DnsParamCache::SetDnsCache(uint16_t netId, const std::string &hostName, const AddrInfo &addrInfo)
185 {
186 if (netId == 0) {
187 netId = defaultNetId_;
188 }
189 std::lock_guard<std::mutex> guard(cacheMutex_);
190 auto it = serverConfigMap_.find(netId);
191 if (it == serverConfigMap_.end()) {
192 DNS_CONFIG_PRINT("SetDnsCache failed: netid is not have netid:%{public}d,", netId);
193 return;
194 }
195
196 it->second.GetCache().Put(hostName, addrInfo);
197 }
198
GetDnsCache(uint16_t netId,const std::string & hostName)199 std::vector<AddrInfo> DnsParamCache::GetDnsCache(uint16_t netId, const std::string &hostName)
200 {
201 if (netId == 0) {
202 netId = defaultNetId_;
203 }
204
205 std::lock_guard<std::mutex> guard(cacheMutex_);
206 auto it = serverConfigMap_.find(netId);
207 if (it == serverConfigMap_.end()) {
208 DNS_CONFIG_PRINT("GetDnsCache failed: netid is not have netid:%{public}d,", netId);
209 return {};
210 }
211
212 return it->second.GetCache().Get(hostName);
213 }
214
SetCacheDelayed(uint16_t netId,const std::string & hostName)215 void DnsParamCache::SetCacheDelayed(uint16_t netId, const std::string &hostName)
216 {
217 if (netId == 0) {
218 netId = defaultNetId_;
219 }
220
221 std::lock_guard<std::mutex> guard(cacheMutex_);
222 auto it = serverConfigMap_.find(netId);
223 if (it == serverConfigMap_.end()) {
224 DNS_CONFIG_PRINT("SetCacheDelayed failed: netid is not have netid:%{public}d,", netId);
225 return;
226 }
227
228 it->second.SetCacheDelayed(hostName);
229 }
230
GetDumpInfo(std::string & info)231 void DnsParamCache::GetDumpInfo(std::string &info)
232 {
233 std::string dnsData;
234 static const std::string TAB = " ";
235 std::for_each(serverConfigMap_.begin(), serverConfigMap_.end(), [&dnsData](const auto &serverConfig) {
236 dnsData.append(TAB + "NetId: " + std::to_string(serverConfig.second.GetNetId()) + "\n");
237 dnsData.append(TAB + "TimeoutMsec: " + std::to_string(serverConfig.second.GetTimeoutMsec()) + "\n");
238 dnsData.append(TAB + "RetryCount: " + std::to_string(serverConfig.second.GetRetryCount()) + "\n");
239 dnsData.append(TAB + "Servers:");
240 GetVectorData(serverConfig.second.GetServers(), dnsData);
241 dnsData.append(TAB + "Domains:");
242 GetVectorData(serverConfig.second.GetDomains(), dnsData);
243 });
244 info.append(dnsData);
245 }
246 } // namespace OHOS::nmd
247