Asterisk - The Open Source Telephony Project GIT-master-4c84066
Loading...
Searching...
No Matches
Data Structures | Typedefs | Functions | Variables
dns_core.c File Reference

Core DNS Functionality. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/sched.h"
#include "asterisk/dns_core.h"
#include "asterisk/dns_srv.h"
#include "asterisk/dns_tlsa.h"
#include "asterisk/dns_recurring.h"
#include "asterisk/dns_resolver.h"
#include "asterisk/dns_internal.h"
#include "asterisk/netsock2.h"
#include <netinet/in.h>
#include <arpa/nameser.h>
Include dependency graph for dns_core.c:

Go to the source code of this file.

Data Structures

struct  dns_synchronous_resolve
 Structure used for signaling back for synchronous resolution completion. More...
 
struct  resolvers
 

Typedefs

typedef struct ast_dns_record *(* dns_alloc_fn) (struct ast_dns_query *query, const char *data, const size_t size)
 
typedef void(* dns_sort_fn) (struct ast_dns_result *result)
 

Functions

static struct ast_dns_recordallocate_dns_record (unsigned int rr_type, struct ast_dns_query *query, const char *data, const size_t size)
 
struct ast_sched_contextast_dns_get_sched (void)
 Retrieve the DNS scheduler context.
 
void * ast_dns_query_get_data (const struct ast_dns_query *query)
 Get the user specific data of a DNS query.
 
const char * ast_dns_query_get_name (const struct ast_dns_query *query)
 Get the name queried in a DNS query.
 
struct ast_dns_resultast_dns_query_get_result (const struct ast_dns_query *query)
 Get the result information for a DNS query.
 
int ast_dns_query_get_rr_class (const struct ast_dns_query *query)
 Get the record resource class of a DNS query.
 
int ast_dns_query_get_rr_type (const struct ast_dns_query *query)
 Get the record resource type of a DNS query.
 
const char * ast_dns_record_get_data (const struct ast_dns_record *record)
 Retrieve the raw DNS record.
 
size_t ast_dns_record_get_data_size (const struct ast_dns_record *record)
 Retrieve the size of the raw DNS record.
 
const struct ast_dns_recordast_dns_record_get_next (const struct ast_dns_record *record)
 Get the next DNS record.
 
int ast_dns_record_get_rr_class (const struct ast_dns_record *record)
 Get the resource record class of a DNS record.
 
int ast_dns_record_get_rr_type (const struct ast_dns_record *record)
 Get the resource record type of a DNS record.
 
int ast_dns_record_get_ttl (const struct ast_dns_record *record)
 Get the TTL of a DNS record.
 
int ast_dns_resolve (const char *name, int rr_type, int rr_class, struct ast_dns_result **result)
 Synchronously resolve a DNS query.
 
struct ast_dns_query_activeast_dns_resolve_async (const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
 Asynchronously resolve a DNS query.
 
int ast_dns_resolve_cancel (struct ast_dns_query_active *active)
 Cancel an asynchronous DNS resolution.
 
int ast_dns_resolve_ipv6_and_ipv4 (struct ast_sockaddr *address, const char *host, const char *port)
 Synchronously resolves host to an AAAA or A 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.
 
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.
 
void ast_dns_result_free (struct ast_dns_result *result)
 Free the DNS result information.
 
const char * ast_dns_result_get_answer (const struct ast_dns_result *result)
 Get the raw DNS answer from a DNS result.
 
unsigned int ast_dns_result_get_bogus (const struct ast_dns_result *result)
 Get whether the result is bogus or not.
 
const char * ast_dns_result_get_canonical (const struct ast_dns_result *result)
 Get the canonical name of the result.
 
int ast_dns_result_get_lowest_ttl (const struct ast_dns_result *result)
 Retrieve the lowest TTL from a result.
 
unsigned int ast_dns_result_get_rcode (const struct ast_dns_result *result)
 Get the error rcode of a DN result.
 
const struct ast_dns_recordast_dns_result_get_records (const struct ast_dns_result *result)
 Get the first record of a DNS Result.
 
unsigned int ast_dns_result_get_secure (const struct ast_dns_result *result)
 Get whether the result is secure or not.
 
int dns_core_init (void)
 
char * dns_find_record (const char *record, size_t record_size, const char *response, size_t response_size)
 Find the location of a DNS record within the entire DNS answer.
 
int dns_parse_short (unsigned char *cur, uint16_t *val)
 Parse a 16-bit unsigned value from a DNS record.
 
int dns_parse_string (char *cur, uint8_t *size, char **val)
 Parse a DNS string from a DNS record.
 
static void dns_query_active_destroy (void *data)
 Destructor for an active DNS query.
 
struct ast_dns_querydns_query_alloc (const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
 Allocate a DNS query (but do not start resolution)
 
static void dns_query_destroy (void *data)
 Destructor for a DNS query.
 
static void dns_shutdown (void)
 
static void dns_synchronous_resolve_callback (const struct ast_dns_query *query)
 Callback used to implement synchronous resolution.
 
static void dns_synchronous_resolve_destroy (void *data)
 Destructor for synchronous resolution structure.
 
static struct ast_dns_recordgeneric_record_alloc (struct ast_dns_query *query, const char *data, const size_t size)
 
static void sort_result (int rr_type, struct ast_dns_result *result)
 

Variables

static dns_alloc_fn dns_alloc_table []
 
static dns_sort_fn dns_sort_table []
 
struct resolvers resolvers = AST_RWLIST_HEAD_INIT_VALUE
 
static struct ast_sched_contextsched
 

Detailed Description

Core DNS Functionality.

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

Definition in file dns_core.c.

Typedef Documentation

◆ dns_alloc_fn

typedef struct ast_dns_record *(* dns_alloc_fn) (struct ast_dns_query *query, const char *data, const size_t size)

Definition at line 503 of file dns_core.c.

◆ dns_sort_fn

typedef void(* dns_sort_fn) (struct ast_dns_result *result)

Definition at line 586 of file dns_core.c.

Function Documentation

◆ allocate_dns_record()

static struct ast_dns_record * allocate_dns_record ( unsigned int  rr_type,
struct ast_dns_query query,
const char *  data,
const size_t  size 
)
static

Definition at line 525 of file dns_core.c.

526{
528
529 if (rr_type < ARRAY_LEN(dns_alloc_table) && dns_alloc_table[rr_type]) {
530 allocator = dns_alloc_table[rr_type];
531 }
532
533 return allocator(query, data, size);
534}
struct ast_dns_record *(* dns_alloc_fn)(struct ast_dns_query *query, const char *data, const size_t size)
Definition dns_core.c:517
static struct ast_dns_record * generic_record_alloc(struct ast_dns_query *query, const char *data, const size_t size)
Definition dns_core.c:503
static dns_alloc_fn dns_alloc_table[]
Definition dns_core.c:519
#define ARRAY_LEN(a)
Definition utils.h:706

References ARRAY_LEN, ast_dns_record::data, dns_alloc_table, generic_record_alloc(), and ast_dns_record::rr_type.

Referenced by ast_dns_resolver_add_record().

◆ ast_dns_get_sched()

struct ast_sched_context * ast_dns_get_sched ( void  )

Retrieve the DNS scheduler context.

Returns
scheduler context

Definition at line 52 of file dns_core.c.

53{
54 return sched;
55}
static struct ast_sched_context * sched
Definition dns_core.c:50

References sched.

Referenced by ast_dns_resolve_recurring(), ast_dns_resolve_recurring_cancel(), and dns_query_recurring_resolution_callback().

◆ ast_dns_query_get_data()

void * ast_dns_query_get_data ( const struct ast_dns_query query)

Get the user specific data of a DNS query.

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

Definition at line 72 of file dns_core.c.

73{
74 return query->user_data;
75}
void * user_data
User-specific data.

References ast_dns_query::user_data.

Referenced by async_callback(), async_callback(), dns_query_recurring_resolution_callback(), dns_query_set_callback(), dns_synchronous_resolve_callback(), query_set_cancel(), query_set_resolve(), recurring_cancel(), recurring_resolve(), resolution_thread(), and resolution_thread().

◆ ast_dns_query_get_name()

const char * ast_dns_query_get_name ( const struct ast_dns_query query)

Get the name queried in a DNS query.

Parameters
queryThe DNS query
Returns
the name queried

Definition at line 57 of file dns_core.c.

58{
59 return query->name;
60}
char name[0]
The name of what is being resolved.

References ast_dns_query::name.

Referenced by dns_query_recurring_resolution_callback(), dns_system_resolver_process_query(), dns_system_resolver_resolve(), dns_system_resolver_set_response(), query_set_test(), unbound_resolver_callback(), and unbound_resolver_resolve().

◆ ast_dns_query_get_result()

struct ast_dns_result * ast_dns_query_get_result ( const struct ast_dns_query query)

Get the result information for a DNS query.

Parameters
queryThe DNS query
Returns
the DNS result information
Note
The result is NOT ao2 allocated

Definition at line 77 of file dns_core.c.

78{
79 return query->result;
80}
struct ast_dns_result * result
Result of the DNS query.

References ast_dns_query::result.

Referenced by ast_dns_resolve_ipv6_and_ipv4(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), dns_query_recurring_resolution_callback(), dns_system_resolver_set_response(), and test_results().

◆ ast_dns_query_get_rr_class()

int ast_dns_query_get_rr_class ( const struct ast_dns_query query)

Get the record resource class of a DNS query.

Parameters
queryThe DNS query
Returns
the record resource class

Definition at line 67 of file dns_core.c.

68{
69 return query->rr_class;
70}
int rr_class
Resource record class.

References ast_dns_query::rr_class.

Referenced by dns_query_recurring_resolution_callback(), dns_system_resolver_add_record(), dns_system_resolver_process_query(), query_set_test(), and unbound_resolver_resolve().

◆ ast_dns_query_get_rr_type()

int ast_dns_query_get_rr_type ( const struct ast_dns_query query)

Get the record resource type of a DNS query.

Parameters
queryThe DNS query
Returns
the record resource type

Definition at line 62 of file dns_core.c.

63{
64 return query->rr_type;
65}
int rr_type
Resource record type.

References ast_dns_query::rr_type.

Referenced by ast_dns_resolver_completed(), dns_query_recurring_resolution_callback(), dns_system_resolver_add_record(), dns_system_resolver_process_query(), query_set_test(), and unbound_resolver_resolve().

◆ ast_dns_record_get_data()

const char * ast_dns_record_get_data ( const struct ast_dns_record record)

Retrieve the raw DNS record.

Parameters
recordThe DNS record
Returns
the raw DNS record

Definition at line 160 of file dns_core.c.

161{
162 return record->data_ptr;
163}
char * data_ptr
pointer to record-specific data.

References ast_dns_record::data_ptr.

Referenced by ast_dns_resolve_ipv6_and_ipv4(), ast_dns_txt_get_strings(), and test_record().

◆ ast_dns_record_get_data_size()

size_t ast_dns_record_get_data_size ( const struct ast_dns_record record)

Retrieve the size of the raw DNS record.

Parameters
recordThe DNS record
Returns
the size of the raw DNS record

Definition at line 165 of file dns_core.c.

166{
167 return record->data_len;
168}
size_t data_len
The size of the raw DNS record.

References ast_dns_record::data_len.

Referenced by ast_dns_resolve_ipv6_and_ipv4(), and ast_dns_txt_get_strings().

◆ ast_dns_record_get_next()

const struct ast_dns_record * ast_dns_record_get_next ( const struct ast_dns_record record)

Get the next DNS record.

Parameters
recordThe current DNS record
Returns
the next DNS record

Definition at line 170 of file dns_core.c.

171{
172 return AST_LIST_NEXT(record, list);
173}
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.

References AST_LIST_NEXT, and ast_dns_record::list.

Referenced by ast_dns_resolve_ipv6_and_ipv4(), ast_dns_result_get_lowest_ttl(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and nominal_test().

◆ ast_dns_record_get_rr_class()

int ast_dns_record_get_rr_class ( const struct ast_dns_record record)

Get the resource record class of a DNS record.

Parameters
recordThe DNS record
Returns
the resource record class

Definition at line 150 of file dns_core.c.

151{
152 return record->rr_class;
153}
int rr_class
Resource record class.

References ast_dns_record::rr_class.

Referenced by test_record().

◆ ast_dns_record_get_rr_type()

int ast_dns_record_get_rr_type ( const struct ast_dns_record record)

◆ ast_dns_record_get_ttl()

int ast_dns_record_get_ttl ( const struct ast_dns_record record)

Get the TTL of a DNS record.

Parameters
recordThe DNS record
Returns
the TTL

Definition at line 155 of file dns_core.c.

156{
157 return record->ttl;
158}
int ttl
Time-to-live of the record.

References ast_dns_record::ttl.

Referenced by ast_dns_result_get_lowest_ttl(), and test_record().

◆ ast_dns_resolve()

int ast_dns_resolve ( const char *  name,
int  rr_type,
int  rr_class,
struct ast_dns_result **  result 
)

Synchronously resolve a DNS query.

Parameters
nameThe name of what to resolve
rr_typeResource record type
rr_classResource record class
resultA pointer to hold the DNS result
Return values
0success - query was completed and result is available
-1failure

Definition at line 315 of file dns_core.c.

316{
317 struct dns_synchronous_resolve *synchronous;
318 struct ast_dns_query_active *active;
319
320 if (ast_strlen_zero(name)) {
321 ast_log(LOG_WARNING, "Could not perform synchronous resolution, no name provided\n");
322 return -1;
323 } else if (rr_type > 65536) {
324 ast_log(LOG_WARNING, "Could not perform synchronous resolution of '%s', resource record type '%d' exceeds maximum\n",
325 name, rr_type);
326 return -1;
327 } else if (rr_type < 0) {
328 ast_log(LOG_WARNING, "Could not perform synchronous resolution of '%s', invalid resource record type '%d'\n",
329 name, rr_type);
330 return -1;
331 } else if (rr_class > 65536) {
332 ast_log(LOG_WARNING, "Could not perform synchronous resolution of '%s', resource record class '%d' exceeds maximum\n",
333 name, rr_class);
334 return -1;
335 } else if (rr_class < 0) {
336 ast_log(LOG_WARNING, "Could not perform synchronous resolution of '%s', invalid resource class '%d'\n",
337 name, rr_class);
338 return -1;
339 } else if (!result) {
340 ast_log(LOG_WARNING, "Could not perform synchronous resolution of '%s', no result pointer provided for storing results\n",
341 name);
342 return -1;
343 }
344
346 if (!synchronous) {
347 return -1;
348 }
349
350 ast_mutex_init(&synchronous->lock);
351 ast_cond_init(&synchronous->cond, NULL);
352
353 active = ast_dns_resolve_async(name, rr_type, rr_class, dns_synchronous_resolve_callback, synchronous);
354 if (active) {
355 /* Wait for resolution to complete */
356 ast_mutex_lock(&synchronous->lock);
357 while (!synchronous->completed) {
358 ast_cond_wait(&synchronous->cond, &synchronous->lock);
359 }
360 ast_mutex_unlock(&synchronous->lock);
361 ao2_ref(active, -1);
362 }
363
364 *result = synchronous->result;
365 ao2_ref(synchronous, -1);
366
367 return *result ? 0 : -1;
368}
#define ast_log
Definition astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
static PGresult * result
Definition cel_pgsql.c:84
static void dns_synchronous_resolve_callback(const struct ast_dns_query *query)
Callback used to implement synchronous resolution.
Definition dns_core.c:302
struct ast_dns_query_active * ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
Asynchronously resolve a DNS query.
Definition dns_core.c:247
static void dns_synchronous_resolve_destroy(void *data)
Destructor for synchronous resolution structure.
Definition dns_core.c:291
static const char name[]
Definition format_mp3.c:68
#define LOG_WARNING
#define ast_cond_wait(cond, mutex)
Definition lock.h:212
#define ast_cond_init(cond, attr)
Definition lock.h:208
#define ast_mutex_init(pmutex)
Definition lock.h:193
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196
#define NULL
Definition resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
An active DNS query.
Structure used for signaling back for synchronous resolution completion.
Definition dns_core.c:279
ast_cond_t cond
Condition used for signaling.
Definition dns_core.c:283
struct ast_dns_result * result
The result from the query.
Definition dns_core.c:287
ast_mutex_t lock
Lock used for signaling.
Definition dns_core.c:281
unsigned int completed
Whether the query has completed.
Definition dns_core.c:285

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_cond_init, ast_cond_wait, ast_dns_resolve_async(), ast_log, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), dns_synchronous_resolve::completed, dns_synchronous_resolve::cond, dns_synchronous_resolve_callback(), dns_synchronous_resolve_destroy(), dns_synchronous_resolve::lock, LOG_WARNING, name, NULL, result, and dns_synchronous_resolve::result.

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

◆ ast_dns_resolve_async()

struct ast_dns_query_active * ast_dns_resolve_async ( const char *  name,
int  rr_type,
int  rr_class,
ast_dns_resolve_callback  callback,
void *  data 
)

Asynchronously resolve a DNS query.

Parameters
nameThe name of what to resolve
rr_typeResource record type
rr_classResource record class
callbackThe callback to invoke upon completion
dataUser data to make available on the query
Return values
non-NULLsuccess - query has been sent for resolution
NULLfailure
Note
The result passed to the callback does not need to be freed
The user data MUST be an ao2 object
This function increments the reference count of the user data, it does NOT steal
The active query must be released upon completion or cancellation using ao2_ref

Definition at line 247 of file dns_core.c.

248{
249 struct ast_dns_query_active *active;
250
252 if (!active) {
253 return NULL;
254 }
255
256 active->query = dns_query_alloc(name, rr_type, rr_class, callback, data);
257 if (!active->query) {
258 ao2_ref(active, -1);
259 return NULL;
260 }
261 ast_debug(2, "Calling %s resolver for name: %s class: %d type: %d", active->query->resolver->name,
262 name, rr_class, rr_type);
263 if (active->query->resolver->resolve(active->query)) {
264 ast_log(LOG_ERROR, "Resolver '%s' returned an error when resolving '%s' of class '%d' and type '%d'\n",
265 active->query->resolver->name, name, rr_class, rr_type);
266 ao2_ref(active, -1);
267 return NULL;
268 }
269
270 return active;
271}
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
struct ast_dns_query * dns_query_alloc(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
Allocate a DNS query (but do not start resolution)
Definition dns_core.c:193
static void dns_query_active_destroy(void *data)
Destructor for an active DNS query.
Definition dns_core.c:176
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
struct ast_dns_query * query
The underlying DNS query.
struct ast_dns_resolver * resolver
The resolver in use for this query.
const char * name
The name of the resolver implementation.
int(* resolve)(struct ast_dns_query *query)
Perform resolution of a DNS query.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_debug, ast_log, callback(), dns_query_active_destroy(), dns_query_alloc(), LOG_ERROR, name, ast_dns_resolver::name, NULL, ast_dns_query_active::query, ast_dns_resolver::resolve, and ast_dns_query::resolver.

Referenced by ast_dns_resolve(), ast_dns_resolve_recurring(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and dns_query_recurring_scheduled_callback().

◆ ast_dns_resolve_cancel()

int ast_dns_resolve_cancel ( struct ast_dns_query_active active)

Cancel an asynchronous DNS resolution.

Parameters
activeThe active DNS query returned from ast_dns_resolve_async
Return values
0success
-1failure
Note
If successfully cancelled the callback will not be invoked

Definition at line 273 of file dns_core.c.

274{
275 return active->query->resolver->cancel(active->query);
276}
int(* cancel)(struct ast_dns_query *query)
Cancel resolution of a DNS query.

References ast_dns_resolver::cancel, ast_dns_query_active::query, and ast_dns_query::resolver.

Referenced by ast_dns_resolve_recurring_cancel(), and AST_TEST_DEFINE().

◆ ast_dns_resolve_ipv6_and_ipv4()

int ast_dns_resolve_ipv6_and_ipv4 ( struct ast_sockaddr address,
const char *  host,
const char *  port 
)

Synchronously resolves host to an AAAA or A record.

Since
16.6.0
Parameters
addressA pointer to an ast_sockaddr structure to receive the IPv6 or IPv4 address
hostThe hostname to resolve
port(optional) A port to parse into the final ast_sockaddr structure
Return values
0success - query was completed and result is available
-1failure
Note
This function makes parallel queries for both AAAA and A records for the host. The first returned AAAA record (if any) is used and if not found, the first A record is used.
Warning
This function is synchronous and will block until records are returned or an error occurs.

Definition at line 370 of file dns_core.c.

371{
373 int i;
374 int rc;
375
376 if (!queries) {
377 ast_log(LOG_ERROR, "Couldn't allocate DNS query structure\n");
378 return -1;
379 }
380 rc = ast_dns_query_set_add(queries, host, ns_t_aaaa, ns_c_in);
381 if (rc != 0) {
382 ast_log(LOG_ERROR, "Couldn't add 'AAAA' DNS query for '%s'\n", host);
383 return -1;
384 }
385 rc = ast_dns_query_set_add(queries, host, ns_t_a, ns_c_in);
386 if (rc != 0) {
387 ast_log(LOG_ERROR, "Couldn't add 'A' DNS query for '%s'\n", host);
388 return -1;
389 }
391 if (rc != 0) {
392 ast_log(LOG_ERROR, "Query set resolve failure for '%s'\n", host);
393 return -1;
394 }
395 for (i = 0; i < ast_dns_query_set_num_queries(queries); ++i) {
396 struct ast_dns_query *query = ast_dns_query_set_get(queries, i);
398 const struct ast_dns_record *record;
399 in_port_t in_port = 0;
400
401 if (!ast_strlen_zero(port)) {
402 in_port = htons(atoi(port));
403 }
404
405 for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {
406 size_t data_size = ast_dns_record_get_data_size(record);
407 const unsigned char *data = (unsigned char *)ast_dns_record_get_data(record);
409
410 if (rr_type == ns_t_aaaa && data_size == 16) {
411 struct sockaddr_in6 sin6 = { 0, };
412
413 sin6.sin6_port = in_port;
414 memcpy(&sin6.sin6_addr, data, data_size);
415 sin6.sin6_family = AF_INET6;
416 memcpy(&address->ss, &sin6, sizeof(sin6));
417 address->len = sizeof(sin6);
418
419 return 0;
420 } else if (rr_type == ns_t_a && data_size == 4) {
421 struct sockaddr_in sin4 = { 0, };
422
423 sin4.sin_port = in_port;
424 memcpy(&sin4.sin_addr, data, data_size);
425 sin4.sin_family = AF_INET;
426 memcpy(&address->ss, &sin4, sizeof(sin4));
427 address->len = sizeof(sin4);
428
429 return 0;
430 } else {
431 ast_debug(3, "Unrecognized rr_type '%u' or data_size '%zu' from DNS query for host '%s'\n",
432 rr_type, data_size, host);
433 continue;
434 }
435 }
436 }
437
438 return -1;
439}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
const struct ast_dns_record * ast_dns_record_get_next(const struct ast_dns_record *record)
Get the next DNS record.
Definition dns_core.c:170
const char * ast_dns_record_get_data(const struct ast_dns_record *record)
Retrieve the raw DNS record.
Definition dns_core.c:160
const struct ast_dns_record * ast_dns_result_get_records(const struct ast_dns_result *result)
Get the first record of a DNS Result.
Definition dns_core.c:102
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition dns_core.c:77
int ast_dns_record_get_rr_type(const struct ast_dns_record *record)
Get the resource record type of a DNS record.
Definition dns_core.c:145
size_t ast_dns_record_get_data_size(const struct ast_dns_record *record)
Retrieve the size of the raw DNS record.
Definition dns_core.c:165
struct ast_dns_query * ast_dns_query_set_get(const struct ast_dns_query_set *query_set, unsigned int index)
Retrieve a query from a query set.
struct ast_dns_query_set * ast_dns_query_set_create(void)
Create a query set to hold queries.
size_t ast_dns_query_set_num_queries(const struct ast_dns_query_set *query_set)
Retrieve the number of queries in a query set.
int ast_dns_query_set_add(struct ast_dns_query_set *query_set, const char *name, int rr_type, int rr_class)
Add a query to a query set.
int ast_query_set_resolve(struct ast_dns_query_set *query_set)
Synchronously resolve queries in a query set.
char * address
Definition f2c.h:59
A set of DNS queries.
A DNS query.
For AST_LIST.
char data[0]
The raw DNS record.
The result of a DNS query.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References ao2_cleanup, ast_debug, ast_dns_query_get_result(), ast_dns_query_set_add(), ast_dns_query_set_create(), ast_dns_query_set_get(), ast_dns_query_set_num_queries(), ast_dns_record_get_data(), ast_dns_record_get_data_size(), ast_dns_record_get_next(), ast_dns_record_get_rr_type(), ast_dns_result_get_records(), ast_log, ast_query_set_resolve(), ast_strlen_zero(), ast_dns_record::data, LOG_ERROR, RAII_VAR, result, and ast_dns_record::rr_type.

Referenced by unicast_rtp_request().

◆ 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 536 of file dns_core.c.

537{
538 struct ast_dns_record *record;
539
540 if (rr_type < 0) {
541 ast_debug(2, "Query '%p': Could not add record, invalid resource record type '%d'\n",
542 query, rr_type);
543 return -1;
544 } else if (rr_type > 65536) {
545 ast_debug(2, "Query '%p': Could not add record, resource record type '%d' exceeds maximum\n",
546 query, rr_type);
547 return -1;
548 } else if (rr_class < 0) {
549 ast_debug(2, "Query '%p': Could not add record, invalid resource record class '%d'\n",
550 query, rr_class);
551 return -1;
552 } else if (rr_class > 65536) {
553 ast_debug(2, "Query '%p': Could not add record, resource record class '%d' exceeds maximum\n",
554 query, rr_class);
555 return -1;
556 } else if (ttl < 0) {
557 ast_debug(2, "Query '%p': Could not add record, invalid TTL '%d'\n",
558 query, ttl);
559 return -1;
560 } else if (!data || !size) {
561 ast_debug(2, "Query '%p': Could not add record, no data specified\n",
562 query);
563 return -1;
564 } else if (!query->result) {
565 ast_debug(2, "Query '%p': No result was set on the query, thus records can not be added\n",
566 query);
567 return -1;
568 }
569
570 record = allocate_dns_record(rr_type, query, data, size);
571 if (!record) {
572 return -1;
573 }
574
575 record->rr_type = rr_type;
576 record->rr_class = rr_class;
577 record->ttl = ttl;
578 record->data_len = size;
579 memcpy(record->data_ptr, data, size);
580
581 AST_LIST_INSERT_TAIL(&query->result->records, record, list);
582
583 return 0;
584}
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:525
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
struct ast_dns_record::@224 list
Linked list information.
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(), AST_TEST_DEFINE(), dns_system_resolver_add_record(), naptr_thread(), resolution_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 600 of file dns_core.c.

601{
602 if (query->result) {
604 }
605
606 query->callback(query);
607}
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:593
ast_dns_resolve_callback callback
Callback to invoke upon completion.

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(), resolution_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 452 of file dns_core.c.

453{
454 return query->resolver_data;
455}
void * resolver_data
Resolver-specific data.

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 633 of file dns_core.c.

634{
635 struct ast_dns_resolver *iter;
636 int inserted = 0;
637
638 if (!resolver) {
639 return -1;
640 } else if (ast_strlen_zero(resolver->name)) {
641 ast_log(LOG_ERROR, "Registration of DNS resolver failed as it does not have a name\n");
642 return -1;
643 } else if (!resolver->resolve) {
644 ast_log(LOG_ERROR, "DNS resolver '%s' does not implement the resolve callback which is required\n",
645 resolver->name);
646 return -1;
647 } else if (!resolver->cancel) {
648 ast_log(LOG_ERROR, "DNS resolver '%s' does not implement the cancel callback which is required\n",
649 resolver->name);
650 return -1;
651 }
652
654
655 AST_LIST_TRAVERSE(&resolvers, iter, next) {
656 if (!strcmp(iter->name, resolver->name)) {
657 ast_log(LOG_ERROR, "A DNS resolver with the name '%s' is already registered\n", resolver->name);
659 return -1;
660 }
661 }
662
664 if (iter->priority > resolver->priority) {
665 AST_RWLIST_INSERT_BEFORE_CURRENT(resolver, next);
666 inserted = 1;
667 break;
668 }
669 }
671
672 if (!inserted) {
673 AST_RWLIST_INSERT_TAIL(&resolvers, resolver, next);
674 }
675
677
678 ast_verb(5, "Registered DNS resolver '%s' with priority '%d'\n", resolver->name, resolver->priority);
679
680 return 0;
681}
#define ast_verb(level,...)
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#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.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_RWLIST_TRAVERSE_SAFE_END
#define AST_RWLIST_INSERT_TAIL
#define AST_RWLIST_INSERT_BEFORE_CURRENT
DNS resolver implementation.
unsigned int priority
Priority for this resolver if multiple exist, lower being higher priority.

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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 441 of file dns_core.c.

442{
443 if (query->resolver_data) {
444 return -1;
445 }
446
447 query->resolver_data = ao2_bump(data);
448
449 return 0;
450}
#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 457 of file dns_core.c.

459{
460 char *buf_ptr;
461
462 if (secure && bogus) {
463 ast_debug(2, "Query '%p': Could not set result information, it can not be both secure and bogus\n",
464 query);
465 return -1;
466 }
467
468 if (ast_strlen_zero(canonical)) {
469 ast_debug(2, "Query '%p': Could not set result information since no canonical name was provided\n",
470 query);
471 return -1;
472 }
473
474 if (!answer) {
475 answer = "";
476 answer_size = 0;
477 ast_debug(2, "Query '%p': Assuming zero-sized answer on NULL input\n", query);
478 }
479
481
482 query->result = ast_calloc(1, sizeof(*query->result) + strlen(canonical) + 1 + answer_size);
483 if (!query->result) {
484 return -1;
485 }
486
487 query->result->secure = secure;
488 query->result->bogus = bogus;
489 query->result->rcode = rcode;
490
491 buf_ptr = query->result->buf;
492 strcpy(buf_ptr, canonical); /* SAFE */
493 query->result->canonical = buf_ptr;
494
495 buf_ptr += strlen(canonical) + 1;
496 memcpy(buf_ptr, answer, answer_size); /* SAFE */
497 query->result->answer = buf_ptr;
498 query->result->answer_size = answer_size;
499
500 return 0;
501}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
static int answer(void *data)
Definition chan_pjsip.c:687
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.
const char * canonical
The canonical name.
size_t answer_size
The size of the raw DNS answer.
unsigned int bogus
Whether the result is bogus.
unsigned int secure
Whether the result is secure.
const char * answer
The raw DNS answer.
unsigned int rcode
Optional rcode, set if an error occurred.

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), dns_system_resolver_set_response(), naptr_thread(), resolution_thread(), resolution_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 683 of file dns_core.c.

684{
685 struct ast_dns_resolver *iter;
686
687 if (!resolver) {
688 return;
689 }
690
693 if (resolver == iter) {
695 break;
696 }
697 }
700
701 ast_verb(5, "Unregistered DNS resolver '%s'\n", resolver->name);
702}
#define AST_RWLIST_REMOVE_CURRENT

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), dns_system_resolver_destroy(), invalid_record_test(), nominal_test(), off_nominal_test(), and query_set_test().

◆ ast_dns_result_free()

void ast_dns_result_free ( struct ast_dns_result result)

Free the DNS result information.

Parameters
resultThe DNS result

Definition at line 130 of file dns_core.c.

131{
132 struct ast_dns_record *record;
133
134 if (!result) {
135 return;
136 }
137
138 while ((record = AST_LIST_REMOVE_HEAD(&result->records, list))) {
139 ast_free(record);
140 }
141
143}
#define ast_free(a)
Definition astmm.h:180
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.

References ast_free, AST_LIST_REMOVE_HEAD, ast_dns_record::list, and result.

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

◆ ast_dns_result_get_answer()

const char * ast_dns_result_get_answer ( const struct ast_dns_result result)

Get the raw DNS answer from a DNS result.

Parameters
resultThe DNS result
Returns
The DNS result

Definition at line 107 of file dns_core.c.

108{
109 return result->answer;
110}

References result.

Referenced by test_results().

◆ ast_dns_result_get_bogus()

unsigned int ast_dns_result_get_bogus ( const struct ast_dns_result result)

Get whether the result is bogus or not.

Parameters
resultThe DNS result
Returns
whether the result is bogus or not

Definition at line 87 of file dns_core.c.

88{
89 return result->bogus;
90}

References result.

Referenced by test_results().

◆ ast_dns_result_get_canonical()

const char * ast_dns_result_get_canonical ( const struct ast_dns_result result)

Get the canonical name of the result.

Parameters
resultThe DNS result
Returns
the canonical name

Definition at line 97 of file dns_core.c.

98{
99 return result->canonical;
100}

References result.

Referenced by test_results().

◆ ast_dns_result_get_lowest_ttl()

int ast_dns_result_get_lowest_ttl ( const struct ast_dns_result result)

Retrieve the lowest TTL from a result.

Parameters
resultThe DNS result
Returns
the lowest TTL
Note
If no records exist this function will return a TTL of 0

Definition at line 112 of file dns_core.c.

113{
114 int ttl = 0;
115 const struct ast_dns_record *record;
116
117 if (ast_dns_result_get_rcode(result) == NXDOMAIN) {
118 return 0;
119 }
120
121 for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {
122 if (!ttl || (ast_dns_record_get_ttl(record) && (ast_dns_record_get_ttl(record) < ttl))) {
123 ttl = ast_dns_record_get_ttl(record);
124 }
125 }
126
127 return ttl;
128}
int ast_dns_record_get_ttl(const struct ast_dns_record *record)
Get the TTL of a DNS record.
Definition dns_core.c:155
unsigned int ast_dns_result_get_rcode(const struct ast_dns_result *result)
Get the error rcode of a DN result.
Definition dns_core.c:92

References ast_dns_record_get_next(), ast_dns_record_get_ttl(), ast_dns_result_get_rcode(), ast_dns_result_get_records(), result, and ast_dns_record::ttl.

Referenced by dns_query_recurring_resolution_callback().

◆ ast_dns_result_get_rcode()

unsigned int ast_dns_result_get_rcode ( const struct ast_dns_result result)

Get the error rcode of a DN result.

Parameters
resultThe DNS result
Returns
the DNS rcode

Definition at line 92 of file dns_core.c.

93{
94 return result->rcode;
95}

References result.

Referenced by ast_dns_result_get_lowest_ttl(), and test_results().

◆ ast_dns_result_get_records()

const struct ast_dns_record * ast_dns_result_get_records ( const struct ast_dns_result result)

Get the first record of a DNS Result.

Parameters
resultThe DNS result
Returns
first DNS record

Definition at line 102 of file dns_core.c.

103{
104 return AST_LIST_FIRST(&result->records);
105}
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.

References AST_LIST_FIRST, and result.

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

◆ ast_dns_result_get_secure()

unsigned int ast_dns_result_get_secure ( const struct ast_dns_result result)

Get whether the result is secure or not.

Parameters
resultThe DNS result
Returns
whether the result is secure or not

Definition at line 82 of file dns_core.c.

83{
84 return result->secure;
85}

References result, and ast_dns_result::secure.

Referenced by test_results().

◆ dns_core_init()

int dns_core_init ( void  )

Provided by dns_core.c

Definition at line 617 of file dns_core.c.

618{
620 if (!sched) {
621 return -1;
622 }
623
625 return -1;
626 }
627
629
630 return 0;
631}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition clicompat.c:19
static void dns_shutdown(void)
Definition dns_core.c:609
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition sched.c:197
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition sched.c:238
Definition sched.c:76

References ast_register_cleanup(), ast_sched_context_create(), ast_sched_start_thread(), and dns_shutdown().

Referenced by asterisk_daemon().

◆ dns_find_record()

char * dns_find_record ( const char *  record,
size_t  record_size,
const char *  response,
size_t  response_size 
)

Find the location of a DNS record within the entire DNS answer.

The DNS record that has been returned by the resolver may be a copy of the record that was found in the complete DNS response. If so, then some DNS record types (specifically those that parse domains) will need to locate the DNS record within the complete DNS response. This is so that if the domain contains pointers to other sections of the DNS response, then the referenced domains may be located.

Parameters
recordThe DNS record returned by a resolver implementation
record_sizeThe size of the DNS record in bytes
responseThe complete DNS answer
response_sizeThe size of the complete DNS response

Definition at line 704 of file dns_core.c.

705{
706 size_t remaining_size = response_size;
707 const char *search_base = response;
708 char *record_offset;
709
710 while (1) {
711 record_offset = memchr((void *)search_base, record[0], remaining_size);
712
713 ast_assert(record_offset != NULL);
714 ast_assert(search_base + remaining_size - record_offset >= record_size);
715
716 if (!memcmp(record_offset, record, record_size)) {
717 return record_offset;
718 }
719
720 remaining_size -= record_offset - search_base;
721 search_base = record_offset + 1;
722 }
723}
#define ast_assert(a)
Definition utils.h:779

References ast_assert, and NULL.

Referenced by dns_naptr_alloc(), and dns_srv_alloc().

◆ dns_parse_short()

int dns_parse_short ( unsigned char *  cur,
uint16_t *  val 
)

Parse a 16-bit unsigned value from a DNS record.

Parameters
curPointer to the location of the 16-bit value in the DNS record
[out]valThe parsed 16-bit unsigned integer
Returns
The number of bytes consumed while parsing

Definition at line 725 of file dns_core.c.

726{
727 /* This assignment takes a big-endian 16-bit value and stores it in the
728 * machine's native byte order. Using this method allows us to avoid potential
729 * alignment issues in case the order is not on a short-addressable boundary.
730 * See http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html for
731 * more information
732 */
733 *val = (cur[1] << 0) | (cur[0] << 8);
734 return sizeof(*val);
735}

Referenced by dns_naptr_alloc(), and dns_srv_alloc().

◆ dns_parse_string()

int dns_parse_string ( char *  cur,
uint8_t *  size,
char **  val 
)

Parse a DNS string from a DNS record.

A DNS string consists of an 8-bit size, followed by the string value (not NULL-terminated).

Parameters
curPointer to the location of the DNS string
[out]sizeThe parsed size of the DNS string
[out]valThe contained string (not NULL-terminated)
Returns
The number of bytes consumed while parsing

Definition at line 737 of file dns_core.c.

738{
739 *size = *cur++;
740 *val = cur;
741 return *size + 1;
742}

Referenced by dns_naptr_alloc().

◆ dns_query_active_destroy()

static void dns_query_active_destroy ( void *  data)
static

Destructor for an active DNS query.

Definition at line 176 of file dns_core.c.

177{
178 struct ast_dns_query_active *active = data;
179
180 ao2_cleanup(active->query);
181}

References ao2_cleanup, and ast_dns_query_active::query.

Referenced by ast_dns_resolve_async().

◆ dns_query_alloc()

struct ast_dns_query * dns_query_alloc ( const char *  name,
int  rr_type,
int  rr_class,
ast_dns_resolve_callback  callback,
void *  data 
)

Allocate a DNS query (but do not start resolution)

Parameters
nameThe name of what to resolve
rr_typeResource record type
rr_classResource record class
callbackThe callback to invoke upon completion
dataUser data to make available on the query
Return values
non-NULLsuccess
NULLfailure
Note
The result passed to the callback does not need to be freed
The user data MUST be an ao2 object
This function increments the reference count of the user data, it does NOT steal
The query must be released upon completion or cancellation using ao2_ref

Definition at line 193 of file dns_core.c.

194{
195 struct ast_dns_query *query;
196
197 if (ast_strlen_zero(name)) {
198 ast_log(LOG_WARNING, "Could not perform asynchronous resolution, no name provided\n");
199 return NULL;
200 } else if (rr_type > 65536) {
201 ast_log(LOG_WARNING, "Could not perform asynchronous resolution of '%s', resource record type '%d' exceeds maximum\n",
202 name, rr_type);
203 return NULL;
204 } else if (rr_type < 0) {
205 ast_log(LOG_WARNING, "Could not perform asynchronous resolution of '%s', invalid resource record type '%d'\n",
206 name, rr_type);
207 return NULL;
208 } else if (rr_class > 65536) {
209 ast_log(LOG_WARNING, "Could not perform asynchronous resolution of '%s', resource record class '%d' exceeds maximum\n",
210 name, rr_class);
211 return NULL;
212 } else if (rr_class < 0) {
213 ast_log(LOG_WARNING, "Could not perform asynchronous resolution of '%s', invalid resource class '%d'\n",
214 name, rr_class);
215 return NULL;
216 } else if (!callback) {
217 ast_log(LOG_WARNING, "Could not perform asynchronous resolution of '%s', no callback provided\n",
218 name);
219 return NULL;
220 }
221
222 query = ao2_alloc_options(sizeof(*query) + strlen(name) + 1, dns_query_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
223 if (!query) {
224 return NULL;
225 }
226
227 query->callback = callback;
228 query->user_data = ao2_bump(data);
229 query->rr_type = rr_type;
230 query->rr_class = rr_class;
231 strcpy(query->name, name); /* SAFE */
232
236
237 if (!query->resolver) {
238 ast_log(LOG_ERROR, "Attempted to do a DNS query for '%s' of class '%d' and type '%d' but no resolver is available\n",
240 ao2_ref(query, -1);
241 return NULL;
242 }
243
244 return query;
245}
static void dns_query_destroy(void *data)
Destructor for a DNS query.
Definition dns_core.c:184
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition linkedlists.h:78
#define AST_RWLIST_FIRST

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_ref, ast_log, AST_RWLIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_strlen_zero(), ast_dns_query::callback, callback(), dns_query_destroy(), LOG_ERROR, LOG_WARNING, ast_dns_query::name, name, NULL, ast_dns_query::resolver, ast_dns_query::rr_class, ast_dns_query::rr_type, and ast_dns_query::user_data.

Referenced by ast_dns_query_set_add(), ast_dns_resolve_async(), and dns_query_recurring_resolution_callback().

◆ dns_query_destroy()

static void dns_query_destroy ( void *  data)
static

Destructor for a DNS query.

Definition at line 184 of file dns_core.c.

185{
186 struct ast_dns_query *query = data;
187
188 ao2_cleanup(query->user_data);
191}

References ao2_cleanup, ast_dns_result_free(), ast_dns_query::resolver_data, ast_dns_query::result, and ast_dns_query::user_data.

Referenced by dns_query_alloc().

◆ dns_shutdown()

static void dns_shutdown ( void  )
static

Definition at line 609 of file dns_core.c.

610{
611 if (sched) {
613 sched = NULL;
614 }
615}
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition sched.c:271

References ast_sched_context_destroy(), and NULL.

Referenced by dns_core_init().

◆ dns_synchronous_resolve_callback()

static void dns_synchronous_resolve_callback ( const struct ast_dns_query query)
static

Callback used to implement synchronous resolution.

Definition at line 302 of file dns_core.c.

303{
304 struct dns_synchronous_resolve *synchronous = ast_dns_query_get_data(query);
305
306 synchronous->result = query->result;
307 ((struct ast_dns_query *)query)->result = NULL;
308
309 ast_mutex_lock(&synchronous->lock);
310 synchronous->completed = 1;
311 ast_cond_signal(&synchronous->cond);
312 ast_mutex_unlock(&synchronous->lock);
313}
void * ast_dns_query_get_data(const struct ast_dns_query *query)
Get the user specific data of a DNS query.
Definition dns_core.c:72
#define ast_cond_signal(cond)
Definition lock.h:210

References ast_cond_signal, ast_dns_query_get_data(), ast_mutex_lock, ast_mutex_unlock, dns_synchronous_resolve::completed, dns_synchronous_resolve::cond, dns_synchronous_resolve::lock, NULL, ast_dns_query::result, and dns_synchronous_resolve::result.

Referenced by ast_dns_resolve().

◆ dns_synchronous_resolve_destroy()

static void dns_synchronous_resolve_destroy ( void *  data)
static

Destructor for synchronous resolution structure.

Definition at line 291 of file dns_core.c.

292{
293 struct dns_synchronous_resolve *synchronous = data;
294
295 ast_mutex_destroy(&synchronous->lock);
296 ast_cond_destroy(&synchronous->cond);
297
298 /* This purposely does not unref result as it has been passed to the caller */
299}
#define ast_cond_destroy(cond)
Definition lock.h:209
#define ast_mutex_destroy(a)
Definition lock.h:195

References ast_cond_destroy, ast_mutex_destroy, dns_synchronous_resolve::cond, and dns_synchronous_resolve::lock.

Referenced by ast_dns_resolve().

◆ generic_record_alloc()

static struct ast_dns_record * generic_record_alloc ( struct ast_dns_query query,
const char *  data,
const size_t  size 
)
static

Definition at line 503 of file dns_core.c.

504{
505 struct ast_dns_record *record;
506
507 record = ast_calloc(1, sizeof(*record) + size);
508 if (!record) {
509 return NULL;
510 }
511
512 record->data_ptr = record->data;
513
514 return record;
515}

Referenced by allocate_dns_record().

◆ sort_result()

static void sort_result ( int  rr_type,
struct ast_dns_result result 
)
static

Definition at line 593 of file dns_core.c.

594{
595 if (dns_sort_table[rr_type]) {
596 dns_sort_table[rr_type](result);
597 }
598}
static dns_sort_fn dns_sort_table[]
Definition dns_core.c:588

References dns_sort_table, and result.

Referenced by ast_dns_resolver_completed().

Variable Documentation

◆ dns_alloc_table

dns_alloc_fn dns_alloc_table[]
static
Initial value:
= {
[T_TXT] = dns_txt_alloc,
[T_NAPTR] = dns_naptr_alloc,
[T_SRV] = dns_srv_alloc,
}
struct ast_dns_record * dns_naptr_alloc(struct ast_dns_query *query, const char *data, const size_t size)
Allocate and parse a DNS NAPTR record.
Definition dns_naptr.c:380
struct ast_dns_record * dns_srv_alloc(struct ast_dns_query *query, const char *data, const size_t size)
Allocate and parse a DNS SRV record.
Definition dns_srv.c:42
struct ast_dns_record * dns_txt_alloc(struct ast_dns_query *query, const char *data, const size_t size)
Allocate and parse a DNS TXT record.
Definition dns_txt.c:38

Definition at line 519 of file dns_core.c.

519 {
520 [T_TXT] = dns_txt_alloc,
521 [T_NAPTR] = dns_naptr_alloc,
522 [T_SRV] = dns_srv_alloc,
523};

Referenced by allocate_dns_record().

◆ dns_sort_table

dns_sort_fn dns_sort_table[]
static
Initial value:
= {
[T_NAPTR] = dns_naptr_sort,
[T_SRV] = dns_srv_sort,
}
void dns_naptr_sort(struct ast_dns_result *result)
Sort the NAPTR records on a result.
Definition dns_naptr.c:551
void dns_srv_sort(struct ast_dns_result *result)
Sort the SRV records on a result.
Definition dns_srv.c:113

Definition at line 588 of file dns_core.c.

588 {
589 [T_NAPTR] = dns_naptr_sort,
590 [T_SRV] = dns_srv_sort,
591};

Referenced by sort_result().

◆ resolvers

◆ sched

struct ast_sched_context* sched
static

Definition at line 50 of file dns_core.c.

Referenced by ast_dns_get_sched().