reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
DnsStub.hxx
Go to the documentation of this file.
1#ifndef RESIP_DNS_STUB_HXX
2#define RESIP_DNS_STUB_HXX
3
4#ifdef HAVE_CONFIG_H
5#include "config.h"
6#endif
7
8
9#include <vector>
10#include <list>
11#include <map>
12#include <set>
13
14#include "rutil/FdPoll.hxx"
15#include "rutil/Fifo.hxx"
17#include "rutil/Logger.hxx"
19#include "rutil/Socket.hxx"
26#include "rutil/dns/RRCache.hxx"
30
31#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS
32
33namespace resip
34{
35class FdPollGrp;
36
38{
39 public:
42 virtual void onDnsCacheDumpRetrieved(std::pair<unsigned long, unsigned long> key, const Data& dnsCache) = 0;
43};
44
45template<typename T>
47{
48 public:
50 int status;
52 std::vector<T> records;
54 {
55 if (status == 0)
56 {
57 for (typename std::vector<T>::const_iterator i=records.begin(); i != records.end(); ++i)
58 {
59 if (i != records.begin())
60 {
61 strm << ", ";
62 }
63 i->dump(strm);
64 }
65 }
66 else
67 {
68 strm << domain << " lookup failed: " << msg;
69 }
70
71 return strm;
72 }
73};
74
75template<class T>
77{
78 r.dump(strm);
79 return strm;
80}
81
83{
84 public:
85 virtual ~DnsResultSink() {}
86 virtual void onDnsResult(const DNSResult<DnsHostRecord>&) = 0;
87 virtual void onLogDnsResult(const DNSResult<DnsHostRecord>&);
88
89// DnsAAAARecord will basically be non-functional if USE_IPV6 wasn't set in the
90// build.
91 virtual void onDnsResult(const DNSResult<DnsAAAARecord>&) = 0;
92 virtual void onLogDnsResult(const DNSResult<DnsAAAARecord>&);
93
94 virtual void onDnsResult(const DNSResult<DnsSrvRecord>&) = 0;
95 virtual void onLogDnsResult(const DNSResult<DnsSrvRecord>&);
96
97 virtual void onDnsResult(const DNSResult<DnsNaptrRecord>&) = 0;
98 virtual void onLogDnsResult(const DNSResult<DnsNaptrRecord>&);
99
100 virtual void onDnsResult(const DNSResult<DnsCnameRecord>&) = 0;
101 virtual void onLogDnsResult(const DNSResult<DnsCnameRecord>&);
102};
103
105{
106 public:
107 virtual ~DnsRawSink() {}
108 virtual void onDnsRaw(int statuts, const unsigned char* abuf, int len) = 0;
109};
110
112{
113 public:
115 typedef std::vector<Data> DataArr;
116 typedef std::vector<DnsResourceRecord*> DnsResourceRecordsByPtr;
117 typedef std::vector<GenericIPAddress> NameserverList;
118
120
122 {
123 public:
124 virtual ~Command() {}
125 virtual void execute() = 0;
126 };
127
129 {
130 public:
131 virtual ~ResultTransform() {}
132 virtual void transform(const Data& target, int rrType, DnsResourceRecordsByPtr& src) = 0;
133 };
134
135 class DnsStubException final : public BaseException
136 {
137 public:
138 DnsStubException(const Data& msg, const Data& file, const int line)
139 : BaseException(msg, file, line)
140 {
141 }
142
143 const char* name() const noexcept override { return "DnsStubException"; }
144 };
145
146 DnsStub(const NameserverList& additional = EmptyNameserverList,
147 AfterSocketCreationFuncPtr socketFunc = 0,
148 AsyncProcessHandler* asyncProcessHandler = 0,
149 FdPollGrp *pollGrp = 0);
150 ~DnsStub();
151
152 // call this method before you create SipStack if you'd like to change the
153 // default DNS lookup timeout and number of retries.
154 static void setDnsTimeoutAndTries(int timeoutInSec, int tries)
155 {
156 mDnsTimeout = timeoutInSec;
157 mDnsTries = tries;
158 }
159 static void enableDnsFeatures(unsigned int features) {mDnsFeatures |= features;} // bit mask of ExternalDns::Features
160
161 void setResultTransform(ResultTransform*);
163
169 void setEnumSuffixes(const std::vector<Data>& suffixes);
170 const std::vector<Data>& getEnumSuffixes() const;
171
176 void setEnumDomains(const std::map<Data,Data>& domains);
177 const std::map<Data,Data>& getEnumDomains() const;
178
179 void clearDnsCache();
180 void logDnsCache();
181 void getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler);
182 void setDnsCacheTTL(int ttl);
183 void setDnsCacheSize(int size);
184 void reloadDnsServers();
185 bool changeNameServers(const NameserverList& additional);
186 bool checkDnsChange();
187 bool supportedType(int);
188
189 template<class QueryType> void lookup(const Data& target, DnsResultSink* sink)
190 {
191 lookup<QueryType>(target, Protocol::Reserved, sink);
192 }
193
194 // There are three pre-defined protocols (see RRList.hxx). Zero(0) is
195 // reserved for internal use, so do not use 0. If you'd like to blacklist
196 // for different types of protocols, just pass in any integer other than
197 // those used for pre-defined protocols.
198 // ?slg? Should we offer a non-queuing version of this - currently all resip lookup
199 // requests are from the DnsThread context anyway, so there is no need to queue
200 // the request to the fifo.
201 template<class QueryType> void lookup(const Data& target, int protocol, DnsResultSink* sink)
202 {
203 QueryCommand<QueryType>* command = new QueryCommand<QueryType>(target, protocol, sink, *this);
204 queueCommand(command);
205 }
206
208
209 virtual void process(FdSet& fdset);
210 virtual unsigned int getTimeTillNextProcessMS();
211 virtual void buildFdSet(FdSet& fdset);
212 void setPollGrp(FdPollGrp* pollGrp);
213 void processTimers();
214
215 virtual void queueCommand(Command* command);
216
217 private:
218 void processFifo();
219
220 protected:
221 void cache(const Data& key, in_addr addr);
222 void cache(const Data& key, const unsigned char* abuf, int alen);
223 void cacheTTL(const Data& key, int rrType, int status, const unsigned char* abuf, int alen);
224
225 private:
226 class ResultConverter //.dcm. -- flyweight?
227 {
228 public:
229 virtual void notifyUser(const Data& target,
230 int status,
231 const Data& msg,
232 const DnsResourceRecordsByPtr& src,
233 DnsResultSink* sink) = 0;
234 virtual ~ResultConverter() {}
235 };
236
237 template<class QueryType>
238 class ResultConverterImpl : public ResultConverter
239 {
240 public:
241 virtual void notifyUser(const Data& target,
242 int status,
243 const Data& msg,
244 const DnsResourceRecordsByPtr& src,
245 DnsResultSink* sink)
246 {
247 resip_assert(sink);
248 DNSResult<typename QueryType::Type> result;
249 for (unsigned int i = 0; i < src.size(); ++i)
250 {
251 typename QueryType::Type* r = dynamic_cast<typename QueryType::Type*>(src[i]);
252 if(r)
253 {
254 result.records.push_back(*r);
255 }
256 else
257 {
258 ErrLog(<<"unexpected result type: " << typeid(src[i]).name());
259 }
260 }
261 result.domain = target;
262 result.status = status;
263 result.msg = msg;
264 sink->onLogDnsResult(result);
265 sink->onDnsResult(result);
266 }
267 };
268
269 class Query : public DnsRawSink
270 {
271 public:
272 Query(DnsStub& stub, ResultTransform* transform, ResultConverter* resultConv,
273 const Data& target, int rrType, bool followCname, int proto, DnsResultSink* s);
274 virtual ~Query();
275
276 enum {MAX_REQUERIES = 5};
277
278 void go();
279 void process(int status, const unsigned char* abuf, const int alen);
280 void onDnsRaw(int status, const unsigned char* abuf, int alen);
281 void followCname(const unsigned char* aptr, const unsigned char*abuf, const int alen, bool& bGotAnswers, bool& bDeleteThis, Data& targetToQuery);
282
283 private:
284 static DnsResourceRecordsByPtr Empty;
285 int mRRType;
286 DnsStub& mStub;
287 ResultTransform* mTransform;
288 ResultConverter* mResultConverter;
289 Data mTarget;
290 int mProto;
291 int mReQuery;
292 DnsResultSink* mSink;
293 bool mFollowCname;
294 };
295
296 private:
297 DnsStub(const DnsStub&); // disable copy ctor.
298 DnsStub& operator=(const DnsStub&);
299
300 public:
301 // sailesh - due to a bug in CodeWarrior,
302 // QueryCommand::execute() can only access this method
303 // if it's public. Even using "friend" doesn't work.
304 template<class QueryType>
305 void query(const Data& target, int proto, DnsResultSink* sink)
306 {
307 Query* query = new Query(*this, mTransform,
308 new ResultConverterImpl<QueryType>(),
309 target, QueryType::getRRType(),
310 QueryType::SupportsCName, proto, sink);
311 mQueries.insert(query);
312 query->go();
313 }
314
315 private:
316
317 template<class QueryType>
318 class QueryCommand : public Command
319 {
320 public:
321 QueryCommand(const Data& target,
322 int proto,
323 DnsResultSink* sink,
324 DnsStub& stub)
325 : mTarget(target),
326 mProto(proto),
327 mSink(sink),
328 mStub(stub)
329 {}
330
331 ~QueryCommand() {}
332
333 void execute()
334 {
335 mStub.query<QueryType>(mTarget, mProto, mSink);
336 }
337
338 private:
339 Data mTarget;
340 int mProto;
341 DnsResultSink* mSink;
342 DnsStub& mStub;
343 };
344
345 void doSetEnumSuffixes(const std::vector<Data>& suffixes);
346 void doSetEnumDomains(const std::map<Data,Data>& domains);
347
348 class SetEnumSuffixesCommand : public Command
349 {
350 public:
351 SetEnumSuffixesCommand(DnsStub& stub,
352 const std::vector<Data>& suffixes)
353 : mStub(stub),
354 mEnumSuffixes(suffixes)
355 {}
356 ~SetEnumSuffixesCommand() {}
357 void execute()
358 {
359 mStub.doSetEnumSuffixes(mEnumSuffixes);
360 }
361
362 private:
363 DnsStub& mStub;
364 std::vector<Data> mEnumSuffixes;
365 };
366
367 class SetEnumDomainsCommand : public Command
368 {
369 public:
370 SetEnumDomainsCommand(DnsStub& stub,
371 const std::map<Data,Data>& domains)
372 : mStub(stub),
373 mEnumDomains(domains)
374 {}
375 ~SetEnumDomainsCommand() {}
376 void execute()
377 {
378 mStub.doSetEnumDomains(mEnumDomains);
379 }
380
381 private:
382 DnsStub& mStub;
383 std::map<Data,Data> mEnumDomains;
384 };
385
386 void doClearDnsCache();
387
388 class ClearDnsCacheCommand : public Command
389 {
390 public:
391 ClearDnsCacheCommand(DnsStub& stub)
392 : mStub(stub)
393 {}
394 ~ClearDnsCacheCommand() {}
395 void execute()
396 {
397 mStub.doClearDnsCache();
398 }
399
400 private:
401 DnsStub& mStub;
402 };
403
404 void doLogDnsCache();
405
406 class LogDnsCacheCommand : public Command
407 {
408 public:
409 LogDnsCacheCommand(DnsStub& stub)
410 : mStub(stub)
411 {}
412 ~LogDnsCacheCommand() {}
413 void execute()
414 {
415 mStub.doLogDnsCache();
416 }
417
418 private:
419 DnsStub& mStub;
420 };
421
422 void doGetDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler);
423
424 class GetDnsCacheDumpCommand : public Command
425 {
426 public:
427 GetDnsCacheDumpCommand(DnsStub& stub, std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler)
428 : mStub(stub), mKey(key), mHandler(handler)
429 {}
430 ~GetDnsCacheDumpCommand() {}
431 void execute()
432 {
433 mStub.doGetDnsCacheDump(mKey, mHandler);
434 }
435
436 private:
437 DnsStub& mStub;
438 std::pair<unsigned long, unsigned long> mKey;
439 GetDnsCacheDumpHandler* mHandler;
440 };
441
442 void doReloadDnsServers();
443
444 class ReloadDnsServersCommand : public Command
445 {
446 public:
447 ReloadDnsServersCommand(DnsStub& stub)
448 : mStub(stub)
449 {}
450 ~ReloadDnsServersCommand() {}
451 void execute()
452 {
453 mStub.doReloadDnsServers();
454 }
455
456 private:
457 DnsStub& mStub;
458 };
459
460 SelectInterruptor mSelectInterruptor;
461 FdPollItemHandle mInterruptorHandle;
462
463 resip::Fifo<Command> mCommandFifo;
464
465 const unsigned char* skipDNSQuestion(const unsigned char *aptr,
466 const unsigned char *abuf,
467 int alen);
468 const unsigned char* createOverlay(const unsigned char* abuf,
469 const int alen,
470 const unsigned char* aptr,
471 std::vector<RROverlay>&,
472 bool discard=false);
473 void removeQuery(Query*);
474 void lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink);
475 Data errorMessage(int status);
476
477 ResultTransform* mTransform;
478 ExternalDns* mDnsProvider;
479 FdPollGrp* mPollGrp;
480 std::set<Query*> mQueries;
481
482 std::vector<Data> mEnumSuffixes; // where to do enum lookups
483 std::map<Data,Data> mEnumDomains;
484
485 static int mDnsTimeout; // in seconds
486 static int mDnsTries;
487 static unsigned int mDnsFeatures; // bit mask of ExternalDns::Features
488
490 AsyncProcessHandler* mAsyncProcessHandler;
491
493 RRCache mRRCache;
494};
495
497
498}
499
500#undef RESIPROCATE_SUBSYSTEM
501
502#endif
503
504/* ====================================================================
505 * The Vovida Software License, Version 1.0
506 *
507 * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved.
508 *
509 * Redistribution and use in source and binary forms, with or without
510 * modification, are permitted provided that the following conditions
511 * are met:
512 *
513 * 1. Redistributions of source code must retain the above copyright
514 * notice, this list of conditions and the following disclaimer.
515 *
516 * 2. Redistributions in binary form must reproduce the above copyright
517 * notice, this list of conditions and the following disclaimer in
518 * the documentation and/or other materials provided with the
519 * distribution.
520 *
521 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
522 * and "Vovida Open Communication Application Library (VOCAL)" must
523 * not be used to endorse or promote products derived from this
524 * software without prior written permission. For written
525 * permission, please contact vocal@vovida.org.
526 *
527 * 4. Products derived from this software may not be called "VOCAL", nor
528 * may "VOCAL" appear in their name, without prior written
529 * permission of Vovida Networks, Inc.
530 *
531 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
532 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
533 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
534 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
535 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
536 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
537 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
538 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
539 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
540 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
541 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
542 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
543 * DAMAGE.
544 *
545 * ====================================================================
546 *
547 * This software consists of voluntary contributions made by Vovida
548 * Networks, Inc. and many individuals on behalf of Vovida Networks,
549 * Inc. For more information on Vovida Networks, Inc., please see
550 * <http://www.vovida.org/>.
551 *
552 */
553
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
The abstract base-class for all exceptions thrown by resip code.
EncodeStream & dump(EncodeStream &strm) const
Definition DnsStub.hxx:53
std::vector< T > records
Definition DnsStub.hxx:52
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
virtual void onDnsRaw(int statuts, const unsigned char *abuf, int len)=0
virtual ~DnsRawSink()
Definition DnsStub.hxx:107
virtual void onDnsResult(const DNSResult< DnsHostRecord > &)=0
virtual void onDnsResult(const DNSResult< DnsSrvRecord > &)=0
virtual void onDnsResult(const DNSResult< DnsCnameRecord > &)=0
virtual void onDnsResult(const DNSResult< DnsNaptrRecord > &)=0
virtual void onDnsResult(const DNSResult< DnsAAAARecord > &)=0
virtual ~DnsResultSink()
Definition DnsStub.hxx:85
virtual void onLogDnsResult(const DNSResult< DnsHostRecord > &)
Definition DnsStub.cxx:47
virtual void execute()=0
DnsStubException(const Data &msg, const Data &file, const int line)
Definition DnsStub.hxx:138
const char * name() const noexcept override
Definition DnsStub.hxx:143
virtual void transform(const Data &target, int rrType, DnsResourceRecordsByPtr &src)=0
virtual unsigned int getTimeTillNextProcessMS()
Definition DnsStub.cxx:124
static NameserverList EmptyNameserverList
Definition DnsStub.hxx:119
std::vector< Data > DataArr
Definition DnsStub.hxx:115
const std::map< Data, Data > & getEnumDomains() const
Definition DnsStub.cxx:844
void reloadDnsServers()
Definition DnsStub.cxx:898
std::vector< GenericIPAddress > NameserverList
Definition DnsStub.hxx:117
void query(const Data &target, int proto, DnsResultSink *sink)
Definition DnsStub.hxx:305
void removeResultTransform()
Definition DnsStub.cxx:403
DnsStub(const NameserverList &additional=EmptyNameserverList, AfterSocketCreationFuncPtr socketFunc=0, AsyncProcessHandler *asyncProcessHandler=0, FdPollGrp *pollGrp=0)
Definition DnsStub.cxx:82
void logDnsCache()
Definition DnsStub.cxx:869
std::vector< DnsResourceRecord * > DnsResourceRecordsByPtr
Definition DnsStub.hxx:116
void setResultTransform(ResultTransform *)
Definition DnsStub.cxx:397
void setEnumDomains(const std::map< Data, Data > &domains)
Definition DnsStub.cxx:837
void clearDnsCache()
Definition DnsStub.cxx:856
void cacheTTL(const Data &key, int rrType, int status, const unsigned char *abuf, int alen)
Definition DnsStub.cxx:242
const std::vector< Data > & getEnumSuffixes() const
Definition DnsStub.cxx:825
static void setDnsTimeoutAndTries(int timeoutInSec, int tries)
Definition DnsStub.hxx:154
void setDnsCacheTTL(int ttl)
Definition DnsStub.cxx:917
void setDnsCacheSize(int size)
Definition DnsStub.cxx:923
void lookup(const Data &target, DnsResultSink *sink)
Definition DnsStub.hxx:189
virtual void queueCommand(Command *command)
Definition DnsStub.cxx:165
void cache(const Data &key, in_addr addr)
Definition DnsStub.cxx:177
bool checkDnsChange()
Definition DnsStub.cxx:318
void lookup(const Data &target, int protocol, DnsResultSink *sink)
Definition DnsStub.hxx:201
virtual void process(FdSet &fdset)
Definition DnsStub.cxx:149
void getDnsCacheDump(std::pair< unsigned long, unsigned long > key, GetDnsCacheDumpHandler *handler)
Definition DnsStub.cxx:882
bool supportedType(int)
Definition DnsStub.cxx:324
virtual void buildFdSet(FdSet &fdset)
Definition DnsStub.cxx:131
void setPollGrp(FdPollGrp *pollGrp)
Definition DnsStub.cxx:409
RRCache::Protocol Protocol
Definition DnsStub.hxx:114
virtual void handleDnsRaw(ExternalDnsRawResult)
Definition DnsStub.cxx:811
bool changeNameServers(const NameserverList &additional)
Definition DnsStub.cxx:307
static void enableDnsFeatures(unsigned int features)
Definition DnsStub.hxx:159
void processTimers()
Definition DnsStub.cxx:157
void setEnumSuffixes(const std::vector< Data > &suffixes)
Definition DnsStub.cxx:818
Object-oriented wrapper for your platform's file-descriptor set.
Definition Socket.hxx:162
A templated, threadsafe message-queue class.
Definition Fifo.hxx:16
virtual void onDnsCacheDumpRetrieved(std::pair< unsigned long, unsigned long > key, const Data &dnsCache)=0
static const int Reserved
Definition RRList.hxx:21
dcm! – add UnusedChecking(_enum) below;
void(* AfterSocketCreationFuncPtr)(Socket s, int transportType, const char *file, int line)
Definition Socket.hxx:107
DnsStub::Protocol Protocol
Definition DnsStub.hxx:496
struct FdPollItemFake * FdPollItemHandle
This is opaque type used to identify a particular Item.
Definition FdPoll.hxx:42
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
#define EncodeStream