• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param);
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(&param.usedTime, sizeof(uint32_t), data.data(), sizeof(uint32_t)) != EOK) {
517             return FixedLengthReceiverState::ONERROR;
518         }
519         if (memcpy_s(&param.queryRet, sizeof(int32_t), data.data() + sizeof(uint32_t), sizeof(int32_t)) != EOK) {
520             return FixedLengthReceiverState::ONERROR;
521         }
522         if (memcpy_s(&param.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(&param.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 &param)
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