EpcTools
An event based multi-threaded C++ development framework.
dnscache.h
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2017 Sprint
3 * Copyright (c) 2019 Sprint
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 
18 #ifndef __DNSCACHE_H
19 #define __DNSCACHE_H
20 
23 
24 #include <list>
25 #include <map>
26 #include <ares.h>
27 
28 #include "dnsquery.h"
29 #include "eatomic.h"
30 #include "esynch.h"
31 #include "etevent.h"
32 #include "eip.h"
33 
34 namespace DNS
35 {
37 
38  typedef int namedserverid_t;
39 
40  class Cache;
41  class QueryProcessor;
42 
43  const namedserverid_t NS_DEFAULT = 0;
44 
47 
48  class QueryProcessorThread : public EThreadBasic
49  {
50  friend QueryProcessor;
51 
52  public:
53  QueryProcessorThread(QueryProcessor &qp);
54 
55  Void incActiveQueries() { m_activequeries.Increment(); }
56  Void decActiveQueries() { m_activequeries.Decrement(); }
57  int getActiveQueries() { return m_activequeries.currCount(); }
58 
59  virtual Dword threadProc(Void *arg);
60 
61  Void shutdown();
62 
63  protected:
64  static Void ares_callback( Void *arg, int status, int timeouts, unsigned char *abuf, int alen );
65 
66  private:
67  QueryProcessorThread();
68  Void wait_for_completion();
69 
70  Bool m_shutdown;
71  QueryProcessor &m_qp;
72  ESemaphorePrivate m_activequeries;
73  };
74 
77 
78  struct NamedServer
79  {
80  char address[128];
81  int family;
82  int udp_port;
83  int tcp_port;
84  };
85 
88 
89  class QueryProcessor
90  {
91  friend Cache;
92  friend QueryProcessorThread;
93  public:
94 
95  QueryProcessor( Cache &cache );
96  ~QueryProcessor();
97 
98  Cache &getCache() { return m_cache; }
99 
100  Void shutdown();
101 
102  QueryProcessorThread *getQueryProcessorThread() { return &m_qpt; }
103 
104  Void setLocalIpAddress(const char *address) { m_localip = address; }
105  const EIpAddress &getLocalIp() { return m_localip; }
106 
107  Void addNamedServer(const char *address, int udp_port, int tcp_port);
108  Void removeNamedServer(const char *address);
109  Void applyNamedServers();
110 
111  EMutexPrivate &getChannelMutex() { return m_mutex; }
112 
113  protected:
114  ares_channel getChannel() { return m_channel; }
115 
116  Void beginQuery( QueryPtr &q );
117  Void endQuery();
118 
119  private:
120  QueryProcessor();
121  Void init();
122 
123  Cache &m_cache;
124  QueryProcessorThread m_qpt;
125  ares_channel m_channel;
126  EIpAddress m_localip;
127  std::map<const char *,NamedServer> m_servers;
128  EMutexPrivate m_mutex;
129  };
130 
133 
134  #define SAVED_QUERY_TYPE "type"
135  #define SAVED_QUERY_DOMAIN "domain"
136 
137  const uint16_t CR_SAVEQUERIES = EM_USER + 1;
138  const uint16_t CR_FORCEREFRESH = EM_USER + 2;
139 
140  class CacheRefresher : EThreadPrivate
141  {
142  friend Cache;
143 
144  protected:
145  CacheRefresher(Cache &cache, unsigned int maxconcur, int percent, long interval);
146 
147  virtual Void onInit() override;
148  virtual Void onQuit() override;
149  virtual Void onTimer( EThreadEventTimer *timer ) override;
150  Void saveQueries( EThreadMessage &msg ) { _saveQueries(); }
151  Void forceRefresh( EThreadMessage &msg ) { _forceRefresh(); }
152 
153  const EString &queryFileName() { return m_qfn; }
154  long querySaveFrequency() { return m_qsf; }
155 
156  Void loadQueries(const char *qfn);
157  Void loadQueries(const std::string &qfn) { loadQueries(qfn.c_str()); }
158  Void initSaveQueries(const char *qfn, long qsf);
159  Void saveQueries() { sendMessage(CR_SAVEQUERIES); }
160  Void forceRefresh() { sendMessage(CR_FORCEREFRESH); }
161 
163 
164  private:
165  CacheRefresher();
166  static Void callback( QueryPtr q, Bool cacheHit, const Void *data );
167  Void _submitQueries( std::list<QueryCacheKey> &keys );
168  Void _refreshQueries();
169  Void _saveQueries();
170  Void _forceRefresh();
171 
172  Cache &m_cache;
173  ESemaphorePrivate m_sem;
174  int m_percent;
175  EThreadEventTimer m_timer;
176  long m_interval;
177  Bool m_running;
178  EString m_qfn;
179  long m_qsf;
180  EThreadEventTimer m_qst;
181  };
182 
184 
187 
189  class Cache
190  {
191  friend QueryProcessor;
192  friend QueryProcessorThread;
193 
194  friend CacheRefresher;
195 
196  public:
198  Cache();
200  ~Cache();
201 
205  static Cache& getInstance(namedserverid_t nsid);
208  static Cache& getInstance() { return getInstance(NS_DEFAULT); }
209 
212  static unsigned int getRefreshConcurrent() { return m_concur; }
217  static unsigned int setRefreshConcurrent(unsigned int concur) { return m_concur = concur; }
218 
221  static int getRefreshPercent() { return m_percent; }
225  static int setRefreshPercent(int percent) { return m_percent = percent; }
226 
229  static long getRefeshInterval() { return m_interval; }
233  static long setRefreshInterval(long interval) { return m_interval = interval; }
234 
237  static int getQueryTimeoutMS() { return m_querytimeout; }
241  static int setQueryTimeoutMS(int timeout) { return m_querytimeout = timeout; }
242 
245  static int getQueryTries() { return m_querytries; }
249  static int setQueryTries(int tries) { return m_querytries = tries; }
250 
255  Void addNamedServer(const char *address, int udp_port=53, int tcp_port=53);
258  Void removeNamedServer(const char *address);
260  Void applyNamedServers();
263  Void setLocalIpAddress(const char *address);
264 
271  QueryPtr query( ns_type rtype, const std::string &domain, Bool &cacheHit, Bool ignorecache=false );
278  Void query( ns_type rtype, const std::string &domain, CachedDNSQueryCallback cb, const Void *data=NULL, Bool ignorecache=false );
279 
282  Void loadQueries(const char *qfn);
285  Void loadQueries(const std::string &qfn) { loadQueries(qfn.c_str()); }
289  Void initSaveQueries(const char *qfn, long qsf);
291  Void saveQueries();
293  Void forceRefresh();
294 
297  namedserverid_t getNamedServerId() { return m_nsid; }
298 
301  long resetNewQueryCount() { return atomic_swap(m_newquerycnt, 0); }
302 
303  protected:
305  Void updateCache( QueryPtr q );
306  QueryPtr lookupQuery( ns_type rtype, const std::string &domain );
307  QueryPtr lookupQuery( QueryCacheKey &qck );
308 
309  Void identifyExpired( std::list<QueryCacheKey> &keys, int percent );
310  Void getCacheKeys( std::list<QueryCacheKey> &keys );
312 
313  private:
314 
315  static int m_ref;
316  static unsigned int m_concur;
317  static int m_percent;
318  static long m_interval;
319  static int m_querytimeout;
320  static int m_querytries;
321 
322  QueryProcessor m_qp;
323  CacheRefresher m_refresher;
324  QueryCache m_cache;
325  namedserverid_t m_nsid;
326  ERWLock m_cacherwlock;
327  long m_newquerycnt;
328  };
329 }
330 
331 #endif // #ifndef __DNSCACHE_H
static Cache & getInstance()
Retrieves/creates the default Cache instance.
Definition: dnscache.h:208
base class for EThreadPrivate and EThreadPublic
Definition: etevent.h:1062
static int setRefreshPercent(int percent)
Assigns the refresh percentage value.
Definition: dnscache.h:225
static int getQueryTries()
Retrives the query "tries" (attempts) value.
Definition: dnscache.h:245
static long setRefreshInterval(long interval)
Assigns the refresh interval.
Definition: dnscache.h:233
long resetNewQueryCount()
Resets the number of new queries (not saved) to zero.
Definition: dnscache.h:301
Macros for performing CPU atomic/interlaced operations.
namedserverid_t getNamedServerId()
Retrieves the named server ID associated with this DNS cache.
Definition: dnscache.h:297
#define atomic_swap(a, b)
atomic swap - replaces a with b
Definition: eatomic.h:39
static unsigned int getRefreshConcurrent()
Retrieves the current setting of the maximum number of conncurrent DNS queries that can be performed ...
Definition: dnscache.h:212
Void loadQueries(const std::string &qfn)
Executes the DNS queries at startup from the suppoied file.
Definition: dnscache.h:285
#define EM_USER
beginning of user events
Definition: etevent.h:810
Defines the EIpAddress and EIpFilterRule classes.
Thread timer class.
Definition: etevent.h:828
Contains the definition of the DNS query related classes.
static unsigned int setRefreshConcurrent(unsigned int concur)
Sets the maximum number of conncurrent DNS queries that can be performed while refreshing the DNS cac...
Definition: dnscache.h:217
An event message that is to be sent to a thread.
Definition: etevent.h:264
static int setQueryTries(int tries)
Assigns the query "tries" (attempts) value.
Definition: dnscache.h:249
An abstract class that represents contains the threadProc() that will be run in a separate thread...
Definition: etbasic.h:53
Represents an IP address with mask.
Definition: eip.h:40
static int getRefreshPercent()
Retrieves the current refresh percentage value.
Definition: dnscache.h:221
#define DECLARE_MESSAGE_MAP()
Inserts message map declarations into the thread class.
Definition: etevent.h:1015
Defines the functionality associated with a DNS cache.
Definition: dnscache.h:189
static long getRefeshInterval()
Retrieves the refresh interval.
Definition: dnscache.h:229
Definition: dnscache.h:34
Represents a private semaphore, the semaphore data is allocated from either the stack or heap...
Definition: esynch.h:382
A private mutex (the mutex data is allocated from either the heap or stack).
Definition: esynch.h:175
static int setQueryTimeoutMS(int timeout)
Assigns the query timeout value.
Definition: dnscache.h:241
std::shared_ptr< Query > QueryPtr
A typedef to std::shared_ptr<Query>.
Definition: dnsquery.h:40
String class.
Definition: estring.h:31
Contains definitions for synchronization objects.
Encapsulates a read-write lock object.
Definition: esynch.h:507
static int getQueryTimeoutMS()
Retrieves the query timeout setting.
Definition: dnscache.h:237