/usr/include/pjlib-util/resolver.h is in libpjproject-dev 2.1.0.0.ast20130823-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | /* $Id: resolver.h 3553 2011-05-05 06:14:19Z nanang $ */
/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PJLIB_UTIL_RESOLVER_H__
#define __PJLIB_UTIL_RESOLVER_H__
/**
* @file resolver.h
* @brief Asynchronous DNS resolver
*/
#include <pjlib-util/dns.h>
PJ_BEGIN_DECL
/**
* @defgroup PJ_DNS_RESOLVER DNS Asynchronous/Caching Resolution Engine
* @ingroup PJ_DNS
* @{
*
* This module manages the host/server resolution by performing asynchronous
* DNS queries and caching the results in the cache. It uses PJLIB-UTIL
* low-level DNS parsing functions (see @ref PJ_DNS) and currently supports
* several types of DNS resource records such as A record (typical query with
* gethostbyname()) and SRV record.
*
* \section PJ_DNS_RESOLVER_FEATURES Features
*
* \subsection PJ_DNS_RESOLVER_FEATURES_ASYNC Asynchronous Query and Query Aggregation
*
* The DNS queries are performed asychronously, with timeout setting
* configured on per resolver instance basis. Application can issue multiple
* asynchronous queries simultaneously. Subsequent queries to the same resource
* (name and DNS resource type) while existing query is still pending will be
* merged into one query, so that only one DNS request packet is issued.
*
* \subsection PJ_DNS_RESOLVER_FEATURES_RETRANSMISSION Query Retransmission
*
* Asynchronous query will be retransmitted if no response is received
* within the preconfigured time. Once maximum retransmission count is
* exceeded and no response is received, the query will time out and the
* callback will be called when error status.
*
* \subsection PJ_DNS_RESOLVER_FEATURES_CACHING Response Caching with TTL
*
* The resolver instance caches the results returned by nameservers, to
* enhance the performance by minimizing the message round-trip to the server.
* The TTL of the cached resposne is calculated from minimum TTL value found
* across all resource record (RR) TTL in the response and further more it can
* be limited to some preconfigured maximum TTL in the resolver.
*
* Response caching can be disabled by setting the maximum TTL value of the
* resolver to zero.
*
* \subsection PJ_DNS_RESOLVER_FEATURES_PARALLEL Parallel and Backup Name Servers
*
* When the resolver is configured with multiple nameservers, initially the
* queries will be issued to multiple name servers simultaneously to probe
* which servers are not active. Once the probing stage is done, subsequent
* queries will be directed to only one ACTIVE server which provides the best
* response time.
*
* Name servers are probed periodically to see which nameservers are active
* and which are down. This probing is done when a query is sent, thus no
* timer is needed to maintain this. Also probing will be done in parallel
* so that there would be no additional delay for the query.
*
*
* \subsection PJ_DNS_RESOLVER_FEATURES_REC Supported Resource Records
*
* The low-level DNS parsing utility (see @ref PJ_DNS) supports parsing of
* the following DNS resource records (RR):
* - DNS A record
* - DNS SRV record
* - DNS PTR record
* - DNS NS record
* - DNS CNAME record
*
* For other types of record, application can parse the raw resource
* record data (rdata) from the parsed DNS packet (#pj_dns_parsed_packet).
*
*
* \section PJ_DNS_RESOLVER_USING Using the Resolver
*
* To use the resolver, application first creates the resolver instance by
* calling #pj_dns_resolver_create(). If application already has its own
* timer and ioqueue instances, it can instruct the resolver to use these
* instances so that application does not need to poll the resolver
* periodically to process events. If application does not specify the
* timer and ioqueue instance for the resolver, an internal timer and
* ioqueue will be created by the resolver. And since the resolver does not
* create it's own thread, application MUST poll the resolver periodically
* by calling #pj_dns_resolver_handle_events() to allow events (network and
* timer) to be processed.
*
* Next, application MUST configure the nameservers to be used by the
* resolver, by calling #pj_dns_resolver_set_ns().
*
* Application performs asynchronous query by submitting the query with
* #pj_dns_resolver_start_query(). Once the query completes (either
* successfully or times out), the callback will be called.
*
* Application can cancel a pending query by calling #pj_dns_resolver_cancel_query().
*
* Resolver must be destroyed by calling #pj_dns_resolver_destroy() to
* release all resources back to the system.
*
*
* \section PJ_DNS_RESOLVER_LIMITATIONS Resolver Limitations
*
* Current implementation mainly suffers from a growing memory problem,
* which mainly is caused by the response caching. Although there is only
* one cache entry per {query, name} combination, these cache entry will
* never get deleted since there is no timer is created to invalidate these
* entries. So the more unique names being queried by application, there more
* enties will be created in the response cache.
*
* Note that a single response entry will occupy about 600-700 bytes of
* pool memory (the PJ_DNS_RESOLVER_RES_BUF_SIZE value plus internal
* structure).
*
* Application can work around this problem by doing one of these:
* - disable caching by setting PJ_DNS_RESOLVER_MAX_TTL and
* PJ_DNS_RESOLVER_INVALID_TTL to zero.
* - periodically query #pj_dns_resolver_get_cached_count() and destroy-
* recreate the resolver to recycle the memory used by the resolver.
*
* Note that future improvement may solve this problem by introducing
* expiration timer to the cached entries.
*
*
* \section PJ_DNS_RESOLVER_REFERENCE Reference
*
* The PJLIB-UTIL resolver was built from the information in the following
* standards:
* - <A HREF="http://www.faqs.org/rfcs/rfc1035.html">
* RFC 1035: "Domain names - implementation and specification"</A>
* - <A HREF="http://www.faqs.org/rfcs/rfc2782.html">
* RFC 2782: "A DNS RR for specifying the location of services (DNS SRV)"
* </A>
*/
/**
* Opaque data type for DNS resolver object.
*/
typedef struct pj_dns_resolver pj_dns_resolver;
/**
* Opaque data type for asynchronous DNS query object.
*/
typedef struct pj_dns_async_query pj_dns_async_query;
/**
* Type of asynchronous callback which will be called when the asynchronous
* query completes.
*
* @param user_data The user data set by application when creating the
* asynchronous query.
* @param status Status of the DNS resolution.
* @param response The response packet received from the server. This
* argument may be NULL when status is not PJ_SUCCESS.
*/
typedef void pj_dns_callback(void *user_data,
pj_status_t status,
pj_dns_parsed_packet *response);
/**
* This structure describes resolver settings.
*/
typedef struct pj_dns_settings
{
unsigned options; /**< Options flags. */
unsigned qretr_delay; /**< Query retransmit delay in msec. */
unsigned qretr_count; /**< Query maximum retransmission count. */
unsigned cache_max_ttl; /**< Maximum TTL for cached responses. If the
value is zero, caching is disabled. */
unsigned good_ns_ttl; /**< See #PJ_DNS_RESOLVER_GOOD_NS_TTL */
unsigned bad_ns_ttl; /**< See #PJ_DNS_RESOLVER_BAD_NS_TTL */
} pj_dns_settings;
/**
* This structure represents DNS A record, as the result of parsing
* DNS response packet using #pj_dns_parse_a_response().
*/
typedef struct pj_dns_a_record
{
/** The target name being queried. */
pj_str_t name;
/** If target name corresponds to a CNAME entry, the alias contains
* the value of the CNAME entry, otherwise it will be empty.
*/
pj_str_t alias;
/** Number of IP addresses. */
unsigned addr_count;
/** IP addresses of the host found in the response */
pj_in_addr addr[PJ_DNS_MAX_IP_IN_A_REC];
/** Internal buffer for hostname and alias. */
char buf_[128];
} pj_dns_a_record;
/**
* Set default values to the DNS settings.
*
* @param s The DNS settings to be initialized.
*/
PJ_DECL(void) pj_dns_settings_default(pj_dns_settings *s);
/**
* Create DNS resolver instance. After the resolver is created, application
* MUST configure the nameservers with #pj_dns_resolver_set_ns().
*
* When creating the resolver, application may specify both timer heap
* and ioqueue instance, so that it doesn't need to poll the resolver
* periodically.
*
* @param pf Pool factory where the memory pool will be created from.
* @param name Optional resolver name to identify the instance in
* the log.
* @param options Optional options, must be zero for now.
* @param timer Optional timer heap instance to be used by the resolver.
* If timer heap is not specified, an internal timer will be
* created, and application would need to poll the resolver
* periodically.
* @param ioqueue Optional I/O Queue instance to be used by the resolver.
* If ioqueue is not specified, an internal one will be
* created, and application would need to poll the resolver
* periodically.
* @param p_resolver Pointer to receive the resolver instance.
*
* @return PJ_SUCCESS on success, or the appropriate error code,
*/
PJ_DECL(pj_status_t) pj_dns_resolver_create(pj_pool_factory *pf,
const char *name,
unsigned options,
pj_timer_heap_t *timer,
pj_ioqueue_t *ioqueue,
pj_dns_resolver **p_resolver);
/**
* Update the name servers for the DNS resolver. The name servers MUST be
* configured before any resolution can be done. The order of nameservers
* specifies their priority; the first name server will be tried first
* before the next in the list.
*
* @param resolver The resolver instance.
* @param count Number of name servers in the array.
* @param servers Array of name server IP addresses or hostnames. If
* hostname is specified, the hostname must be resolvable
* with pj_gethostbyname().
* @param ports Optional array of ports. If this argument is NULL,
* the nameserver will use default port.
*
* @return PJ_SUCCESS on success, or the appropriate error code,
*/
PJ_DECL(pj_status_t) pj_dns_resolver_set_ns(pj_dns_resolver *resolver,
unsigned count,
const pj_str_t servers[],
const pj_uint16_t ports[]);
/**
* Get the resolver current settings.
*
* @param resolver The resolver instance.
* @param st Buffer to be filled up with resolver settings.
*
* @return The query timeout setting, in seconds.
*/
PJ_DECL(pj_status_t) pj_dns_resolver_get_settings(pj_dns_resolver *resolver,
pj_dns_settings *st);
/**
* Modify the resolver settings. Application should initialize the settings
* by retrieving current settings first before applying new settings, to
* ensure that all fields are initialized properly.
*
* @param resolver The resolver instance.
* @param st The resolver settings.
*
* @return PJ_SUCCESS on success, or the appropriate error code,
*/
PJ_DECL(pj_status_t) pj_dns_resolver_set_settings(pj_dns_resolver *resolver,
const pj_dns_settings *st);
/**
* Poll for events from the resolver. This function MUST be called
* periodically when the resolver is using it's own timer or ioqueue
* (in other words, when NULL is specified as either \a timer or
* \a ioqueue argument in #pj_dns_resolver_create()).
*
* @param resolver The resolver instance.
* @param timeout Maximum time to wait for event occurence. If this
* argument is NULL, this function will wait forever
* until events occur.
*/
PJ_DECL(void) pj_dns_resolver_handle_events(pj_dns_resolver *resolver,
const pj_time_val *timeout);
/**
* Destroy DNS resolver instance.
*
* @param resolver The resolver object to be destryed
* @param notify If non-zero, all pending asynchronous queries will be
* cancelled and its callback will be called. If FALSE,
* then no callback will be called.
*
* @return PJ_SUCCESS on success, or the appropriate error code,
*/
PJ_DECL(pj_status_t) pj_dns_resolver_destroy(pj_dns_resolver *resolver,
pj_bool_t notify);
/**
* Create and start asynchronous DNS query for a single resource. Depending
* on whether response cache is available, this function will either start
* an asynchronous DNS query or call the callback immediately.
*
* If response is not available in the cache, an asynchronous query will be
* started, and callback will be called at some time later when the query
* completes. If \a p_query argument is not NULL, it will be filled with
* the asynchronous query object.
*
* If response is available in the cache, the callback will be called
* immediately before this function returns. In this case, if \a p_query
* argument is not NULL, the value will be set to NULL since no new query
* is started.
*
* @param resolver The resolver object.
* @param name The name to be resolved.
* @param type The type of resource (see #pj_dns_type constants).
* @param options Optional options, must be zero for now.
* @param cb Callback to be called when the query completes,
* either successfully or with failure.
* @param user_data Arbitrary user data to be associated with the query,
* and which will be given back in the callback.
* @param p_query Optional pointer to receive the query object, if one
* was started. If this pointer is specified, a NULL may
* be returned if response cache is available immediately.
*
* @return PJ_SUCCESS if either an asynchronous query has been
* started successfully or response cache is available and
* the user callback has been called.
*/
PJ_DECL(pj_status_t) pj_dns_resolver_start_query(pj_dns_resolver *resolver,
const pj_str_t *name,
int type,
unsigned options,
pj_dns_callback *cb,
void *user_data,
pj_dns_async_query **p_query);
/**
* Cancel a pending query.
*
* @param query The pending asynchronous query to be cancelled.
* @param notify If non-zero, the callback will be called with failure
* status to notify that the query has been cancelled.
*
* @return PJ_SUCCESS on success, or the appropriate error code,
*/
PJ_DECL(pj_status_t) pj_dns_resolver_cancel_query(pj_dns_async_query *query,
pj_bool_t notify);
/**
* A utility function to parse a DNS response containing A records into
* DNS A record.
*
* @param pkt The DNS response packet.
* @param rec The structure to be initialized with the parsed
* DNS A record from the packet.
*
* @return PJ_SUCCESS if response can be parsed successfully.
*/
PJ_DECL(pj_status_t) pj_dns_parse_a_response(const pj_dns_parsed_packet *pkt,
pj_dns_a_record *rec);
/**
* Put the specified DNS packet into DNS cache. This function is mainly used
* for testing the resolver, however it can also be used to inject entries
* into the resolver.
*
* The packet MUST contain either answer section or query section so that
* it can be indexed.
*
* @param resolver The resolver instance.
* @param pkt DNS packet to be added to the DNS cache. If the packet
* matches existing entry, it will update the entry.
* @param set_ttl If the value is PJ_FALSE, the entry will not expire
* (so use with care). Otherwise cache expiration will be
* calculated based on the TTL of the answeres.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pj_dns_resolver_add_entry(pj_dns_resolver *resolver,
const pj_dns_parsed_packet *pkt,
pj_bool_t set_ttl);
/**
* Get the total number of response in the response cache.
*
* @param resolver The resolver instance.
*
* @return Current number of entries being stored in the response
* cache.
*/
PJ_DECL(unsigned) pj_dns_resolver_get_cached_count(pj_dns_resolver *resolver);
/**
* Dump resolver state to the log.
*
* @param resolver The resolver instance.
* @param detail Will print detailed entries.
*/
PJ_DECL(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
pj_bool_t detail);
/**
* @}
*/
PJ_END_DECL
#endif /* __PJLIB_UTIL_RESOLVER_H__ */
|