Fixed build on MacOSX
[pwlib.git] / include / ptclib / pdns.h
blob754bdcb37a4dccd2db5acd8e5ac5836427b1534f
1 /*
2 * pdns.h
4 * PWLib library for DNS lookup services
6 * Portable Windows Library
8 * Copyright (c) 2003 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): ______________________________________.
26 * $Log$
27 * Revision 1.13 2007/08/13 00:56:30 rjongbloed
28 * Fixed compile on DevStudio 2003
30 * Revision 1.12 2007/08/10 10:07:29 dsandras
31 * Fixed DNS support thanks to Vincent Luba <luba novacom be>.
33 * Revision 1.11 2006/02/26 11:51:20 csoutheren
34 * Extended DNS test program to include URL based SRV lookups
35 * Re-arranged SRV lookup code to allow access to internal routine
36 * Reformatted code
38 * Revision 1.10 2006/02/26 09:26:17 shorne
39 * Added DNS SRV record lookups
41 * Revision 1.9 2005/11/30 12:47:37 csoutheren
42 * Removed tabs, reformatted some code, and changed tags for Doxygen
44 * Revision 1.8 2004/06/24 07:36:24 csoutheren
45 * Added definitions of T_SRV and T_NAPTR for hosts that do not have these
47 * Revision 1.7 2004/05/31 12:49:47 csoutheren
48 * Added handling of unknown DNS types
50 * Revision 1.6 2004/05/28 06:50:42 csoutheren
51 * Reorganised DNS functions to use templates, and exposed more internals to allow new DNS lookup types to be added
53 * Revision 1.5 2003/07/22 23:52:20 dereksmithies
54 * Fix from Fabrizio Ammollo to cope with when P_DNS is disabled. Thanks!
56 * Revision 1.4 2003/04/16 07:02:55 robertj
57 * Cleaned up source.
59 * Revision 1.3 2003/04/15 08:14:06 craigs
60 * Added single string form of GetSRVRecords
62 * Revision 1.2 2003/04/15 08:06:24 craigs
63 * Added Unix implementation
65 * Revision 1.1 2003/04/15 04:06:56 craigs
66 * Initial version
70 #if P_DNS
71 #ifndef _PDNS_H
72 #define _PDNS_H
74 #ifdef P_USE_PRAGMA
75 #pragma interface
76 #endif
78 #include <ptlib/sockets.h>
80 #include <ptclib/random.h>
81 #include <ptclib/url.h>
83 #if defined(_WIN32)
85 # include <windns.h>
86 # pragma comment(lib, P_DNS_LIBRARY)
88 // Accommodate spelling error in windns.h
89 enum { DnsSectionAdditional = DnsSectionAddtional };
91 #else
93 # define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines
94 # include <arpa/nameser.h>
95 # include <resolv.h>
96 # if defined(P_MACOSX) && (P_MACOSX >= 700)
97 # include <arpa/nameser_compat.h>
98 # endif
100 #endif // _WIN32
102 #ifdef P_HAS_RESOLVER
104 //////////////////////////////////////////////////////////////////////////
106 // these classes provide an emulation of the Microsoft DNS API
107 // on non-Window systems
110 #ifndef T_SRV
111 #define T_SRV 33
112 #endif
114 #ifndef T_NAPTR
115 #define T_NAPTR 35
116 #endif
119 #define DNS_STATUS int
120 #define DNS_TYPE_SRV T_SRV
121 #define DNS_TYPE_MX T_MX
122 #define DNS_TYPE_A T_A
123 #define DNS_TYPE_NAPTR T_NAPTR
124 #define DnsFreeRecordList 0
125 #define DNS_QUERY_STANDARD 0
126 #define DNS_QUERY_BYPASS_CACHE 0
128 typedef struct _DnsAData {
129 DWORD IpAddress;
130 } DNS_A_DATA;
132 typedef struct {
133 char pNameExchange[MAXDNAME];
134 WORD wPreference;
135 } DNS_MX_DATA;
137 typedef struct {
138 char pNameHost[MAXDNAME];
139 } DNS_PTR_DATA;
141 typedef struct _DnsSRVData {
142 char pNameTarget[MAXDNAME];
143 WORD wPriority;
144 WORD wWeight;
145 WORD wPort;
146 } DNS_SRV_DATA;
148 typedef struct _DnsNULLData {
149 DWORD dwByteCount;
150 char data[1];
151 } DNS_NULL_DATA;
153 typedef struct _DnsRecordFlags
155 unsigned Section : 2;
156 unsigned Delete : 1;
157 unsigned CharSet : 2;
158 unsigned Unused : 3;
159 unsigned Reserved : 24;
160 } DNS_RECORD_FLAGS;
162 typedef enum _DnsSection
164 DnsSectionQuestion,
165 DnsSectionAnswer,
166 DnsSectionAuthority,
167 DnsSectionAdditional,
168 } DNS_SECTION;
171 class DnsRecord {
172 public:
173 DnsRecord * pNext;
174 char pName[MAXDNAME];
175 WORD wType;
176 WORD wDataLength;
178 union {
179 DWORD DW; ///< flags as DWORD
180 DNS_RECORD_FLAGS S; ///< flags as structure
181 } Flags;
183 union {
184 DNS_A_DATA A;
185 DNS_MX_DATA MX;
186 DNS_PTR_DATA NS;
187 DNS_SRV_DATA SRV;
188 DNS_NULL_DATA Null;
189 } Data;
192 typedef DnsRecord * PDNS_RECORD;
194 extern void DnsRecordListFree(PDNS_RECORD rec, int FreeType);
196 extern DNS_STATUS DnsQuery_A(const char * service,
197 WORD requestType,
198 DWORD options,
199 void *,
200 PDNS_RECORD * results,
201 void *);
204 #endif // P_HAS_RESOLVER
206 namespace PDNS {
208 //////////////////////////////////////////////////////////////////////////
210 // this template automates the creation of a list of records for
211 // a specific type of DNS lookup
214 template <unsigned type, class RecordListType, class RecordType>
215 BOOL Lookup(const PString & name, RecordListType & recordList)
217 if (name.IsEmpty())
218 return FALSE;
220 recordList.RemoveAll();
222 PDNS_RECORD results = NULL;
223 DNS_STATUS status = DnsQuery_A((const char *)name,
224 type,
225 DNS_QUERY_STANDARD,
226 NULL,
227 &results,
228 NULL);
229 if (status != 0)
230 return FALSE;
232 // find records matching the correct type
233 PDNS_RECORD dnsRecord = results;
234 while (dnsRecord != NULL) {
235 RecordType * record = recordList.HandleDNSRecord(dnsRecord, results);
236 if (record != NULL)
237 recordList.Append(record);
238 dnsRecord = dnsRecord->pNext;
241 if (results != NULL)
242 DnsRecordListFree(results, DnsFreeRecordList);
244 return recordList.GetSize() != 0;
247 /////////////////////////////////////////////////////////////
249 class SRVRecord : public PObject
251 PCLASSINFO(SRVRecord, PObject);
252 public:
253 SRVRecord()
254 { used = FALSE; }
256 Comparison Compare(const PObject & obj) const;
257 void PrintOn(ostream & strm) const;
259 PString hostName;
260 PIPSocket::Address hostAddress;
261 BOOL used;
262 WORD port;
263 WORD priority;
264 WORD weight;
267 PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord)
268 public:
269 void PrintOn(ostream & strm) const;
271 SRVRecord * GetFirst();
272 SRVRecord * GetNext();
274 PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
276 protected:
277 PINDEX priPos;
278 PWORDArray priList;
282 * return a list of DNS SRV record with the specified service type
285 inline BOOL GetRecords(const PString & service, SRVRecordList & serviceList)
286 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); }
289 * provided for backwards compatibility
291 inline BOOL GetSRVRecords(
292 const PString & service,
293 SRVRecordList & serviceList
295 { return GetRecords(service, serviceList); }
298 * return a list of DNS SRV record with the specified service, type and domain
301 BOOL GetSRVRecords(
302 const PString & service,
303 const PString & type,
304 const PString & domain,
305 SRVRecordList & serviceList
309 * Perform a DNS lookup of the specified service
310 * @return TRUE if the service could be resolved, else FALSE
313 BOOL LookupSRV(
314 const PString & domain, ///< domain to lookup
315 const PString & service, ///< service to use
316 WORD defaultPort, ///< default por to use
317 PIPSocketAddressAndPortVector & addrList ///< returned list of sockets and ports
320 BOOL LookupSRV(
321 const PURL & url, ///< URL to lookup
322 const PString & service, ///< service to use
323 PStringList & returnStr ///< resolved addresses, if return value is TRUE
326 ////////////////////////////////////////////////////////////////
328 class MXRecord : public PObject
330 PCLASSINFO(MXRecord, PObject);
331 public:
332 MXRecord()
333 { used = FALSE; }
334 Comparison Compare(const PObject & obj) const;
335 void PrintOn(ostream & strm) const;
337 PString hostName;
338 PIPSocket::Address hostAddress;
339 BOOL used;
340 WORD preference;
343 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord)
344 public:
345 void PrintOn(ostream & strm) const;
347 MXRecord * GetFirst();
348 MXRecord * GetNext();
350 PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results);
352 protected:
353 PINDEX lastIndex;
357 * return a list of MX records for the specified domain
359 inline BOOL GetRecords(
360 const PString & domain,
361 MXRecordList & serviceList
363 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); }
366 * provided for backwards compatibility
368 inline BOOL GetMXRecords(
369 const PString & domain,
370 MXRecordList & serviceList
373 return GetRecords(domain, serviceList);
376 ///////////////////////////////////////////////////////////////////////////
378 }; // namespace PDNS
380 #endif // _PDNS_H
381 #endif // P_DNS
383 // End Of File ///////////////////////////////////////////////////////////////