1 /*
2 * Copyright (c) 2022-2024 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 <arpa/inet.h>
17
18 #include "dns_config_client.h"
19 #include "dns_param_cache.h"
20 #include "init_socket.h"
21 #include "net_conn_client.h"
22 #include "net_handle.h"
23 #include "netsys_client.h"
24 #ifdef USE_SELINUX
25 #include "selinux/selinux.h"
26 #endif
27
28 #include "dns_quality_diag.h"
29 #include "dns_resolv_listen.h"
30 #include "epoller.h"
31 #include "fwmark_client.h"
32 #include "parameters.h"
33
34 namespace OHOS::nmd {
35 static constexpr const uint32_t MAX_LISTEN_NUM = 1024;
36 const std::string PUBLIC_DNS_SERVER = "persist.sys.netsysnative_dns_servers_backup";
37 using namespace NetManagerStandard;
38
39 class DnsResolvListenInternal {
40 public:
41 DnsResolvListenInternal() = default;
~DnsResolvListenInternal()42 ~DnsResolvListenInternal()
43 {
44 if (serverSockFd_ > 0) {
45 close(serverSockFd_);
46 }
47 }
48
49 void StartListen();
50
51 private:
52 static void ProcGetConfigCommand(int clientSockFd, uint16_t netId, uint32_t uid);
53 #ifdef FEATURE_NET_FIREWALL_ENABLE
54 static void ProcSetCacheCommand(const std::string &name, uint16_t netId, uint32_t callingUid,
55 AddrInfo addrInfo[MAX_RESULTS], uint32_t resNum);
56 static void ProcGetCacheCommand(const std::string &name, int clientSockFd, uint16_t netId, uint32_t callingUid);
57 #endif
58 static void ProcSetCacheCommand(const std::string &name, uint16_t netId, AddrInfo addrInfo[MAX_RESULTS],
59 uint32_t resNum);
60 static void ProcGetCacheCommand(const std::string &name, int clientSockFd, uint16_t netId);
61 static void ProcJudgeIpv6Command(int clientSockFd, uint16_t netId);
62 static void ProcGetDefaultNetworkCommand(int clientSockFd);
63 static void ProcBindSocketCommand(int32_t remoteFd, uint16_t netId);
64 static void AddPublicDnsServers(ResolvConfig &sendData, size_t serverSize);
65 static bool IsUserDefinedServer(uint16_t netId, uint32_t uid);
66
67 ReceiverRunner ProcCommand();
68 ReceiverRunner ProcBindSocket(uint32_t netId);
69 ReceiverRunner ProcGetKeyLengthForCache(CommandType command, uint16_t netId, uint32_t uid);
70 ReceiverRunner ProcGetKeyForCache(CommandType command, uint16_t netId, uint32_t uid);
71 ReceiverRunner ProcGetCacheSize(const std::string &name, uint16_t netId, uint32_t uid);
72 ReceiverRunner ProcGetCacheContent(const std::string &name, uint16_t netId, uint32_t uid, uint32_t resNum);
73 ReceiverRunner ProcPostDnsThreadResult(uint16_t netId);
74 ReceiverRunner ProcGetKeyLengthForCache(uint16_t netId, uint32_t uid, uint32_t pid);
75 ReceiverRunner ProcGetKeyForCache(uint16_t netId, uint32_t uid, uint32_t pid);
76 ReceiverRunner ProcGetPostParam(const std::string &name, uint16_t netId, uint32_t uid, uint32_t pid);
77 struct PostParam {
78 uint32_t usedTime = 0;
79 int32_t queryRet = 0;
80 uint32_t aiSize = 0;
81 QueryParam param{};
82 };
83 ReceiverRunner ProcPostDnsResult(const std::string &name, uint16_t netId, uint32_t uid, uint32_t pid,
84 const PostParam ¶m);
85
86 int32_t serverSockFd_ = -1;
87 std::shared_ptr<EpollServer> server_;
88 };
89
AddPublicDnsServers(ResolvConfig & sendData,size_t serverSize)90 void DnsResolvListenInternal::AddPublicDnsServers(ResolvConfig &sendData, size_t serverSize)
91 {
92 std::string publicDnsServer = OHOS::system::GetParameter(PUBLIC_DNS_SERVER, "");
93 size_t i = 0;
94 for (; i < serverSize; i++) {
95 if (strcmp(sendData.nameservers[i], publicDnsServer.c_str()) == 0) {
96 return;
97 }
98 }
99 if (i >= MAX_SERVER_NUM) {
100 NETNATIVE_LOGI("Invalid serverSize or mPublicDns already exists");
101 return;
102 }
103 if (memcpy_s(sendData.nameservers[i], sizeof(sendData.nameservers[i]), publicDnsServer.c_str(),
104 publicDnsServer.length() + 1) != ERR_OK) {
105 DNS_CONFIG_PRINT("mem copy failed");
106 return;
107 }
108 DNS_CONFIG_PRINT("i = %{public}d sendData.nameservers: %{public}s", i, sendData.nameservers[i]);
109 }
110
ProcGetConfigCommand(int clientSockFd,uint16_t netId,uint32_t uid)111 void DnsResolvListenInternal::ProcGetConfigCommand(int clientSockFd, uint16_t netId, uint32_t uid)
112 {
113 NETNATIVE_LOG_D("DnsResolvListenInternal::ProcGetConfigCommand uid = [%{public}u]", uid);
114 ResolvConfig sendData = {0};
115 std::vector<std::string> servers;
116 std::vector<std::string> domains;
117 uint16_t baseTimeoutMsec = DEFAULT_TIMEOUT;
118 uint8_t retryCount = DEFAULT_RETRY;
119 bool isUserDefinedDnsServer = false;
120
121 #ifdef FEATURE_NET_FIREWALL_ENABLE
122 DnsParamCache::GetInstance().SetCallingUid(uid);
123 #endif
124
125 int status;
126 if (DnsParamCache::GetInstance().IsVpnOpen() && netId == 0) {
127 status = DnsParamCache::GetInstance().GetResolverConfig(static_cast<uint16_t>(netId), uid, servers, domains,
128 baseTimeoutMsec, retryCount);
129 } else {
130 status = DnsParamCache::GetInstance().GetResolverConfig(static_cast<uint16_t>(netId), servers, domains,
131 baseTimeoutMsec, retryCount);
132 }
133 DNS_CONFIG_PRINT("GetResolverConfig status: %{public}d", status);
134 if (status < 0) {
135 sendData.error = status;
136 } else {
137 sendData.retryCount = retryCount;
138 sendData.timeoutMs = baseTimeoutMsec;
139 size_t i = 0;
140 for (; i < std::min<size_t>(MAX_SERVER_NUM - 1, servers.size()); i++) {
141 if (memcpy_s(sendData.nameservers[i], sizeof(sendData.nameservers[i]), servers[i].c_str(),
142 servers[i].length()) < 0) {
143 DNS_CONFIG_PRINT("mem copy failed");
144 continue;
145 }
146 DNS_CONFIG_PRINT("i = %{public}d sendData.nameservers: %{public}s", i, sendData.nameservers[i]);
147 }
148 sendData.nonPublicNum = i;
149 // the last one is for baidu DNS Server
150 #ifdef ENABLE_PUBLIC_DNS_SERVER
151 if (!IsUserDefinedServer(static_cast<uint16_t>(netId), uid)) {
152 AddPublicDnsServers(sendData, i);
153 }
154 #endif
155 }
156 if (!PollSendData(clientSockFd, reinterpret_cast<char *>(&sendData), sizeof(ResolvConfig))) {
157 DNS_CONFIG_PRINT("send failed");
158 }
159 DNS_CONFIG_PRINT("ProcGetConfigCommand end");
160 }
161
ProcGetCacheCommand(const std::string & name,int clientSockFd,uint16_t netId)162 void DnsResolvListenInternal::ProcGetCacheCommand(const std::string &name, int clientSockFd, uint16_t netId)
163 {
164 #ifdef FEATURE_NET_FIREWALL_ENABLE
165 ProcGetCacheCommand(name, clientSockFd, netId, 0);
166 }
167
ProcGetCacheCommand(const std::string & name,int clientSockFd,uint16_t netId,uint32_t callingUid)168 void DnsResolvListenInternal::ProcGetCacheCommand(const std::string &name, int clientSockFd, uint16_t netId,
169 uint32_t callingUid)
170 {
171 DnsParamCache::GetInstance().SetCallingUid(callingUid);
172 #endif
173 auto cacheRes = DnsParamCache::GetInstance().GetDnsCache(netId, name);
174
175 uint32_t resNum = std::min<uint32_t>(MAX_RESULTS, static_cast<uint32_t>(cacheRes.size()));
176 if (!PollSendData(clientSockFd, reinterpret_cast<char *>(&resNum), sizeof(resNum))) {
177 DNS_CONFIG_PRINT("send errno %{public}d", errno);
178 return;
179 }
180
181 if (resNum == 0 || resNum > MAX_RESULTS) {
182 return;
183 }
184
185 AddrInfo addrInfo[MAX_RESULTS] = {};
186 for (uint32_t i = 0; i < resNum; i++) {
187 if (memcpy_s(reinterpret_cast<char *>(&addrInfo[i]), sizeof(AddrInfo), reinterpret_cast<char *>(&cacheRes[i]),
188 sizeof(AddrInfo)) != 0) {
189 return;
190 }
191 }
192 if (!PollSendData(clientSockFd, reinterpret_cast<char *>(addrInfo), sizeof(AddrInfo) * resNum)) {
193 DNS_CONFIG_PRINT("send errno %{public}d", errno);
194 return;
195 }
196 DNS_CONFIG_PRINT("ProcGetCacheCommand end");
197 }
198
ProcSetCacheCommand(const std::string & name,uint16_t netId,AddrInfo addrInfo[MAX_RESULTS],uint32_t resNum)199 void DnsResolvListenInternal::ProcSetCacheCommand(const std::string &name, uint16_t netId,
200 AddrInfo addrInfo[MAX_RESULTS], uint32_t resNum)
201 {
202 #ifdef FEATURE_NET_FIREWALL_ENABLE
203 ProcSetCacheCommand(name, netId, 0, addrInfo, resNum);
204 }
205
ProcSetCacheCommand(const std::string & name,uint16_t netId,uint32_t callingUid,AddrInfo addrInfo[MAX_RESULTS],uint32_t resNum)206 void DnsResolvListenInternal::ProcSetCacheCommand(const std::string &name, uint16_t netId, uint32_t callingUid,
207 AddrInfo addrInfo[MAX_RESULTS], uint32_t resNum)
208 {
209 #endif
210 #ifdef FEATURE_NET_FIREWALL_ENABLE
211 DnsParamCache::GetInstance().SetCallingUid(callingUid);
212 #endif
213 for (size_t i = 0; i < resNum; ++i) {
214 DnsParamCache::GetInstance().SetDnsCache(netId, name, addrInfo[i]);
215 }
216 DnsParamCache::GetInstance().SetCacheDelayed(netId, name);
217 DNS_CONFIG_PRINT("ProcSetCacheCommand end");
218 }
219
ProcJudgeIpv6Command(int clientSockFd,uint16_t netId)220 void DnsResolvListenInternal::ProcJudgeIpv6Command(int clientSockFd, uint16_t netId)
221 {
222 int enable = DnsParamCache::GetInstance().IsIpv6Enable(netId) ? 1 : 0;
223 if (!PollSendData(clientSockFd, reinterpret_cast<char *>(&enable), sizeof(int))) {
224 DNS_CONFIG_PRINT("send failed");
225 }
226 }
227
ProcGetDefaultNetworkCommand(int clientSockFd)228 void DnsResolvListenInternal::ProcGetDefaultNetworkCommand(int clientSockFd)
229 {
230 NetHandle netHandle;
231 NetConnClient::GetInstance().GetDefaultNet(netHandle);
232 int netId = netHandle.GetNetId();
233 NETNATIVE_LOGE("ProcGetDefaultNetworkCommand %{public}d", netId);
234 if (!PollSendData(clientSockFd, reinterpret_cast<char *>(&netId), sizeof(int))) {
235 NETNATIVE_LOGE("send failed");
236 }
237 }
238
ProcBindSocketCommand(int32_t remoteFd,uint16_t netId)239 void DnsResolvListenInternal::ProcBindSocketCommand(int32_t remoteFd, uint16_t netId)
240 {
241 NETNATIVE_LOGE("ProcGetDefaultNetworkCommand %{public}d, %{public}d", netId, remoteFd);
242 if (OHOS::nmd::FwmarkClient().BindSocket(remoteFd, netId) != NETMANAGER_SUCCESS) {
243 NETNATIVE_LOGE("BindSocket to netid failed");
244 }
245 }
246
StartListen()247 void DnsResolvListenInternal::StartListen()
248 {
249 NETNATIVE_LOGE("Enter StartListen");
250
251 serverSockFd_ = GetControlSocket(DNS_SOCKET_NAME);
252 if (serverSockFd_ < 0) {
253 NETNATIVE_LOGE("create socket failed %{public}d", errno);
254 return;
255 }
256
257 // listen
258 if (listen(serverSockFd_, MAX_LISTEN_NUM) < 0) {
259 NETNATIVE_LOGE("listen errno %{public}d", errno);
260 close(serverSockFd_);
261 serverSockFd_ = -1;
262 return;
263 }
264
265 if (!MakeNonBlock(serverSockFd_)) {
266 close(serverSockFd_);
267 serverSockFd_ = -1;
268 return;
269 }
270 NETNATIVE_LOGE("begin listen");
271 server_ = std::make_shared<EpollServer>(serverSockFd_, sizeof(RequestInfo), ProcCommand());
272 server_->Run();
273 }
274
ProcCommand()275 ReceiverRunner DnsResolvListenInternal::ProcCommand()
276 {
277 // single thread, captrue <this> is safe
278 return [this](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
279 if (server_ == nullptr) {
280 return FixedLengthReceiverState::ONERROR;
281 }
282 if (data.size() < sizeof(RequestInfo)) {
283 return FixedLengthReceiverState::ONERROR;
284 }
285
286 RequestInfo requestInfo{};
287 if (memcpy_s(&requestInfo, sizeof(RequestInfo), data.data(), sizeof(RequestInfo)) != EOK) {
288 return FixedLengthReceiverState::ONERROR;
289 }
290
291 auto info = &requestInfo;
292 auto netId = info->netId;
293 auto uid = info->uid;
294
295 switch (info->command) {
296 case GET_CONFIG:
297 ProcGetConfigCommand(fd, netId, uid);
298 return FixedLengthReceiverState::DATA_ENOUGH;
299 case GET_CACHE:
300 case SET_CACHE:
301 if (server_) {
302 server_->AddReceiver(fd, sizeof(uint32_t),
303 ProcGetKeyLengthForCache(static_cast<CommandType>(info->command),
304 static_cast<uint16_t>(info->netId), info->uid));
305 }
306 return FixedLengthReceiverState::CONTINUE;
307 case POST_DNS_RESULT:
308 server_->AddReceiver(fd, sizeof(uint32_t) + sizeof(uint32_t),
309 ProcPostDnsThreadResult(static_cast<uint16_t>(info->netId)));
310 return FixedLengthReceiverState::CONTINUE;
311 case JUDGE_IPV6:
312 ProcJudgeIpv6Command(fd, netId);
313 return FixedLengthReceiverState::DATA_ENOUGH;
314 case GET_DEFAULT_NETWORK:
315 ProcGetDefaultNetworkCommand(fd);
316 return FixedLengthReceiverState::DATA_ENOUGH;
317 case BIND_SOCKET:
318 server_->AddReceiver(fd, sizeof(int32_t), ProcBindSocket(netId));
319 return FixedLengthReceiverState::CONTINUE;
320 default:
321 return FixedLengthReceiverState::ONERROR;
322 }
323 };
324 }
325
ProcBindSocket(uint32_t netId)326 ReceiverRunner DnsResolvListenInternal::ProcBindSocket(uint32_t netId)
327 {
328 return [this, netId](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
329 // fd is AF_UNIX fd
330 // remoteFd is the TCP/UDP socket which is from app process
331 if (server_ == nullptr) {
332 return FixedLengthReceiverState::ONERROR;
333 }
334 if (data.size() < sizeof(int32_t)) {
335 return FixedLengthReceiverState::ONERROR;
336 }
337
338 int32_t remoteFd;
339 if (memcpy_s(&remoteFd, sizeof(int32_t), data.data(), sizeof(int32_t)) != EOK) {
340 return FixedLengthReceiverState::ONERROR;
341 }
342 ProcBindSocketCommand(remoteFd, netId);
343 return FixedLengthReceiverState::DATA_ENOUGH;
344 };
345 }
346
ProcGetKeyLengthForCache(CommandType command,uint16_t netId,uint32_t uid)347 ReceiverRunner DnsResolvListenInternal::ProcGetKeyLengthForCache(CommandType command, uint16_t netId, uint32_t uid)
348 {
349 return [this, command, netId, uid](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
350 if (server_ == nullptr) {
351 return FixedLengthReceiverState::ONERROR;
352 }
353 if (data.size() < sizeof(uint32_t)) {
354 return FixedLengthReceiverState::ONERROR;
355 }
356
357 uint32_t nameLen;
358 if (memcpy_s(&nameLen, sizeof(uint32_t), data.data(), sizeof(uint32_t)) != EOK) {
359 return FixedLengthReceiverState::ONERROR;
360 }
361 if (nameLen > MAX_HOST_NAME_LEN) {
362 return FixedLengthReceiverState::ONERROR;
363 }
364 server_->AddReceiver(fd, nameLen, ProcGetKeyForCache(command, netId, uid));
365 return FixedLengthReceiverState::CONTINUE;
366 };
367 }
368
ProcGetKeyForCache(CommandType command,uint16_t netId,uint32_t uid)369 ReceiverRunner DnsResolvListenInternal::ProcGetKeyForCache(CommandType command, uint16_t netId, uint32_t uid)
370 {
371 return [this, command, netId, uid](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
372 if (server_ == nullptr) {
373 return FixedLengthReceiverState::ONERROR;
374 }
375 if (data.empty()) {
376 return FixedLengthReceiverState::ONERROR;
377 }
378
379 switch (command) {
380 case SET_CACHE:
381 server_->AddReceiver(fd, sizeof(uint32_t), ProcGetCacheSize(data, netId, uid));
382 return FixedLengthReceiverState::CONTINUE;
383 case GET_CACHE:
384 #ifdef FEATURE_NET_FIREWALL_ENABLE
385 ProcGetCacheCommand(data, fd, netId, uid);
386 #else
387 ProcGetCacheCommand(data, fd, netId);
388 #endif
389 return FixedLengthReceiverState::DATA_ENOUGH;
390 default:
391 return FixedLengthReceiverState::ONERROR;
392 }
393 };
394 }
395
ProcGetCacheSize(const std::string & name,uint16_t netId,uint32_t uid)396 ReceiverRunner DnsResolvListenInternal::ProcGetCacheSize(const std::string &name, uint16_t netId, uint32_t uid)
397 {
398 return [this, name, netId, uid](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
399 if (server_ == nullptr) {
400 return FixedLengthReceiverState::ONERROR;
401 }
402 if (data.size() < sizeof(uint32_t)) {
403 return FixedLengthReceiverState::ONERROR;
404 }
405
406 uint32_t resNum;
407 if (memcpy_s(&resNum, sizeof(uint32_t), data.data(), sizeof(uint32_t)) != EOK) {
408 return FixedLengthReceiverState::ONERROR;
409 }
410 resNum = std::min<uint32_t>(MAX_RESULTS, resNum);
411 if (resNum == 0) {
412 return FixedLengthReceiverState::ONERROR;
413 }
414 server_->AddReceiver(fd, sizeof(AddrInfo) * resNum, ProcGetCacheContent(name, netId, uid, resNum));
415 return FixedLengthReceiverState::CONTINUE;
416 };
417 }
418
ProcGetCacheContent(const std::string & name,uint16_t netId,uint32_t uid,uint32_t resNum)419 ReceiverRunner DnsResolvListenInternal::ProcGetCacheContent(const std::string &name, uint16_t netId, uint32_t uid,
420 uint32_t resNum)
421 {
422 return [this, name, netId, uid, resNum](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
423 if (server_ == nullptr) {
424 return FixedLengthReceiverState::ONERROR;
425 }
426 if (data.size() < sizeof(AddrInfo) * resNum) {
427 return FixedLengthReceiverState::ONERROR;
428 }
429
430 auto size = std::min<uint32_t>(MAX_RESULTS, resNum);
431 AddrInfo addrInfo[MAX_RESULTS]{};
432 if (memcpy_s(addrInfo, sizeof(AddrInfo) * MAX_RESULTS, data.data(), sizeof(AddrInfo) * size) != EOK) {
433 return FixedLengthReceiverState::ONERROR;
434 }
435 #ifdef FEATURE_NET_FIREWALL_ENABLE
436 ProcSetCacheCommand(name, netId, uid, addrInfo, size);
437 #else
438 ProcSetCacheCommand(name, netId, addrInfo, size);
439 #endif
440 return FixedLengthReceiverState::DATA_ENOUGH;
441 };
442 }
443
ProcPostDnsThreadResult(uint16_t netId)444 ReceiverRunner DnsResolvListenInternal::ProcPostDnsThreadResult(uint16_t netId)
445 {
446 return [this, netId](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
447 if (server_ == nullptr) {
448 return FixedLengthReceiverState::ONERROR;
449 }
450 if (data.size() < sizeof(uint32_t) + sizeof(uint32_t)) {
451 return FixedLengthReceiverState::ONERROR;
452 }
453
454 uint32_t uid;
455 uint32_t pid;
456 if (memcpy_s(&uid, sizeof(uint32_t), data.data(), sizeof(uint32_t)) != EOK) {
457 return FixedLengthReceiverState::ONERROR;
458 }
459 if (memcpy_s(&pid, sizeof(uint32_t), data.data() + sizeof(uint32_t), sizeof(uint32_t)) != EOK) {
460 return FixedLengthReceiverState::ONERROR;
461 }
462 server_->AddReceiver(fd, sizeof(uint32_t), ProcGetKeyLengthForCache(netId, uid, pid));
463 return FixedLengthReceiverState::CONTINUE;
464 };
465 }
466
ProcGetKeyLengthForCache(uint16_t netId,uint32_t uid,uint32_t pid)467 ReceiverRunner DnsResolvListenInternal::ProcGetKeyLengthForCache(uint16_t netId, uint32_t uid, uint32_t pid)
468 {
469 return [this, netId, uid, pid](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
470 if (server_ == nullptr) {
471 return FixedLengthReceiverState::ONERROR;
472 }
473 if (data.size() < sizeof(uint32_t)) {
474 return FixedLengthReceiverState::ONERROR;
475 }
476 uint32_t nameLen;
477 if (memcpy_s(&nameLen, sizeof(uint32_t), data.data(), sizeof(uint32_t)) != EOK) {
478 return FixedLengthReceiverState::ONERROR;
479 }
480 if (nameLen > MAX_HOST_NAME_LEN) {
481 return FixedLengthReceiverState::ONERROR;
482 }
483 server_->AddReceiver(fd, nameLen, ProcGetKeyForCache(netId, uid, pid));
484 return FixedLengthReceiverState::CONTINUE;
485 };
486 }
487
ProcGetKeyForCache(uint16_t netId,uint32_t uid,uint32_t pid)488 ReceiverRunner DnsResolvListenInternal::ProcGetKeyForCache(uint16_t netId, uint32_t uid, uint32_t pid)
489 {
490 return [this, netId, uid, pid](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
491 if (server_ == nullptr) {
492 return FixedLengthReceiverState::ONERROR;
493 }
494 if (data.empty()) {
495 return FixedLengthReceiverState::ONERROR;
496 }
497
498 server_->AddReceiver(fd, sizeof(uint32_t) + sizeof(int32_t) + sizeof(uint32_t) + sizeof(QueryParam),
499 ProcGetPostParam(data, netId, uid, pid));
500 return FixedLengthReceiverState::CONTINUE;
501 };
502 }
503
ProcGetPostParam(const std::string & name,uint16_t netId,uint32_t uid,uint32_t pid)504 ReceiverRunner DnsResolvListenInternal::ProcGetPostParam(const std::string &name, uint16_t netId, uint32_t uid,
505 uint32_t pid)
506 {
507 return [this, name, netId, uid, pid](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
508 if (server_ == nullptr) {
509 return FixedLengthReceiverState::ONERROR;
510 }
511 if (data.size() < sizeof(uint32_t) + sizeof(int32_t) + sizeof(uint32_t) + sizeof(QueryParam)) {
512 return FixedLengthReceiverState::ONERROR;
513 }
514
515 PostParam param{};
516 if (memcpy_s(¶m.usedTime, sizeof(uint32_t), data.data(), sizeof(uint32_t)) != EOK) {
517 return FixedLengthReceiverState::ONERROR;
518 }
519 if (memcpy_s(¶m.queryRet, sizeof(int32_t), data.data() + sizeof(uint32_t), sizeof(int32_t)) != EOK) {
520 return FixedLengthReceiverState::ONERROR;
521 }
522 if (memcpy_s(¶m.aiSize, sizeof(uint32_t), data.data() + sizeof(uint32_t) + sizeof(int32_t),
523 sizeof(uint32_t)) != EOK) {
524 return FixedLengthReceiverState::ONERROR;
525 }
526 if (memcpy_s(¶m.param, sizeof(QueryParam),
527 data.data() + sizeof(uint32_t) + sizeof(int32_t) + sizeof(uint32_t), sizeof(QueryParam)) != EOK) {
528 return FixedLengthReceiverState::ONERROR;
529 }
530
531 if (param.queryRet == 0 && param.aiSize > 0) {
532 auto size = std::min<uint32_t>(MAX_RESULTS, param.aiSize);
533 param.aiSize = size;
534 server_->AddReceiver(fd, sizeof(AddrInfo) * size, ProcPostDnsResult(name, netId, uid, pid, param));
535 return FixedLengthReceiverState::CONTINUE;
536 } else {
537 DnsQualityDiag::GetInstance().ReportDnsResult(netId, uid, pid, static_cast<int32_t>(param.usedTime),
538 const_cast<char *>(name.c_str()), 0, param.queryRet,
539 param.param, nullptr);
540 return FixedLengthReceiverState::DATA_ENOUGH;
541 }
542 };
543 }
544
ProcPostDnsResult(const std::string & name,uint16_t netId,uint32_t uid,uint32_t pid,const PostParam & param)545 ReceiverRunner DnsResolvListenInternal::ProcPostDnsResult(const std::string &name, uint16_t netId, uint32_t uid,
546 uint32_t pid, const PostParam ¶m)
547 {
548 return
549 [this, name, netId, uid, pid, param](FileDescriptor fd, const std::string &data) -> FixedLengthReceiverState {
550 if (server_ == nullptr) {
551 return FixedLengthReceiverState::ONERROR;
552 }
553 if (data.size() < sizeof(AddrInfo) * param.aiSize) {
554 return FixedLengthReceiverState::ONERROR;
555 }
556 auto size = std::min<uint32_t>(MAX_RESULTS, param.aiSize);
557 AddrInfo addrInfo[MAX_RESULTS]{};
558 if (memcpy_s(addrInfo, sizeof(AddrInfo) * MAX_RESULTS, data.data(), sizeof(AddrInfo) * size) != EOK) {
559 return FixedLengthReceiverState::ONERROR;
560 }
561 DnsQualityDiag::GetInstance().ReportDnsResult(netId, uid, pid, static_cast<int32_t>(param.usedTime),
562 const_cast<char *>(name.c_str()), size, param.queryRet,
563 param.param, addrInfo);
564 return FixedLengthReceiverState::DATA_ENOUGH;
565 };
566 }
567
StartListen()568 void DnsResolvListen::StartListen()
569 {
570 (void)this;
571 DnsResolvListenInternal dnsResolvListenInternal;
572 dnsResolvListenInternal.StartListen();
573 }
574
IsUserDefinedServer(uint16_t netId,uint32_t uid)575 bool DnsResolvListenInternal::IsUserDefinedServer(uint16_t netId, uint32_t uid)
576 {
577 int status = 0;
578 bool isUserDefinedDnsServer = false;
579 if (DnsParamCache::GetInstance().IsVpnOpen() && netId == 0) {
580 status = DnsParamCache::GetInstance().GetUserDefinedServerFlag(static_cast<uint16_t>(netId),
581 isUserDefinedDnsServer, uid);
582 } else {
583 status = DnsParamCache::GetInstance().GetUserDefinedServerFlag(static_cast<uint16_t>(netId),
584 isUserDefinedDnsServer);
585 }
586 if (status < 0) {
587 isUserDefinedDnsServer = false;
588 }
589 return isUserDefinedDnsServer;
590 }
591 } // namespace OHOS::nmd
592