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 #ifndef INCLUDE_DNS_PROXY_LISTEN_H
17 #define INCLUDE_DNS_PROXY_LISTEN_H
18 
19 #include <iostream>
20 #include <mutex>
21 #include <netinet/in.h>
22 #include <vector>
23 #include <map>
24 #include <sys/eventfd.h>
25 
26 #include "dns_proxy_request_socket.h"
27 
28 namespace OHOS {
29 namespace nmd {
30 class DnsProxyListen {
31 public:
32     DnsProxyListen();
33     ~DnsProxyListen();
34 
35     /**
36      * Begin dns proxy listen
37      *
38      */
39     void OnListen();
40 
41     /**
42      * Close dns proxy listen
43      */
44     void OffListen();
45 
46     /**
47      * Dns proxy listen obj
48      *
49      */
50     void StartListen();
51 
52     /**
53      * Set the Parse Net Id objectse
54      *
55      * @param netId network ID
56      */
57     void SetParseNetId(uint16_t netId);
58 
59     using DnsSocketHolderBase = std::map<int32_t, DnsProxyRequestSocket>;
60 
61 private:
62 class DnsSocketHolder : private DnsSocketHolderBase {
63 public:
find(const int32_t & x)64     auto find(const int32_t& x) { return DnsSocketHolderBase::find(x); }
begin()65     auto begin() { return DnsSocketHolderBase::begin(); }
end()66     auto end() { return DnsSocketHolderBase::end(); }
cbegin()67     auto cbegin() { return DnsSocketHolderBase::cbegin(); }
cend()68     auto cend() { return DnsSocketHolderBase::cend(); }
clear()69     auto clear() { return DnsSocketHolderBase::clear(); }
size()70     auto size() { return DnsSocketHolderBase::size(); }
empty()71     auto empty() { return DnsSocketHolderBase::empty(); }
72     template<typename... Args>
73     auto emplace(Args&&... args) -> decltype(DnsSocketHolderBase::emplace(std::forward<Args>(args)...));
74     auto erase(iterator position) -> decltype(DnsSocketHolderBase::erase(position));
75 private:
76     constexpr static uint32_t MAX_SOCKET_CAPACITY = 300;
77     std::list<iterator> lruCache;
78 };
79 
80 private:
81     void DnsParseBySocket(std::unique_ptr<RecvBuff> &recvBuff, std::unique_ptr<AlignedSockAddr> &clientSock);
82     static void DnsSendRecvParseData(int32_t clientSocket, char *requestData, int32_t resLen,
83                                      AlignedSockAddr &proxyAddr);
84     static bool CheckDnsResponse(char *recBuff, size_t recLen);
85     static bool CheckDnsQuestion(char *recBuff, size_t recLen);
86     void SendDnsBack2Client(int32_t socketFd);
87     void clearResource();
88     void SendRequest2Server(int32_t socketFd);
89     bool GetDnsProxyServers(std::vector<std::string> &servers, size_t serverIdx);
90     bool MakeAddrInfo(std::vector<std::string> &servers, size_t serverIdx, AlignedSockAddr &addrParse,
91                       AlignedSockAddr &clientSock);
92     int32_t proxySockFd_;
93     int32_t proxySockFd6_;
94     int32_t epollFd_ = -1;
95     static uint16_t netId_;
96     static std::atomic_bool proxyListenSwitch_;
97     static std::mutex listenerMutex_;
98     DnsSocketHolder serverIdxOfSocket;
99     std::chrono::system_clock::time_point collectTime;
100     void EpollTimeout();
101     void CollectSocks();
102     void InitListenForIpv4();
103     void InitListenForIpv6();
104     bool InitForListening(epoll_event &proxyEvent, epoll_event &proxy6Event);
105     void GetRequestAndTransmit(int32_t family);
106 };
107 } // namespace nmd
108 } // namespace OHOS
109 #endif // INCLUDE_DNS_PROXY_LISTEN_H
110