Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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.

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}
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
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
struct ast_dns_result * result
Result of the DNS query.
Definition: dns_internal.h:147
For AST_LIST.
Definition: dns_internal.h:39
int ttl
Time-to-live of the record.
Definition: dns_internal.h:45
char data[0]
The raw DNS record.
Definition: dns_internal.h:60
struct ast_dns_record::@215 list
Linked list information.
int rr_class
Resource record class.
Definition: dns_internal.h:43
int rr_type
Resource record type.
Definition: dns_internal.h:41
size_t data_len
The size of the raw DNS record.
Definition: dns_internal.h:47
char * data_ptr
pointer to record-specific data.
Definition: dns_internal.h:58
struct ast_dns_result::dns_records records

References allocate_dns_record(), ast_debug, AST_LIST_INSERT_TAIL, ast_dns_record::data, 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().

◆ 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.

600{
602
603 query->callback(query);
604}
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_resolve_callback callback
Callback to invoke upon completion.
Definition: dns_internal.h:139

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().

◆ 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.

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

References ast_dns_query::resolver_data.

Referenced by AST_TEST_DEFINE(), and unbound_resolver_cancel().

◆ 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.

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(5, "Registered DNS resolver '%s' with priority '%d'\n", resolver->name, resolver->priority);
676
677 return 0;
678}
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
#define ast_verb(level,...)
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:610
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
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
int(* cancel)(struct ast_dns_query *query)
Cancel resolution of a DNS query.
Definition: dns_resolver.h:48
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
int(* resolve)(struct ast_dns_query *query)
Perform resolution of a DNS query.
Definition: dns_resolver.h:45

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().

◆ 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.

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)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480

References ao2_bump, and ast_dns_query::resolver_data.

Referenced by AST_TEST_DEFINE(), and unbound_resolver_resolve().

◆ 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
secureWhether 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.

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
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}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static int answer(void *data)
Definition: chan_pjsip.c:683
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
char buf[0]
Buffer for dynamic data.
Definition: dns_internal.h:133
const char * canonical
The canonical name.
Definition: dns_internal.h:127
size_t answer_size
The size of the raw DNS answer.
Definition: dns_internal.h:131
unsigned int bogus
Whether the result is bogus.
Definition: dns_internal.h:121
unsigned int secure
Whether the result is secure.
Definition: dns_internal.h:119
const char * answer
The raw DNS answer.
Definition: dns_internal.h:129
unsigned int rcode
Optional rcode, set if an error occurred.
Definition: dns_internal.h:123

References answer(), 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().

◆ 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.

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(5, "Unregistered DNS resolver '%s'\n", resolver->name);
699}
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570

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().