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 
33 namespace DNS
34 {
36 
37  typedef int namedserverid_t;
38 
39  class Cache;
40  class QueryProcessor;
41 
42  const namedserverid_t NS_DEFAULT = 0;
43 
46 
47  class QueryProcessorThread : public EThreadBasic
48  {
49  friend QueryProcessor;
50 
51  public:
52  QueryProcessorThread(QueryProcessor &qp);
53 
54  Void incActiveQueries() { m_activequeries.Increment(); }
55  Void decActiveQueries() { m_activequeries.Decrement(); }
56  int getActiveQueries() { return m_activequeries.currCount(); }
57 
58  virtual Dword threadProc(Void *arg);
59 
60  Void shutdown();
61 
62  protected:
63  static Void ares_callback( Void *arg, int status, int timeouts, unsigned char *abuf, int alen );
64 
65  private:
66  QueryProcessorThread();
67  Void wait_for_completion();
68 
69  Bool m_shutdown;
70  QueryProcessor &m_qp;
71  ESemaphorePrivate m_activequeries;
72  };
73 
76 
77  struct NamedServer
78  {
79  char address[128];
80  int family;
81  int udp_port;
82  int tcp_port;
83  };
84 
87 
88  class QueryProcessor
89  {
90  friend Cache;
91  friend QueryProcessorThread;
92  public:
93 
94  QueryProcessor( Cache &cache );
95  ~QueryProcessor();
96 
97  Cache &getCache() { return m_cache; }
98 
99  Void shutdown();
100 
101  QueryProcessorThread *getQueryProcessorThread() { return &m_qpt; }
102 
103  Void addNamedServer(const char *address, int udp_port, int tcp_port);
104  Void removeNamedServer(const char *address);
105  Void applyNamedServers();
106 
107  EMutexPrivate &getChannelMutex() { return m_mutex; }
108 
109  protected:
110  ares_channel getChannel() { return m_channel; }
111 
112  Void beginQuery( QueryPtr &q );
113  Void endQuery();
114 
115  private:
116  QueryProcessor();
117  Void init();
118 
119  Cache &m_cache;
120  QueryProcessorThread m_qpt;
121  ares_channel m_channel;
122  std::map<const char *,NamedServer> m_servers;
123  EMutexPrivate m_mutex;
124  };
125 
128 
129  #define SAVED_QUERY_TYPE "type"
130  #define SAVED_QUERY_DOMAIN "domain"
131 
132  const uint16_t CR_SAVEQUERIES = EM_USER + 1;
133  const uint16_t CR_FORCEREFRESH = EM_USER + 2;
134 
135  class CacheRefresher : EThreadPrivate
136  {
137  friend Cache;
138 
139  protected:
140  CacheRefresher(Cache &cache, unsigned int maxconcur, int percent, long interval);
141 
142  virtual Void onInit();
143  virtual Void onQuit();
144  virtual Void onTimer( EThreadEventTimer &timer );
145  Void saveQueries( EThreadMessage &msg ) { _saveQueries(); }
146  Void forceRefresh( EThreadMessage &msg ) { _forceRefresh(); }
147 
148  const EString &queryFileName() { return m_qfn; }
149  long querySaveFrequency() { return m_qsf; }
150 
151  Void loadQueries(const char *qfn);
152  Void loadQueries(const std::string &qfn) { loadQueries(qfn.c_str()); }
153  Void initSaveQueries(const char *qfn, long qsf);
154  Void saveQueries() { sendMessage(CR_SAVEQUERIES); }
155  Void forceRefresh() { sendMessage(CR_FORCEREFRESH); }
156 
158 
159  private:
160  CacheRefresher();
161  static Void callback( QueryPtr q, Bool cacheHit, const Void *data );
162  Void _submitQueries( std::list<QueryCacheKey> &keys );
163  Void _refreshQueries();
164  Void _saveQueries();
165  Void _forceRefresh();
166 
167  Cache &m_cache;
168  ESemaphorePrivate m_sem;
169  int m_percent;
170  EThreadEventTimer m_timer;
171  long m_interval;
172  Bool m_running;
173  EString m_qfn;
174  long m_qsf;
175  EThreadEventTimer m_qst;
176  };
177 
179 
182 
184  class Cache
185  {
186  friend QueryProcessor;
187  friend QueryProcessorThread;
188 
189  friend CacheRefresher;
190 
191  public:
193  Cache();
195  ~Cache();
196 
200  static Cache& getInstance(namedserverid_t nsid);
203  static Cache& getInstance() { return getInstance(NS_DEFAULT); }
204 
207  static unsigned int getRefreshConcurrent() { return m_concur; }
212  static unsigned int setRefreshConcurrent(unsigned int concur) { return m_concur = concur; }
213 
216  static int getRefreshPercent() { return m_percent; }
220  static int setRefreshPercent(int percent) { return m_percent = percent; }
221 
224  static long getRefeshInterval() { return m_interval; }
228  static long setRefreshInterval(long interval) { return m_interval = interval; }
229 
234  Void addNamedServer(const char *address, int udp_port=53, int tcp_port=53);
237  Void removeNamedServer(const char *address);
239  Void applyNamedServers();
240 
247  QueryPtr query( ns_type rtype, const std::string &domain, Bool &cacheHit, Bool ignorecache=false );
254  Void query( ns_type rtype, const std::string &domain, CachedDNSQueryCallback cb, const Void *data=NULL, Bool ignorecache=false );
255 
258  Void loadQueries(const char *qfn);
261  Void loadQueries(const std::string &qfn) { loadQueries(qfn.c_str()); }
265  Void initSaveQueries(const char *qfn, long qsf);
267  Void saveQueries();
269  Void forceRefresh();
270 
273  namedserverid_t getNamedServerId() { return m_nsid; }
274 
277  long resetNewQueryCount() { return atomic_swap(m_newquerycnt, 0); }
278 
279  protected:
281  Void updateCache( QueryPtr q );
282  QueryPtr lookupQuery( ns_type rtype, const std::string &domain );
283  QueryPtr lookupQuery( QueryCacheKey &qck );
284 
285  Void identifyExpired( std::list<QueryCacheKey> &keys, int percent );
286  Void getCacheKeys( std::list<QueryCacheKey> &keys );
288 
289  private:
290 
291  static int m_ref;
292  static unsigned int m_concur;
293  static int m_percent;
294  static long m_interval;
295 
296  QueryProcessor m_qp;
297  CacheRefresher m_refresher;
298  QueryCache m_cache;
299  namedserverid_t m_nsid;
300  ERWLock m_cacherwlock;
301  long m_newquerycnt;
302  };
303 }
304 
305 #endif // #ifndef __DNSCACHE_H
EThreadEventTimer
Thread timer class.
Definition: etevent.h:852
DNS::Cache::forceRefresh
Void forceRefresh()
Forces a refresh of the DNS cache.
Definition: dnscache.cpp:518
DNS::Cache::applyNamedServers
Void applyNamedServers()
Updates the named servers as a set in the underlying c-ares library.
Definition: dnscache.cpp:461
EThreadMessage
An event message that is to be sent to a thread.
Definition: etevent.h:266
DNS::Cache::getInstance
static Cache & getInstance()
Retrieves/creates the default Cache instance.
Definition: dnscache.h:203
DNS::Cache::loadQueries
Void loadQueries(const std::string &qfn)
Executes the DNS queries at startup from the suppoied file.
Definition: dnscache.h:261
DNS::Cache::setRefreshInterval
static long setRefreshInterval(long interval)
Assigns the refresh interval.
Definition: dnscache.h:228
dnsquery.h
Contains the definition of the DNS query related classes.
DNS::Cache::getRefreshConcurrent
static unsigned int getRefreshConcurrent()
Retrieves the current setting of the maximum number of conncurrent DNS queries that can be performed ...
Definition: dnscache.h:207
DNS::Cache::setRefreshPercent
static int setRefreshPercent(int percent)
Assigns the refresh percentage value.
Definition: dnscache.h:220
EMutexPrivate
A private mutex (the mutex data is allocated from either the heap or stack).
Definition: esynch.h:175
EThreadEvent
base class for EThreadPrivate and EThreadPublic
Definition: etevent.h:1040
atomic_swap
#define atomic_swap(a, b)
atomic swap - replaces a with b
Definition: eatomic.h:39
esynch.h
Contains definitions for synchronization objects.
DNS::Cache::saveQueries
Void saveQueries()
Saves the DNS queries that are part of the cache.
Definition: dnscache.cpp:513
etevent.h
eatomic.h
Macros for performing CPU atomic/interlaced operations.
ERWLock
Encapsulates a read-write lock object.
Definition: esynch.h:507
DNS::Cache::getNamedServerId
namedserverid_t getNamedServerId()
Retrieves the named server ID associated with this DNS cache.
Definition: dnscache.h:273
DNS::Cache::Cache
Cache()
Default constructor.
Definition: dnscache.cpp:372
EM_USER
#define EM_USER
beginning of user events
Definition: etevent.h:786
DNS::Cache::resetNewQueryCount
long resetNewQueryCount()
Resets the number of new queries (not saved) to zero.
Definition: dnscache.h:277
ESemaphorePrivate
Represents a private semaphore, the semaphore data is allocated from either the stack or heap.
Definition: esynch.h:382
DNS::Cache
Defines the functionality associated with a DNS cache.
Definition: dnscache.h:184
DNS::Cache::addNamedServer
Void addNamedServer(const char *address, int udp_port=53, int tcp_port=53)
Adds a named server to this DNS cache object.
Definition: dnscache.cpp:451
DNS::Cache::query
QueryPtr query(ns_type rtype, const std::string &domain, Bool &cacheHit, Bool ignorecache=false)
Performs a DNS query synchronously.
Definition: dnscache.cpp:466
DNS::Cache::initSaveQueries
Void initSaveQueries(const char *qfn, long qsf)
Initializes the settings used to save queries.
Definition: dnscache.cpp:508
EThreadBasic
An abstract class that represents contains the threadProc() that will be run in a separate thread.
Definition: etbasic.h:53
DECLARE_MESSAGE_MAP
#define DECLARE_MESSAGE_MAP()
Inserts message map declarations into the thread class.
Definition: etevent.h:793
DNS::Cache::getRefeshInterval
static long getRefeshInterval()
Retrieves the refresh interval.
Definition: dnscache.h:224
DNS::Cache::loadQueries
Void loadQueries(const char *qfn)
Executes the DNS queries at startup from the suppoied file.
Definition: dnscache.cpp:503
DNS::Cache::setRefreshConcurrent
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:212
DNS
Definition: dnscache.h:33
DNS::Cache::~Cache
~Cache()
Class destructor.
Definition: dnscache.cpp:395
EString
String class.
Definition: estring.h:30
DNS::QueryPtr
std::shared_ptr< Query > QueryPtr
A typedef to std::shared_ptr<Query>.
Definition: dnsquery.h:40
DNS::Cache::removeNamedServer
Void removeNamedServer(const char *address)
Removes the specified named server from this DNS cache.
Definition: dnscache.cpp:456
DNS::Cache::getRefreshPercent
static int getRefreshPercent()
Retrieves the current refresh percentage value.
Definition: dnscache.h:216