PTLib
Version 2.10.4
|
00001 /* 00002 * pdns.h 00003 * 00004 * PWLib library for DNS lookup services 00005 * 00006 * Portable Windows Library 00007 * 00008 * Copyright (c) 2003 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Revision: 25959 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2011-06-02 00:33:14 -0500 (Thu, 02 Jun 2011) $ 00029 */ 00030 00031 #ifndef PTLIB_PDNS_H 00032 #define PTLIB_PDNS_H 00033 00034 #if P_DNS 00035 00036 #ifdef P_USE_PRAGMA 00037 #pragma interface 00038 #endif 00039 00040 #include <ptlib/sockets.h> 00041 00042 #include <ptclib/random.h> 00043 #include <ptclib/url.h> 00044 00045 #if defined(_WIN32) 00046 00047 #include <windns.h> 00048 00049 #ifndef __MINGW32__ 00050 00051 #include <ntverp.h> 00052 00053 #pragma comment(lib, "dnsapi.lib") 00054 00055 // Accommodate spelling error in windns.h 00056 enum { DnsSectionAdditional = DnsSectionAddtional }; 00057 00058 #endif 00059 00060 #else /* _WIN32 */ 00061 00062 #define P_HAS_RESOLVER 1 // set if using Unix-style DNS routines 00063 #include <arpa/nameser.h> 00064 #include <resolv.h> 00065 #if defined(P_MACOSX) && (P_MACOSX >= 700) 00066 #include <arpa/nameser_compat.h> 00067 #endif 00068 00069 #endif // _WIN32 00070 00071 00072 #if defined(_WIN32) && VER_PRODUCTBUILD < 6000 00073 typedef struct 00074 { 00075 WORD wOrder; 00076 WORD wPreference; 00077 PSTR pFlags; 00078 PSTR pService; 00079 PSTR pRegularExpression; 00080 PSTR pReplacement; 00081 } 00082 DNS_NAPTR_DATA; 00083 #endif 00084 00085 00086 #ifdef P_HAS_RESOLVER 00087 00089 // 00090 // these classes provide an emulation of the Microsoft DNS API 00091 // on non-Window systems 00092 // 00093 00094 #define DnsRecordListFree PDnsRecordListFree 00095 00096 #ifndef T_SRV 00097 #define T_SRV 33 00098 #endif 00099 00100 #ifndef T_NAPTR 00101 #define T_NAPTR 35 00102 #endif 00103 00104 00105 #define DNS_STATUS int 00106 #define DNS_TYPE_SRV T_SRV 00107 #define DNS_TYPE_MX T_MX 00108 #define DNS_TYPE_A T_A 00109 #define DNS_TYPE_NAPTR T_NAPTR 00110 #define DnsFreeRecordList 0 00111 #define DNS_QUERY_STANDARD 0 00112 #define DNS_QUERY_BYPASS_CACHE 0 00113 00114 typedef struct _DnsAData { 00115 DWORD IpAddress; 00116 } DNS_A_DATA; 00117 00118 typedef struct { 00119 char pNameExchange[MAXDNAME]; 00120 WORD wPreference; 00121 } DNS_MX_DATA; 00122 00123 typedef struct { 00124 char pNameHost[MAXDNAME]; 00125 } DNS_PTR_DATA; 00126 00127 typedef struct _DnsSRVData { 00128 char pNameTarget[MAXDNAME]; 00129 WORD wPriority; 00130 WORD wWeight; 00131 WORD wPort; 00132 } DNS_SRV_DATA; 00133 00134 typedef struct _DnsNULLData { 00135 DWORD dwByteCount; 00136 char data[1]; 00137 } DNS_NULL_DATA; 00138 00139 typedef struct _DnsRecordFlags 00140 { 00141 unsigned Section : 2; 00142 unsigned Delete : 1; 00143 unsigned CharSet : 2; 00144 unsigned Unused : 3; 00145 unsigned Reserved : 24; 00146 } DNS_RECORD_FLAGS; 00147 00148 typedef enum _DnsSection 00149 { 00150 DnsSectionQuestion, 00151 DnsSectionAnswer, 00152 DnsSectionAuthority, 00153 DnsSectionAdditional, 00154 } DNS_SECTION; 00155 00156 00157 class DnsRecord { 00158 public: 00159 DnsRecord * pNext; 00160 char pName[MAXDNAME]; 00161 WORD wType; 00162 WORD wDataLength; 00163 00164 union { 00165 DWORD DW; 00166 DNS_RECORD_FLAGS S; 00167 } Flags; 00168 00169 union { 00170 DNS_A_DATA A; 00171 DNS_MX_DATA MX; 00172 DNS_PTR_DATA NS; 00173 DNS_SRV_DATA SRV; 00174 DNS_NULL_DATA Null; 00175 } Data; 00176 }; 00177 00178 typedef DnsRecord DNS_RECORD; 00179 typedef DnsRecord * PDNS_RECORD; 00180 00181 00182 typedef DWORD IP4_ADDRESS, *PIP4_ADDRESS; 00183 00184 typedef struct _IP4_ARRAY 00185 { 00186 DWORD AddrCount; 00187 IP4_ADDRESS AddrArray[1]; 00188 } 00189 IP4_ARRAY, *PIP4_ARRAY; 00190 00191 00192 extern void PDnsRecordListFree(PDNS_RECORD rec, int FreeType); 00193 00194 extern DNS_STATUS DnsQuery_A(const char * service, 00195 WORD requestType, 00196 DWORD options, 00197 PIP4_ARRAY, 00198 PDNS_RECORD * results, 00199 void *); 00200 00201 00202 #endif // P_HAS_RESOLVER 00203 00204 namespace PDNS { 00205 00207 00208 DNS_STATUS Cached_DnsQuery( 00209 const char * name, 00210 WORD type, 00211 DWORD options, 00212 void * extra, 00213 PDNS_RECORD * queryResults, 00214 void * reserved 00215 ); 00216 00217 00218 void Cached_DnsRecordListFree(PDNS_RECORD, int); 00219 00221 // 00222 // this template automates the creation of a list of records for 00223 // a specific type of DNS lookup 00224 // 00225 00226 template <unsigned type, class RecordListType, class RecordType> 00227 PBoolean Lookup(const PString & name, RecordListType & recordList) 00228 { 00229 if (name.IsEmpty()) 00230 return false; 00231 00232 recordList.RemoveAll(); 00233 00234 PDNS_RECORD results = NULL; 00235 DNS_STATUS status = Cached_DnsQuery((const char *)name, 00236 type, 00237 DNS_QUERY_STANDARD, 00238 (PIP4_ARRAY)NULL, 00239 &results, 00240 NULL); 00241 if (status != 0) 00242 return false; 00243 00244 // find records matching the correct type 00245 PDNS_RECORD dnsRecord = results; 00246 while (dnsRecord != NULL) { 00247 RecordType * record = recordList.HandleDNSRecord(dnsRecord, results); 00248 if (record != NULL) 00249 recordList.Append(record); 00250 dnsRecord = dnsRecord->pNext; 00251 } 00252 00253 if (results != NULL) 00254 Cached_DnsRecordListFree(results, DnsFreeRecordList); 00255 00256 return recordList.GetSize() != 0; 00257 } 00258 00260 00261 class SRVRecord : public PObject 00262 { 00263 PCLASSINFO(SRVRecord, PObject); 00264 public: 00265 SRVRecord() 00266 { used = false; } 00267 00268 Comparison Compare(const PObject & obj) const; 00269 void PrintOn(ostream & strm) const; 00270 00271 PString hostName; 00272 PIPSocket::Address hostAddress; 00273 PBoolean used; 00274 WORD port; 00275 WORD priority; 00276 WORD weight; 00277 }; 00278 00279 PDECLARE_SORTED_LIST(SRVRecordList, PDNS::SRVRecord) 00280 public: 00281 void PrintOn(ostream & strm) const; 00282 00283 SRVRecord * GetFirst(); 00284 SRVRecord * GetNext(); 00285 00286 PDNS::SRVRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results); 00287 00288 protected: 00289 PINDEX priPos; 00290 PWORDArray priList; 00291 }; 00292 00297 inline PBoolean GetRecords(const PString & service, SRVRecordList & serviceList) 00298 { return Lookup<DNS_TYPE_SRV, SRVRecordList, SRVRecord>(service, serviceList); } 00299 00303 inline PBoolean GetSRVRecords( 00304 const PString & service, 00305 SRVRecordList & serviceList 00306 ) 00307 { return GetRecords(service, serviceList); } 00308 00313 PBoolean GetSRVRecords( 00314 const PString & service, 00315 const PString & type, 00316 const PString & domain, 00317 SRVRecordList & serviceList 00318 ); 00319 00325 PBoolean LookupSRV( 00326 const PString & srvQuery, 00327 WORD defaultPort, 00328 PIPSocketAddressAndPortVector & addrList 00329 ); 00330 00331 PBoolean LookupSRV( 00332 const PString & domain, 00333 const PString & service, 00334 WORD defaultPort, 00335 PIPSocketAddressAndPortVector & addrList 00336 ); 00337 00338 PBoolean LookupSRV( 00339 const PURL & url, 00340 const PString & service, 00341 PStringList & returnStr 00342 ); 00343 00345 00346 class MXRecord : public PObject 00347 { 00348 PCLASSINFO(MXRecord, PObject); 00349 public: 00350 MXRecord() 00351 { used = false; } 00352 Comparison Compare(const PObject & obj) const; 00353 void PrintOn(ostream & strm) const; 00354 00355 PString hostName; 00356 PIPSocket::Address hostAddress; 00357 PBoolean used; 00358 WORD preference; 00359 }; 00360 00361 PDECLARE_SORTED_LIST(MXRecordList, PDNS::MXRecord) 00362 public: 00363 void PrintOn(ostream & strm) const; 00364 00365 MXRecord * GetFirst(); 00366 MXRecord * GetNext(); 00367 00368 PDNS::MXRecord * HandleDNSRecord(PDNS_RECORD dnsRecord, PDNS_RECORD results); 00369 00370 protected: 00371 PINDEX lastIndex; 00372 }; 00373 00377 inline PBoolean GetRecords( 00378 const PString & domain, 00379 MXRecordList & serviceList 00380 ) 00381 { return Lookup<DNS_TYPE_MX, MXRecordList, MXRecord>(domain, serviceList); } 00382 00386 inline PBoolean GetMXRecords( 00387 const PString & domain, 00388 MXRecordList & serviceList 00389 ) 00390 { 00391 return GetRecords(domain, serviceList); 00392 } 00393 00394 00395 }; // namespace PDNS 00396 00397 #endif // P_DNS 00398 00399 #endif // PTLIB_PDNS_H 00400 00401 00402 // End Of File ///////////////////////////////////////////////////////////////