Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Functions
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. More...
 
void ast_dns_resolver_completed (struct ast_dns_query *query)
 Mark a DNS query as having been completed. More...
 
void * ast_dns_resolver_get_data (const struct ast_dns_query *query)
 Retrieve resolver specific data. More...
 
int ast_dns_resolver_register (struct ast_dns_resolver *resolver)
 Register a DNS resolver. More...
 
int ast_dns_resolver_set_data (struct ast_dns_query *query, void *data)
 Set resolver specific data on a query. More...
 
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. More...
 
void ast_dns_resolver_unregister (struct ast_dns_resolver *resolver)
 Unregister a DNS resolver. More...
 

Detailed Description

DNS Resolver API.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file dns_resolver.h.

Function Documentation

◆ ast_dns_resolver_add_record()

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
queryThe DNS query
rr_typeResource record type
rr_classResource record class
ttlTTL of the record
dataThe raw DNS record
sizeThe size of the raw DNS record
Return values
0success
-1failure

Definition at line 535 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_record::list, ast_dns_result::records, ast_dns_query::result, ast_dns_record::rr_class, ast_dns_record::rr_type, and ast_dns_record::ttl.

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

536 {
537  struct ast_dns_record *record;
538 
539  if (rr_type < 0) {
540  ast_debug(2, "Query '%p': Could not add record, invalid resource record type '%d'\n",
541  query, rr_type);
542  return -1;
543  } else if (rr_type > 65536) {
544  ast_debug(2, "Query '%p': Could not add record, resource record type '%d' exceeds maximum\n",
545  query, rr_type);
546  return -1;
547  } else if (rr_class < 0) {
548  ast_debug(2, "Query '%p': Could not add record, invalid resource record class '%d'\n",
549  query, rr_class);
550  return -1;
551  } else if (rr_class > 65536) {
552  ast_debug(2, "Query '%p': Could not add record, resource record class '%d' exceeds maximum\n",
553  query, rr_class);
554  return -1;
555  } else if (ttl < 0) {
556  ast_debug(2, "Query '%p': Could not add record, invalid TTL '%d'\n",
557  query, ttl);
558  return -1;
559  } else if (!data || !size) {
560  ast_debug(2, "Query '%p': Could not add record, no data specified\n",
561  query);
562  return -1;
563  } else if (!query->result) {
564  ast_debug(2, "Query '%p': No result was set on the query, thus records can not be added\n",
565  query);
566  return -1;
567  }
568 
569  record = allocate_dns_record(rr_type, query, data, size);
570  if (!record) {
571  return -1;
572  }
573 
574  record->rr_type = rr_type;
575  record->rr_class = rr_class;
576  record->ttl = ttl;
577  record->data_len = size;
578  memcpy(record->data_ptr, data, size);
579 
580  AST_LIST_INSERT_TAIL(&query->result->records, record, list);
581 
582  return 0;
583 }
char * data_ptr
pointer to record-specific data.
Definition: dns_internal.h:58
For AST_LIST.
Definition: dns_internal.h:39
struct ast_dns_record::@253 list
Linked list information.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static struct ast_dns_record * allocate_dns_record(unsigned int rr_type, struct ast_dns_query *query, const char *data, const size_t size)
Definition: dns_core.c:524
char data[0]
The raw DNS record.
Definition: dns_internal.h:60
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
size_t data_len
The size of the raw DNS record.
Definition: dns_internal.h:47
struct ast_dns_result * result
Result of the DNS query.
Definition: dns_internal.h:147
int ttl
Time-to-live of the record.
Definition: dns_internal.h:45
struct ast_dns_result::dns_records records
int rr_type
Resource record type.
Definition: dns_internal.h:41
int rr_class
Resource record class.
Definition: dns_internal.h:43

◆ ast_dns_resolver_completed()

void ast_dns_resolver_completed ( struct ast_dns_query query)

Mark a DNS query as having been completed.

Parameters
queryThe DNS query

Definition at line 599 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 dns_system_resolver_process_query(), naptr_thread(), resolution_thread(), srv_thread(), and unbound_resolver_callback().

600 {
602 
603  query->callback(query);
604 }
struct ast_dns_result * result
Result of the DNS query.
Definition: dns_internal.h:147
ast_dns_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:139
int ast_dns_query_get_rr_type(const struct ast_dns_query *query)
Get the record resource type of a DNS query.
Definition: dns_core.c:62
static void sort_result(int rr_type, struct ast_dns_result *result)
Definition: dns_core.c:592

◆ ast_dns_resolver_get_data()

void* ast_dns_resolver_get_data ( const struct ast_dns_query query)

Retrieve resolver specific data.

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

Definition at line 451 of file dns_core.c.

References ast_dns_query::resolver_data.

Referenced by AST_TEST_DEFINE(), and unbound_resolver_cancel().

452 {
453  return query->resolver_data;
454 }
void * resolver_data
Resolver-specific data.
Definition: dns_internal.h:145

◆ ast_dns_resolver_register()

int ast_dns_resolver_register ( struct ast_dns_resolver resolver)

Register a DNS resolver.

Parameters
resolverA DNS resolver implementation
Return values
0success
-1failure

Definition at line 630 of file dns_core.c.

References AST_LIST_TRAVERSE, ast_log, 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_strlen_zero, ast_verb, ast_dns_resolver::cancel, LOG_ERROR, ast_dns_resolver::name, ast_dns_resolver::priority, and ast_dns_resolver::resolve.

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

631 {
632  struct ast_dns_resolver *iter;
633  int inserted = 0;
634 
635  if (!resolver) {
636  return -1;
637  } else if (ast_strlen_zero(resolver->name)) {
638  ast_log(LOG_ERROR, "Registration of DNS resolver failed as it does not have a name\n");
639  return -1;
640  } else if (!resolver->resolve) {
641  ast_log(LOG_ERROR, "DNS resolver '%s' does not implement the resolve callback which is required\n",
642  resolver->name);
643  return -1;
644  } else if (!resolver->cancel) {
645  ast_log(LOG_ERROR, "DNS resolver '%s' does not implement the cancel callback which is required\n",
646  resolver->name);
647  return -1;
648  }
649 
651 
652  AST_LIST_TRAVERSE(&resolvers, iter, next) {
653  if (!strcmp(iter->name, resolver->name)) {
654  ast_log(LOG_ERROR, "A DNS resolver with the name '%s' is already registered\n", resolver->name);
656  return -1;
657  }
658  }
659 
661  if (iter->priority > resolver->priority) {
662  AST_RWLIST_INSERT_BEFORE_CURRENT(resolver, next);
663  inserted = 1;
664  break;
665  }
666  }
668 
669  if (!inserted) {
670  AST_RWLIST_INSERT_TAIL(&resolvers, resolver, next);
671  }
672 
674 
675  ast_verb(2, "Registered DNS resolver '%s' with priority '%d'\n", resolver->name, resolver->priority);
676 
677  return 0;
678 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:609
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
#define LOG_ERROR
Definition: logger.h:285
int(* resolve)(struct ast_dns_query *query)
Perform resolution of a DNS query.
Definition: dns_resolver.h:45
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
DNS resolver implementation.
Definition: dns_resolver.h:32
unsigned int priority
Priority for this resolver if multiple exist, lower being higher priority.
Definition: dns_resolver.h:37
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
int(* cancel)(struct ast_dns_query *query)
Cancel resolution of a DNS query.
Definition: dns_resolver.h:48

◆ ast_dns_resolver_set_data()

int ast_dns_resolver_set_data ( struct ast_dns_query query,
void *  data 
)

Set resolver specific data on a query.

Parameters
queryThe DNS query
dataThe 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
0success
-1failure, resolver data is already set

Definition at line 440 of file dns_core.c.

References ao2_bump, and ast_dns_query::resolver_data.

Referenced by AST_TEST_DEFINE(), and unbound_resolver_resolve().

441 {
442  if (query->resolver_data) {
443  return -1;
444  }
445 
446  query->resolver_data = ao2_bump(data);
447 
448  return 0;
449 }
#define ao2_bump(obj)
Definition: astobj2.h:491
void * resolver_data
Resolver-specific data.
Definition: dns_internal.h:145

◆ ast_dns_resolver_set_result()

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
queryThe DNS query
resultWhether the result is secured or not
bogusWhether the result is bogus or not
rcodeOptional response code
canonicalThe canonical name
answerThe raw DNS answer
answer_sizeThe size of the raw DNS answer

Zero-sized and NULL answers are permitted by this function. This may be necessary if the query fails at an early stage and no actual DNS response has been received from a DNS server.

Return values
0success
-1failure

Definition at line 456 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(), dns_system_resolver_set_response(), naptr_thread(), resolution_thread(), srv_thread(), and unbound_resolver_callback().

458 {
459  char *buf_ptr;
460 
461  if (secure && bogus) {
462  ast_debug(2, "Query '%p': Could not set result information, it can not be both secure and bogus\n",
463  query);
464  return -1;
465  }
466 
467  if (ast_strlen_zero(canonical)) {
468  ast_debug(2, "Query '%p': Could not set result information since no canonical name was provided\n",
469  query);
470  return -1;
471  }
472 
473  if (!answer) {
474  answer = "";
475  answer_size = 0;
476  ast_debug(2, "Query '%p': Assuming zero-sized answer on NULL input\n", query);
477  }
478 
479  ast_dns_result_free(query->result);
480 
481  query->result = ast_calloc(1, sizeof(*query->result) + strlen(canonical) + 1 + answer_size);
482  if (!query->result) {
483  return -1;
484  }
485 
486  query->result->secure = secure;
487  query->result->bogus = bogus;
488  query->result->rcode = rcode;
489 
490  buf_ptr = query->result->buf;
491  strcpy(buf_ptr, canonical); /* SAFE */
492  query->result->canonical = buf_ptr;
493 
494  buf_ptr += strlen(canonical) + 1;
495  memcpy(buf_ptr, answer, answer_size); /* SAFE */
496  query->result->answer = buf_ptr;
497  query->result->answer_size = answer_size;
498 
499  return 0;
500 }
unsigned int rcode
Optional rcode, set if an error occurred.
Definition: dns_internal.h:123
unsigned int secure
Whether the result is secure.
Definition: dns_internal.h:119
const char * canonical
The canonical name.
Definition: dns_internal.h:127
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
static int answer(void *data)
Definition: chan_pjsip.c:682
struct ast_dns_result * result
Result of the DNS query.
Definition: dns_internal.h:147
char buf[0]
Buffer for dynamic data.
Definition: dns_internal.h:133
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
unsigned int bogus
Whether the result is bogus.
Definition: dns_internal.h:121
size_t answer_size
The size of the raw DNS answer.
Definition: dns_internal.h:131
const char * answer
The raw DNS answer.
Definition: dns_internal.h:129

◆ ast_dns_resolver_unregister()

void ast_dns_resolver_unregister ( struct ast_dns_resolver resolver)

Unregister a DNS resolver.

Parameters
resolverA DNS resolver implementation

Definition at line 680 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(), dns_system_resolver_destroy(), invalid_record_test(), nominal_test(), off_nominal_test(), and query_set_test().

681 {
682  struct ast_dns_resolver *iter;
683 
684  if (!resolver) {
685  return;
686  }
687 
690  if (resolver == iter) {
692  break;
693  }
694  }
697 
698  ast_verb(2, "Unregistered DNS resolver '%s'\n", resolver->name);
699 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
#define ast_verb(level,...)
Definition: logger.h:463
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
DNS resolver implementation.
Definition: dns_resolver.h:32
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616