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
SelectNameservers(const std::vector<std::string> & servers)37 std::vector<std::string> DnsParamCache::SelectNameservers(const std::vector<std::string> &servers)
38 {
39 std::vector<std::string> res = servers;
40 if (res.size() > MAX_SERVER_NUM) {
41 res.resize(MAX_SERVER_NUM);
42 }
43 return res;
44 }
45
CreateCacheForNet(uint16_t netId)46 int32_t DnsParamCache::CreateCacheForNet(uint16_t netId)
47 {
48 NETNATIVE_LOG_D("DnsParamCache::CreateCacheForNet, netid:%{public}d,", netId);
49 std::lock_guard<std::mutex> guard(cacheMutex_);
50 if (serverConfigMap_.find(netId) != serverConfigMap_.end()) {
51 NETNATIVE_LOGE("DnsParamCache::CreateCacheForNet, netid already exist, no need to create");
52 return -EEXIST;
53 }
54 serverConfigMap_[netId].SetNetId(netId);
55 return 0;
56 }
57
DestroyNetworkCache(uint16_t netId)58 int32_t DnsParamCache::DestroyNetworkCache(uint16_t netId)
59 {
60 NETNATIVE_LOG_D("DnsParamCache::CreateCacheForNet, netid:%{public}d,", netId);
61 std::lock_guard<std::mutex> guard(cacheMutex_);
62 if (serverConfigMap_.erase(netId)) {
63 return 0;
64 } else {
65 return -EEXIST;
66 }
67 }
68
SetResolverConfig(uint16_t netId,uint16_t baseTimeoutMsec,uint8_t retryCount,const std::vector<std::string> & servers,const std::vector<std::string> & domains)69 int32_t DnsParamCache::SetResolverConfig(uint16_t netId, uint16_t baseTimeoutMsec, uint8_t retryCount,
70 const std::vector<std::string> &servers,
71 const std::vector<std::string> &domains)
72 {
73 std::vector<std::string> nameservers = SelectNameservers(servers);
74 NETNATIVE_LOG_D("DnsParamCache::SetResolverConfig, netid:%{public}d, numServers:%{public}d,", netId,
75 static_cast<int>(nameservers.size()));
76
77 std::lock_guard<std::mutex> guard(cacheMutex_);
78
79 // select_domains
80 if (serverConfigMap_.find(netId) == serverConfigMap_.end()) {
81 NETNATIVE_LOGE("DnsParamCache::SetResolverConfig failed, netid is non-existent");
82 return -ENOENT;
83 }
84
85 auto oldDnsServers = serverConfigMap_[netId].GetServers();
86 std::sort(oldDnsServers.begin(), oldDnsServers.end());
87
88 auto newDnsServers = servers;
89 std::sort(newDnsServers.begin(), newDnsServers.end());
90
91 if (oldDnsServers != newDnsServers) {
92 serverConfigMap_[netId].GetCache().Clear();
93 }
94
95 serverConfigMap_[netId].SetNetId(netId);
96 serverConfigMap_[netId].SetServers(servers);
97 serverConfigMap_[netId].SetDomains(domains);
98 if (retryCount == 0) {
99 serverConfigMap_[netId].SetRetryCount(RES_DEFAULT_RETRY);
100 } else {
101 serverConfigMap_[netId].SetRetryCount(retryCount);
102 }
103 if (baseTimeoutMsec == 0) {
104 serverConfigMap_[netId].SetTimeoutMsec(RES_TIMEOUT);
105 } else {
106 serverConfigMap_[netId].SetTimeoutMsec(baseTimeoutMsec);
107 }
108 return 0;
109 }
110
SetDefaultNetwork(uint16_t netId)111 void DnsParamCache::SetDefaultNetwork(uint16_t netId)
112 {
113 defaultNetId_ = netId;
114 }
115
GetResolverConfig(uint16_t netId,std::vector<std::string> & servers,std::vector<std::string> & domains,uint16_t & baseTimeoutMsec,uint8_t & retryCount)116 int32_t DnsParamCache::GetResolverConfig(uint16_t netId, std::vector<std::string> &servers,
117 std::vector<std::string> &domains, uint16_t &baseTimeoutMsec,
118 uint8_t &retryCount)
119 {
120 if (netId == 0) {
121 netId = defaultNetId_;
122 }
123
124 std::lock_guard<std::mutex> guard(cacheMutex_);
125 if (serverConfigMap_.find(netId) == serverConfigMap_.end()) {
126 DNS_CONFIG_PRINT("get Config failed: netid is not have netid:%{public}d,", netId);
127 return -ENOENT;
128 }
129
130 servers = serverConfigMap_[netId].GetServers();
131 domains = serverConfigMap_[netId].GetDomains();
132 baseTimeoutMsec = serverConfigMap_[netId].GetTimeoutMsec();
133 retryCount = serverConfigMap_[netId].GetRetryCount();
134
135 return 0;
136 }
137
GetDefaultNetwork() const138 int32_t DnsParamCache::GetDefaultNetwork() const
139 {
140 return defaultNetId_;
141 }
142
SetDnsCache(uint16_t netId,const std::string & hostName,const AddrInfo & addrInfo)143 void DnsParamCache::SetDnsCache(uint16_t netId, const std::string &hostName, const AddrInfo &addrInfo)
144 {
145 if (netId == 0) {
146 netId = defaultNetId_;
147 }
148 std::lock_guard<std::mutex> guard(cacheMutex_);
149 if (serverConfigMap_.find(netId) == serverConfigMap_.end()) {
150 DNS_CONFIG_PRINT("SetDnsCache failed: netid is not have netid:%{public}d,", netId);
151 return;
152 }
153
154 serverConfigMap_[netId].GetCache().Put(hostName, addrInfo);
155 }
156
GetDnsCache(uint16_t netId,const std::string & hostName)157 std::vector<AddrInfo> DnsParamCache::GetDnsCache(uint16_t netId, const std::string &hostName)
158 {
159 if (netId == 0) {
160 netId = defaultNetId_;
161 }
162
163 std::lock_guard<std::mutex> guard(cacheMutex_);
164 if (serverConfigMap_.find(netId) == serverConfigMap_.end()) {
165 DNS_CONFIG_PRINT("GetDnsCache failed: netid is not have netid:%{public}d,", netId);
166 return {};
167 }
168
169 return serverConfigMap_[netId].GetCache().Get(hostName);
170 }
171
SetCacheDelayed(uint16_t netId,const std::string & hostName)172 void DnsParamCache::SetCacheDelayed(uint16_t netId, const std::string &hostName)
173 {
174 if (netId == 0) {
175 netId = defaultNetId_;
176 }
177
178 std::lock_guard<std::mutex> guard(cacheMutex_);
179 if (serverConfigMap_.find(netId) == serverConfigMap_.end()) {
180 DNS_CONFIG_PRINT("SetCacheDelayed failed: netid is not have netid:%{public}d,", netId);
181 return;
182 }
183
184 serverConfigMap_[netId].SetCacheDelayed(hostName);
185 }
186
GetDumpInfo(std::string & info)187 void DnsParamCache::GetDumpInfo(std::string &info)
188 {
189 std::string dnsData;
190 static const std::string TAB = " ";
191 std::for_each(serverConfigMap_.begin(), serverConfigMap_.end(), [&dnsData](const auto &serverConfig) {
192 dnsData.append(TAB + "NetId: " + std::to_string(serverConfig.second.GetNetId()) + "\n");
193 dnsData.append(TAB + "TimeoutMsec: " + std::to_string(serverConfig.second.GetTimeoutMsec()) + "\n");
194 dnsData.append(TAB + "RetryCount: " + std::to_string(serverConfig.second.GetRetryCount()) + "\n");
195 dnsData.append(TAB + "Servers:");
196 GetVectorData(serverConfig.second.GetServers(), dnsData);
197 dnsData.append(TAB + "Domains:");
198 GetVectorData(serverConfig.second.GetDomains(), dnsData);
199 });
200 info.append(dnsData);
201 }
202 } // namespace OHOS::nmd
203