Asterisk - The Open Source Telephony Project GIT-master-f36a736
dns_system_resolver.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2015, Digium, Inc.
5 *
6 * Ashley Sanders <asanders@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief The default DNS resolver for Asterisk.
22 *
23 * \arg See also \ref res_resolver_unbound.c
24 *
25 * \author Ashley Sanders <asanders@digium.com>
26 */
27
28#include "asterisk.h"
29
30#include "asterisk/_private.h"
31#include "asterisk/astobj2.h"
32#include "asterisk/dns.h"
33#include "asterisk/dns_core.h"
37#include "asterisk/utils.h"
38
39/*! \brief The consideration priority for this resolver implementation. */
40#define DNS_SYSTEM_RESOLVER_PRIORITY INT_MAX
41
42/*! \brief Resolver return code upon success. */
43#define DNS_SYSTEM_RESOLVER_SUCCESS 0
44
45/*! \brief Resolver return code upon failure. */
46#define DNS_SYSTEM_RESOLVER_FAILURE -1
47
48
49static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl);
50static int dns_system_resolver_cancel(struct ast_dns_query *query);
51static void dns_system_resolver_destroy(void);
52static int dns_system_resolver_process_query(void *data);
53static int dns_system_resolver_resolve(struct ast_dns_query *query);
54static int dns_system_resolver_set_response(void *context, unsigned char *dns_response, int dns_response_len, int rcode);
55
56
57/*! \brief The task processor to use for making DNS searches asynchronous. */
59
60/*! \brief The base definition for the dns_system_resolver */
62 .name = "system",
66};
67
68/*!
69 * \brief Callback to handle processing resource records.
70 *
71 * \details Adds an individual resource record discovered with ast_search_dns_ex to the
72 * ast_dns_query currently being resolved.
73 *
74 * \internal
75 *
76 * \param context A void pointer to the ast_dns_query being processed.
77 * \param record An individual resource record discovered during the DNS search.
78 * \param record_len The length of the resource record.
79 * \param ttl The resource record's expiration time limit (time to live).
80 *
81 * \retval 0 on success
82 * \retval -1 on failure
83 */
84static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl)
85{
86 struct ast_dns_query *query = context;
87
88 /* Add the record to the query.*/
89 return ast_dns_resolver_add_record(query,
92 ttl,
93 (const char*) record,
94 record_len);
95}
96
97/*!
98 * \brief Cancels processing resolution for a given query.
99 *
100 * \note The system API calls block so there is no way to cancel them. Therefore, this function always
101 * returns failure when invoked.
102 *
103 * \internal
104 *
105 * \param query The ast_dns_query to cancel.
106 *
107 * \retval 0 on success
108 * \retval -1 on failure
109 */
111{
113}
114
115/*!
116 * \brief Destructor.
117 *
118 * \internal
119 */
121{
122 /* Unreference the task processor */
124
125 /* Unregister the base resolver */
127}
128
129/*!
130 * \brief Callback to handle processing the query from the ast_taskprocessor instance.
131 *
132 * \internal
133 *
134 * \param data A void pointer to the ast_dns_query being processed.
135 *
136 * \retval -1 on search failure
137 * \retval 0 on no records found
138 * \retval 1 on success
139 */
141{
142 struct ast_dns_query *query = data;
143
144 /* Perform the DNS search */
151
152 /* Handle the possible return values from the DNS search */
153 if (res == AST_DNS_SEARCH_FAILURE) {
154 ast_debug(1, "DNS search failed for query: '%s'\n",
156 } else if (res == AST_DNS_SEARCH_NO_RECORDS) {
157 ast_debug(1, "DNS search failed to yield any results for query: '%s'\n",
159 }
160
161 /* Mark the query as complete */
163
164 /* Reduce the reference count on the query object */
165 ao2_ref(query, -1);
166
167 return res;
168}
169
170/*!
171 * \brief Resolves a DNS query.
172 *
173 * \internal
174 *
175 * \param query The ast_dns_query to resolve.
176 *
177 * \retval 0 on successful load of query handler to the ast_taskprocessor instance
178 * \retval -1 on failure to load the query handler to the ast_taskprocessor instance
179 */
181{
182 /* Add query processing handler to the task processor */
185 ao2_bump(query));
186
187 /* The query processing handler was not added to the task processor */
188 if (res < 0) {
189 ast_log(LOG_ERROR, "Failed to perform async DNS resolution of '%s'\n",
191 ao2_ref(query, -1);
192 }
193
194 /* Return the result of adding the query processing handler to the task processor */
195 return res;
196}
197
198/*!
199 * \brief Callback to handle initializing the results field.
200 *
201 * \internal
202 *
203 * \param context A void pointer to the ast_dns_query being processed.
204 * \param dns_response The full DNS response.
205 * \param dns_response_len The length of the full DNS response.
206 * \param rcode The DNS response code.
207 *
208 * \retval 0 on success
209 * \retval -1 on failure
210 */
211static int dns_system_resolver_set_response(void *context, unsigned char *dns_response, int dns_response_len, int rcode)
212{
213 struct ast_dns_query *query = context;
214 int res;
215
216 /* Instantiate the query's result field (if necessary). */
217 if (!ast_dns_query_get_result(query)) {
218 res = ast_dns_resolver_set_result(query,
219 0,
220 0,
221 rcode,
223 (const char*) dns_response,
224 dns_response_len);
225
226 if (res) {
227 /* There was a problem instantiating the results field. */
228 ast_log(LOG_ERROR, "Could not instantiate the results field for query: '%s'\n",
230 }
231 } else {
233 }
234
235 return res;
236}
237
238/*!
239 * \brief Initializes the resolver.
240 *
241 * \retval 0 on success
242 * \retval -1 on failure
243 */
245{
246 /* Register the base resolver */
248
249 if (res) {
251 }
252
253 /* Instantiate the task processor */
254 dns_system_resolver_tp = ast_taskprocessor_get("dns_system_resolver_tp",
256
257 /* Return error if the task processor failed to instantiate */
260 }
261
262 /* Register the cleanup function */
264
266}
Prototypes for public functions only of internal interest,.
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
DNS support for Asterisk.
enum ast_dns_search_result ast_search_dns_ex(void *context, const char *dname, int rr_class, int rr_type, int(*response_handler)(void *context, unsigned char *dns_response, int dns_response_len, int rcode), int(*record_handler)(void *context, unsigned char *record, int record_len, int ttl))
Extended version of the DNS search function.
Definition: dns.c:536
ast_dns_search_result
DNS search return values.
Definition: dns.h:28
@ AST_DNS_SEARCH_FAILURE
Definition: dns.h:29
@ AST_DNS_SEARCH_NO_RECORDS
Definition: dns.h:30
Core DNS API.
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
int ast_dns_query_get_rr_class(const struct ast_dns_query *query)
Get the record resource class of a DNS query.
Definition: dns_core.c:67
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
const char * ast_dns_query_get_name(const struct ast_dns_query *query)
Get the name queried in a DNS query.
Definition: dns_core.c:57
DNS Resolver API.
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.
Definition: dns_core.c:456
void ast_dns_resolver_completed(struct ast_dns_query *query)
Mark a DNS query as having been completed.
Definition: dns_core.c:599
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:632
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.
Definition: dns_core.c:535
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:682
static struct ast_taskprocessor * dns_system_resolver_tp
The task processor to use for making DNS searches asynchronous.
static int dns_system_resolver_process_query(void *data)
Callback to handle processing the query from the ast_taskprocessor instance.
#define DNS_SYSTEM_RESOLVER_FAILURE
Resolver return code upon failure.
static int dns_system_resolver_add_record(void *context, unsigned char *record, int record_len, int ttl)
Callback to handle processing resource records.
static void dns_system_resolver_destroy(void)
Destructor.
static int dns_system_resolver_set_response(void *context, unsigned char *dns_response, int dns_response_len, int rcode)
Callback to handle initializing the results field.
static int dns_system_resolver_resolve(struct ast_dns_query *query)
Resolves a DNS query.
#define DNS_SYSTEM_RESOLVER_PRIORITY
The consideration priority for this resolver implementation.
#define DNS_SYSTEM_RESOLVER_SUCCESS
Resolver return code upon success.
int ast_dns_system_resolver_init(void)
Initializes the resolver.
struct ast_dns_resolver dns_system_resolver_base
The base definition for the dns_system_resolver.
static int dns_system_resolver_cancel(struct ast_dns_query *query)
Cancels processing resolution for a given query.
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
A set of macros to manage forward-linked lists.
A DNS query.
Definition: dns_internal.h:137
DNS resolver implementation.
Definition: dns_resolver.h:32
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
A ast_taskprocessor structure is a singleton by name.
Definition: taskprocessor.c:69
An API for managing task processing threads that can be shared across modules.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:76
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
Utility functions.