dns_resolver.h File Reference

DNS Resolver API. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_dns_resolver
 DNS resolver implementation. More...

Functions

int ast_dns_resolver_add_record (struct ast_dns_query *query, int rr_type, int rr_class, int ttl, const char *data, const size_t size)
 Add a DNS record to the result of a DNS query.
void ast_dns_resolver_completed (struct ast_dns_query *query)
 Mark a DNS query as having been completed.
void * ast_dns_resolver_get_data (const struct ast_dns_query *query)
 Retrieve resolver specific data.
int ast_dns_resolver_register (struct ast_dns_resolver *resolver)
 Register a DNS resolver.
int ast_dns_resolver_set_data (struct ast_dns_query *query, void *data)
 Set resolver specific data on a query.
int ast_dns_resolver_set_result (struct ast_dns_query *query, unsigned int secure, unsigned int bogus, unsigned int rcode, const char *canonical, const char *answer, size_t answer_size)
 Set result information for a DNS query.
void ast_dns_resolver_unregister (struct ast_dns_resolver *resolver)
 Unregister a DNS resolver.


Detailed Description

DNS Resolver API.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file dns_resolver.h.


Function Documentation

int ast_dns_resolver_add_record ( struct ast_dns_query query,
int  rr_type,
int  rr_class,
int  ttl,
const char *  data,
const size_t  size 
)

Add a DNS record to the result of a DNS query.

Parameters:
query The DNS query
rr_type Resource record type
rr_class Resource record class
ttl TTL of the record
data The raw DNS record
size The size of the raw DNS record
Return values:
0 success
-1 failure

Definition at line 443 of file dns_core.c.

References allocate_dns_record(), ast_debug, AST_LIST_INSERT_TAIL, ast_dns_record::data_len, ast_dns_record::data_ptr, ast_dns_query::result, ast_dns_record::rr_class, ast_dns_record::rr_type, and ast_dns_record::ttl.

Referenced by AST_TEST_DEFINE(), naptr_thread(), resolution_thread(), srv_thread(), and unbound_resolver_callback().

00444 {
00445    struct ast_dns_record *record;
00446 
00447    if (rr_type < 0) {
00448       ast_debug(2, "Query '%p': Could not add record, invalid resource record type '%d'\n",
00449          query, rr_type);
00450       return -1;
00451    } else if (rr_type > ns_t_max) {
00452       ast_debug(2, "Query '%p': Could not add record, resource record type '%d' exceeds maximum\n",
00453          query, rr_type);
00454       return -1;
00455    } else if (rr_class < 0) {
00456       ast_debug(2, "Query '%p': Could not add record, invalid resource record class '%d'\n",
00457          query, rr_class);
00458       return -1;
00459    } else if (rr_class > ns_c_max) {
00460       ast_debug(2, "Query '%p': Could not add record, resource record class '%d' exceeds maximum\n",
00461          query, rr_class);
00462       return -1;
00463    } else if (ttl < 0) {
00464       ast_debug(2, "Query '%p': Could not add record, invalid TTL '%d'\n",
00465          query, ttl);
00466       return -1;
00467    } else if (!data || !size) {
00468       ast_debug(2, "Query '%p': Could not add record, no data specified\n",
00469          query);
00470       return -1;
00471    } else if (!query->result) {
00472       ast_debug(2, "Query '%p': No result was set on the query, thus records can not be added\n",
00473          query);
00474       return -1;
00475    }
00476 
00477    record = allocate_dns_record(rr_type, query, data, size);
00478    if (!record) {
00479       return -1;
00480    }
00481 
00482    record->rr_type = rr_type;
00483    record->rr_class = rr_class;
00484    record->ttl = ttl;
00485    record->data_len = size;
00486    memcpy(record->data_ptr, data, size);
00487 
00488    AST_LIST_INSERT_TAIL(&query->result->records, record, list);
00489 
00490    return 0;
00491 }

void ast_dns_resolver_completed ( struct ast_dns_query query  ) 

Mark a DNS query as having been completed.

Parameters:
query The DNS query

Definition at line 507 of file dns_core.c.

References ast_dns_query_get_rr_type(), ast_dns_query::callback, ast_dns_query::result, and sort_result().

Referenced by naptr_thread(), resolution_thread(), srv_thread(), and unbound_resolver_callback().

00508 {
00509    sort_result(ast_dns_query_get_rr_type(query), query->result);
00510 
00511    query->callback(query);
00512 }

void* ast_dns_resolver_get_data ( const struct ast_dns_query query  ) 

Retrieve resolver specific data.

Parameters:
query The DNS query
Returns:
the resolver specific data
Note:
The reference count of the resolver data is NOT incremented on return

Definition at line 364 of file dns_core.c.

References ast_dns_query::resolver_data.

Referenced by AST_TEST_DEFINE(), and unbound_resolver_cancel().

00365 {
00366    return query->resolver_data;
00367 }

int ast_dns_resolver_register ( struct ast_dns_resolver resolver  ) 

Register a DNS resolver.

Parameters:
resolver A DNS resolver implementation
Return values:
0 success
-1 failure

Definition at line 522 of file dns_core.c.

References AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_log, ast_register_cleanup(), AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sched_context_create(), ast_sched_start_thread(), ast_strlen_zero, ast_verb, ast_dns_resolver::cancel, dns_shutdown(), LOG_ERROR, ast_dns_resolver::name, ast_dns_resolver::priority, and ast_dns_resolver::resolve.

Referenced by AST_TEST_DEFINE(), invalid_record_test(), load_module(), nominal_test(), and off_nominal_test().

00523 {
00524    struct ast_dns_resolver *iter;
00525    int inserted = 0;
00526 
00527    if (!resolver) {
00528       return -1;
00529    } else if (ast_strlen_zero(resolver->name)) {
00530       ast_log(LOG_ERROR, "Registration of DNS resolver failed as it does not have a name\n");
00531       return -1;
00532    } else if (!resolver->resolve) {
00533       ast_log(LOG_ERROR, "DNS resolver '%s' does not implement the resolve callback which is required\n",
00534          resolver->name);
00535       return -1;
00536    } else if (!resolver->cancel) {
00537       ast_log(LOG_ERROR, "DNS resolver '%s' does not implement the cancel callback which is required\n",
00538          resolver->name);
00539       return -1;
00540    }
00541 
00542    AST_RWLIST_WRLOCK(&resolvers);
00543 
00544    /* On the first registration of a resolver start a scheduler for recurring queries */
00545    if (AST_LIST_EMPTY(&resolvers) && !sched) {
00546       sched = ast_sched_context_create();
00547       if (!sched) {
00548          ast_log(LOG_ERROR, "DNS resolver '%s' could not be registered: Failed to create scheduler for recurring DNS queries\n",
00549             resolver->name);
00550          AST_RWLIST_UNLOCK(&resolvers);
00551          return -1;
00552       }
00553 
00554       if (ast_sched_start_thread(sched)) {
00555          ast_log(LOG_ERROR, "DNS resolver '%s' could not be registered: Failed to start thread for recurring DNS queries\n",
00556             resolver->name);
00557          dns_shutdown();
00558          AST_RWLIST_UNLOCK(&resolvers);
00559          return -1;
00560       }
00561 
00562       ast_register_cleanup(dns_shutdown);
00563    }
00564 
00565    AST_LIST_TRAVERSE(&resolvers, iter, next) {
00566       if (!strcmp(iter->name, resolver->name)) {
00567          ast_log(LOG_ERROR, "A DNS resolver with the name '%s' is already registered\n", resolver->name);
00568          AST_RWLIST_UNLOCK(&resolvers);
00569          return -1;
00570       }
00571    }
00572 
00573    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&resolvers, iter, next) {
00574       if (iter->priority > resolver->priority) {
00575          AST_RWLIST_INSERT_BEFORE_CURRENT(resolver, next);
00576          inserted = 1;
00577          break;
00578       }
00579    }
00580    AST_RWLIST_TRAVERSE_SAFE_END;
00581 
00582    if (!inserted) {
00583       AST_RWLIST_INSERT_TAIL(&resolvers, resolver, next);
00584    }
00585 
00586    AST_RWLIST_UNLOCK(&resolvers);
00587 
00588    ast_verb(2, "Registered DNS resolver '%s' with priority '%d'\n", resolver->name, resolver->priority);
00589 
00590    return 0;
00591 }

int ast_dns_resolver_set_data ( struct ast_dns_query query,
void *  data 
)

Set resolver specific data on a query.

Parameters:
query The DNS query
data The resolver specific data
Note:
The resolver data MUST be an ao2 object

This function increments the reference count of the resolver data, it does NOT steal

Once resolver specific data has been set it can not be changed

Return values:
0 success
-1 failure, resolver data is already set

Definition at line 353 of file dns_core.c.

References ao2_bump, and ast_dns_query::resolver_data.

Referenced by AST_TEST_DEFINE(), and unbound_resolver_resolve().

00354 {
00355    if (query->resolver_data) {
00356       return -1;
00357    }
00358 
00359    query->resolver_data = ao2_bump(data);
00360 
00361    return 0;
00362 }

int ast_dns_resolver_set_result ( struct ast_dns_query query,
unsigned int  secure,
unsigned int  bogus,
unsigned int  rcode,
const char *  canonical,
const char *  answer,
size_t  answer_size 
)

Set result information for a DNS query.

Parameters:
query The DNS query
result Whether the result is secured or not
bogus Whether the result is bogus or not
rcode Optional response code
canonical The canonical name
answer The raw DNS answer
answer_size The size of the raw DNS answer
Return values:
0 success
-1 failure

Definition at line 369 of file dns_core.c.

References ast_dns_result::answer, ast_dns_result::answer_size, ast_calloc, ast_debug, ast_dns_result_free(), ast_strlen_zero, ast_dns_result::bogus, ast_dns_result::buf, ast_dns_result::canonical, ast_dns_result::rcode, ast_dns_query::result, and ast_dns_result::secure.

Referenced by AST_TEST_DEFINE(), naptr_thread(), resolution_thread(), srv_thread(), and unbound_resolver_callback().

00371 {
00372    char *buf_ptr;
00373 
00374    if (secure && bogus) {
00375       ast_debug(2, "Query '%p': Could not set result information, it can not be both secure and bogus\n",
00376          query);
00377       return -1;
00378    }
00379 
00380    if (ast_strlen_zero(canonical)) {
00381       ast_debug(2, "Query '%p': Could not set result information since no canonical name was provided\n",
00382          query);
00383       return -1;
00384    }
00385 
00386    if (!answer || answer_size == 0) {
00387       ast_debug(2, "Query '%p': Could not set result information since no DNS answer was provided\n",
00388          query);
00389       return -1;
00390    }
00391 
00392    ast_dns_result_free(query->result);
00393 
00394    query->result = ast_calloc(1, sizeof(*query->result) + strlen(canonical) + 1 + answer_size);
00395    if (!query->result) {
00396       return -1;
00397    }
00398 
00399    query->result->secure = secure;
00400    query->result->bogus = bogus;
00401    query->result->rcode = rcode;
00402 
00403    buf_ptr = query->result->buf;
00404    strcpy(buf_ptr, canonical); /* SAFE */
00405    query->result->canonical = buf_ptr;
00406 
00407    buf_ptr += strlen(canonical) + 1;
00408    memcpy(buf_ptr, answer, answer_size); /* SAFE */
00409    query->result->answer = buf_ptr;
00410    query->result->answer_size = answer_size;
00411 
00412    return 0;
00413 }

void ast_dns_resolver_unregister ( struct ast_dns_resolver resolver  ) 

Unregister a DNS resolver.

Parameters:
resolver A DNS resolver implementation

Definition at line 593 of file dns_core.c.

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and ast_dns_resolver::name.

Referenced by AST_TEST_DEFINE(), invalid_record_test(), nominal_test(), and off_nominal_test().

00594 {
00595    struct ast_dns_resolver *iter;
00596 
00597    if (!resolver) {
00598       return;
00599    }
00600 
00601    AST_RWLIST_WRLOCK(&resolvers);
00602    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&resolvers, iter, next) {
00603       if (resolver == iter) {
00604          AST_RWLIST_REMOVE_CURRENT(next);
00605          break;
00606       }
00607    }
00608    AST_RWLIST_TRAVERSE_SAFE_END;
00609    AST_RWLIST_UNLOCK(&resolvers);
00610 
00611    ast_verb(2, "Unregistered DNS resolver '%s'\n", resolver->name);
00612 }


Generated on Thu Apr 16 06:30:43 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6