The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_unbound.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 14a4371bf4a4ef91a23980d43956188a8af52813 $
19 * @file rlm_unbound.c
20 * @brief DNS services via libunbound.
21 *
22 * @copyright 2013 The FreeRADIUS server project
23 * @copyright 2013 Brian S. Julin (bjulin@clarku.edu)
24 */
25RCSID("$Id: 14a4371bf4a4ef91a23980d43956188a8af52813 $")
26
27#define LOG_PREFIX mctx->mi->name
28
29#include <freeradius-devel/server/base.h>
30#include <freeradius-devel/server/module_rlm.h>
31#include <freeradius-devel/server/log.h>
32#include <freeradius-devel/unlang/xlat_func.h>
33#include <fcntl.h>
34
35#include "io.h"
36#include "log.h"
37
38typedef struct {
40
41 char const *filename; //!< Unbound configuration file
42 char const *resolvconf; //!< resolv.conf file to use
43 char const *hosts; //!< hosts file to load
45
46typedef struct {
47 unbound_io_event_base_t *ev_b; //!< Unbound event base
48 rlm_unbound_t *inst; //!< Instance data
49 unbound_log_t *u_log; //!< Unbound log structure
51
52typedef struct {
53 int async_id; //!< Id of async query
54 request_t *request; //!< Current request being processed
55 rlm_unbound_thread_t *t; //!< Thread running this request
56 int done; //!< Indicator that the callback has been called
57 ///< Negative values indicate errors.
58 bool timedout; //!< Request timedout.
59 fr_type_t return_type; //!< Data type to parse results into
60 bool has_priority; //!< Does the returned data start with a priority field
61 uint16_t count; //!< Number of results to return
62 fr_value_box_list_t list; //!< Where to put the parsed results
63 TALLOC_CTX *out_ctx; //!< CTX to allocate parsed results in
64 fr_event_timer_t const *ev; //!< Event for timeout
66
67/*
68 * A mapping of configuration file names to internal variables.
69 */
70static const conf_parser_t module_config[] = {
71 { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_FILE_INPUT, rlm_unbound_t, filename), .dflt = "${modconfdir}/unbound/default.conf" },
72 { FR_CONF_OFFSET("timeout", rlm_unbound_t, timeout), .dflt = "3000" },
73 { FR_CONF_OFFSET_FLAGS("resolvconf", CONF_FLAG_FILE_INPUT, rlm_unbound_t, resolvconf) },
76};
77
79{
80 /*
81 * Cancel an outstanding async unbound call if the request is being freed
82 */
83 if ((ur->async_id != 0) && (ur->done == 0)) ub_cancel(ur->t->ev_b->ub, ur->async_id);
84
85 return 0;
86}
87
88/** Callback called by unbound when resolution started with ub_resolve_event() completes
89 *
90 * @param mydata the request tracking structure set up before ub_resolve_event() was called
91 * @param rcode should be the rcode from the reply packet, but appears not to be
92 * @param packet wire format reply packet
93 * @param packet_len length of wire format packet
94 * @param sec DNSSEC status code
95 * @param why_bogus String describing DNSSEC issue if sec = 1
96 * @param rate_limited Was the request rate limited due to unbound workload
97 */
98static void xlat_unbound_callback(void *mydata, int rcode, void *packet, int packet_len, int sec,
99 char *why_bogus
100#if UNBOUND_VERSION_MAJOR > 1 || (UNBOUND_VERSION_MAJOR == 1 && UNBOUND_VERSION_MINOR > 7)
101 , UNUSED int rate_limited
102#endif
103 )
104
105{
106 unbound_request_t *ur = talloc_get_type_abort(mydata, unbound_request_t);
107 request_t *request = ur->request;
108 fr_dbuff_t dbuff;
109 uint16_t qdcount = 0, ancount = 0, i, rdlength = 0;
110 uint8_t pktrcode = 0, skip = 0;
112 fr_value_box_t *vb;
113
114 /*
115 * Request has completed remove timeout event and set
116 * async_id to 0 so ub_cancel() is not called when ur is freed
117 */
118 if (ur->ev) (void)fr_event_timer_delete(&ur->ev);
119 ur->async_id = 0;
120
121 /*
122 * Bogus responses have the "sec" flag set to 1
123 */
124 if (sec == 1) {
125 RERROR("%s", why_bogus);
126 ur->done = -16;
127 goto resume;
128 }
129
130 RHEXDUMP4((uint8_t const *)packet, packet_len, "Unbound callback called with packet [length %d]", packet_len);
131
132 fr_dbuff_init(&dbuff, (uint8_t const *)packet, (size_t)packet_len);
133
134 /* Skip initial header entries */
135 fr_dbuff_advance(&dbuff, 3);
136
137 /*
138 * Extract rcode - it doesn't appear to be passed in as a
139 * parameter, contrary to the documentation...
140 */
141 fr_dbuff_out(&pktrcode, &dbuff);
142 rcode = pktrcode & 0x0f;
143 if (rcode != 0) {
144 ur->done = 0 - rcode;
145 REDEBUG("DNS rcode is %d", rcode);
146 goto resume;
147 }
148
149 fr_dbuff_out(&qdcount, &dbuff);
150 if (qdcount > 1) {
151 RERROR("DNS results packet with multiple questions");
152 ur->done = -32;
153 goto resume;
154 }
155
156 /* How many answer records do we have? */
157 fr_dbuff_out(&ancount, &dbuff);
158 RDEBUG4("Unbound returned %d answers", ancount);
159
160 /* Skip remaining header entries */
161 fr_dbuff_advance(&dbuff, 4);
162
163 /* Skip the QNAME */
164 fr_dbuff_out(&skip, &dbuff);
165 while (skip > 0) {
166 if (skip > 63) {
167 /*
168 * This is a pointer to somewhere else in the the packet
169 * Pointers use two octets
170 * Just move past the pointer to the next label in the question
171 */
172 fr_dbuff_advance(&dbuff, 1);
173 } else {
174 if (fr_dbuff_remaining(&dbuff) < skip) break;
175 fr_dbuff_advance(&dbuff, skip);
176 }
177 fr_dbuff_out(&skip, &dbuff);
178 }
179
180 /* Skip QTYPE and QCLASS */
181 fr_dbuff_advance(&dbuff, 4);
182
183 /* We only want a limited number of replies */
184 if (ancount > ur->count) ancount = ur->count;
185
186 fr_value_box_list_init(&ur->list);
187
188 /* Read the answer RRs */
189 for (i = 0; i < ancount; i++) {
190 fr_dbuff_out(&skip, &dbuff);
191 if (skip > 63) fr_dbuff_advance(&dbuff, 1);
192
193 /* Skip TYPE, CLASS and TTL */
194 fr_dbuff_advance(&dbuff, 8);
195
196 fr_dbuff_out(&rdlength, &dbuff);
197 RDEBUG4("RDLENGTH is %d", rdlength);
198
200 switch (ur->return_type) {
203 case FR_TYPE_OCTETS:
204 if (fr_value_box_from_network(ur->out_ctx, vb, ur->return_type, NULL,
205 &dbuff, rdlength, true) < 0) {
206 error:
207 talloc_free(vb);
208 fr_value_box_list_talloc_free(&ur->list);
209 ur->done = -32;
210 goto resume;
211 }
212 break;
213
214 case FR_TYPE_STRING:
215 if (ur->has_priority) {
216 /*
217 * This record type has a priority before the label
218 * add the priority first as a separate box
219 */
220 fr_value_box_t *priority_vb;
221 if (rdlength < 3) {
222 REDEBUG("Invalid data returned");
223 goto error;
224 }
225 MEM(priority_vb = fr_value_box_alloc_null(ur->out_ctx));
226 if (fr_value_box_from_network(ur->out_ctx, priority_vb, FR_TYPE_UINT16, NULL,
227 &dbuff, 2, true) < 0) {
228 talloc_free(priority_vb);
229 goto error;
230 }
231 fr_value_box_list_insert_tail(&ur->list, priority_vb);
232 }
233
234 /* String types require decoding of dns format labels */
235 used = fr_dns_label_to_value_box(ur->out_ctx, vb, (uint8_t const *)packet, packet_len,
236 (uint8_t const *)fr_dbuff_current(&dbuff), true, NULL);
237 if (used < 0) goto error;
238 fr_dbuff_advance(&dbuff, (size_t)used);
239 break;
240
241 default:
242 RERROR("No meaningful output type set");
243 goto error;
244 }
245
246 fr_value_box_list_insert_tail(&ur->list, vb);
247
248 }
249
250 ur->done = 1;
251
252resume:
254}
255
256/** Callback from our timeout event to cancel a request
257 *
258 */
260{
261 unbound_request_t *ur = talloc_get_type_abort(uctx, unbound_request_t);
262 request_t *request = ur->request;
263
264 REDEBUG("Timeout waiting for DNS resolution");
266
267 ur->timedout = true;
268}
269
270/*
271 * Xlat signal callback if an unbound request needs cancelling
272 */
273static void xlat_unbound_signal(xlat_ctx_t const *xctx, request_t *request, UNUSED fr_signal_t action)
274{
275 unbound_request_t *ur = talloc_get_type_abort(xctx->rctx, unbound_request_t);
276
277 if (ur->ev) (void)fr_event_timer_delete(&ur->ev);
278
279 RDEBUG2("Forcefully cancelling pending unbound request");
280}
281
282/*
283 * Xlat resume callback after unbound has either returned or timed out
284 * Move the parsed results to the xlat output cursor
285 */
287 xlat_ctx_t const *xctx,
288 request_t *request, UNUSED fr_value_box_list_t *in)
289{
290 fr_value_box_t *vb;
291 unbound_request_t *ur = talloc_get_type_abort(xctx->rctx, unbound_request_t);
292
293 /*
294 * Request timed out
295 */
296 if (ur->timedout) return XLAT_ACTION_FAIL;
297
298#define RCODEERROR(_code, _message) case _code: \
299 REDEBUG(_message, xctx->mctx->mi->name); \
300 goto error
301
302 /* Check for unbound errors */
303 switch (ur->done) {
304 case 1:
305 break;
306
307 default:
308 REDEBUG("Unknown DNS error");
309 error:
310 talloc_free(ur);
311 return XLAT_ACTION_FAIL;
312
313 RCODEERROR(0, "%s - No result");
314 RCODEERROR(-1, "%s - Query format error");
315 RCODEERROR(-2, "%s - DNS server failure");
316 RCODEERROR(-3, "%s - Nonexistent domain name");
317 RCODEERROR(-4, "%s - DNS server does not support query type");
318 RCODEERROR(-5, "%s - DNS server refused query");
319 RCODEERROR(-16, "%s - Bogus DNS response");
320 RCODEERROR(-32, "%s - Error parsing DNS response");
321 }
322
323 /*
324 * Move parsed results into xlat cursor
325 */
326 while ((vb = fr_value_box_list_pop_head(&ur->list))) {
328 }
329
330 talloc_free(ur);
331 return XLAT_ACTION_DONE;
332}
333
334
336 { .required = true, .concat = true, .type = FR_TYPE_STRING },
337 { .required = true, .concat = true, .type = FR_TYPE_STRING },
338 { .single = true, .type = FR_TYPE_UINT16 },
340};
341
342/** Perform a DNS lookup using libunbound
343 *
344 * @ingroup xlat_functions
345 */
347 xlat_ctx_t const *xctx,
348 request_t *request, fr_value_box_list_t *in)
349{
351 rlm_unbound_thread_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_unbound_thread_t);
352 fr_value_box_t *host_vb = fr_value_box_list_head(in);
353 fr_value_box_t *query_vb = fr_value_box_list_next(in, host_vb);
354 fr_value_box_t *count_vb = fr_value_box_list_next(in, query_vb);
356
357 if (host_vb->vb_length == 0) {
358 REDEBUG("Can't resolve zero length host");
359 return XLAT_ACTION_FAIL;
360 }
361
362 MEM(ur = talloc_zero(unlang_interpret_frame_talloc_ctx(request), unbound_request_t));
363 talloc_set_destructor(ur, _unbound_request_free);
364
365 /*
366 * Set the maximum number of records we want to return
367 */
368 if ((count_vb) && (count_vb->type == FR_TYPE_UINT16) && (count_vb->vb_uint16 > 0)) {
369 ur->count = count_vb->vb_uint16;
370 } else {
371 ur->count = UINT16_MAX;
372 }
373
374 ur->request = request;
375 ur->t = t;
376 ur->out_ctx = ctx;
377
378#define UB_QUERY(_record, _rrvalue, _return, _hasprio) \
379 if (strcmp(query_vb->vb_strvalue, _record) == 0) { \
380 ur->return_type = _return; \
381 ur->has_priority = _hasprio; \
382 ub_resolve_event(t->ev_b->ub, host_vb->vb_strvalue, _rrvalue, 1, ur, \
383 xlat_unbound_callback, &ur->async_id); \
384 }
385
386 /* coverity[dereference] */
387 UB_QUERY("A", 1, FR_TYPE_IPV4_ADDR, false)
388 else UB_QUERY("AAAA", 28, FR_TYPE_IPV6_ADDR, false)
389 else UB_QUERY("PTR", 12, FR_TYPE_STRING, false)
390 else UB_QUERY("MX", 15, FR_TYPE_STRING, true)
391 else UB_QUERY("SRV", 33, FR_TYPE_STRING, true)
392 else UB_QUERY("TXT", 16, FR_TYPE_STRING, false)
393 else UB_QUERY("CERT", 37, FR_TYPE_OCTETS, false)
394 else {
395 REDEBUG("Invalid / unsupported DNS query type");
396 return XLAT_ACTION_FAIL;
397 }
398
399 /*
400 * unbound returned before we yielded - run the callback
401 * This is when serving results from local data
402 */
403 if (ur->async_id == 0) {
404 xlat_ctx_t our_xctx = *xctx;
405
406 our_xctx.rctx = ur; /* Make the rctx available to the resume function */
407
408 return xlat_unbound_resume(ctx, out, &our_xctx, request, in);
409 }
410
411 if (fr_event_timer_in(ur, ur->t->ev_b->el, &ur->ev, fr_time_delta_from_msec(inst->timeout),
412 xlat_unbound_timeout, ur) < 0) {
413 REDEBUG("Unable to attach unbound timeout_envent");
414 ub_cancel(t->ev_b->ub, ur->async_id);
415 return XLAT_ACTION_FAIL;
416 }
417
419}
420
422{
423 rlm_unbound_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_unbound_t);
424 rlm_unbound_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_unbound_thread_t);
425 int res;
426
427 t->inst = inst;
428 if (unbound_io_init(t, &t->ev_b, mctx->el) < 0) {
429 PERROR("Unable to create unbound event base");
430 return -1;
431 }
432
433 /*
434 * Ensure unbound uses threads
435 */
436 res = ub_ctx_async(t->ev_b->ub, 1);
437 if (res) {
438 error:
439 PERROR("%s", ub_strerror(res));
440 free_error:
441 talloc_free(t->ev_b);
442 return -1;
443 }
444
445 /*
446 * Load settings from the unbound config file
447 */
448 res = ub_ctx_config(t->ev_b->ub, UNCONST(char *, inst->filename));
449 if (res) goto error;
450
451 if (unbound_log_init(t, &t->u_log, t->ev_b->ub) < 0) {
452 PERROR("Failed to initialise unbound log");
453 goto free_error;
454 }
455
456 /*
457 * Load resolv.conf if specified
458 */
459 if (inst->resolvconf) ub_ctx_resolvconf(t->ev_b->ub, inst->resolvconf);
460
461 /*
462 * Load hosts file if specified
463 */
464 if (inst->hosts) ub_ctx_hosts(t->ev_b->ub, inst->hosts);
465
466 /*
467 * The unbound context needs to be "finalised" to fix its settings.
468 * The API does not expose a method to do this, rather it happens on first
469 * use. A quick workaround is to delete data which won't be present
470 */
471 ub_ctx_data_remove(t->ev_b->ub, "notar33lsite.foo123.nottld A 127.0.0.1");
472
473 return 0;
474}
475
477{
478 rlm_unbound_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_unbound_thread_t);
479
480 talloc_free(t->u_log);
481 talloc_free(t->ev_b);
482
483 return 0;
484}
485
486static int mod_bootstrap(module_inst_ctx_t const *mctx)
487{
488 rlm_unbound_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_unbound_t);
489 xlat_t *xlat;
490
491 if (inst->timeout > 10000) {
492 cf_log_err(mctx->mi->conf, "timeout must be 0 to 10000");
493 return -1;
494 }
495
496 if(!(xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, NULL, xlat_unbound, FR_TYPE_VOID))) return -1;
498
499 return 0;
500}
501
504 .common = {
505 .magic = MODULE_MAGIC_INIT,
506 .name = "unbound",
507 .inst_size = sizeof(rlm_unbound_t),
509 .bootstrap = mod_bootstrap,
510
511 .thread_inst_size = sizeof(rlm_unbound_thread_t),
512 .thread_inst_type = "rlm_unbound_thread_t",
513 .thread_instantiate = mod_thread_instantiate,
514 .thread_detach = mod_thread_detach
515 }
516};
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:167
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:256
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition cf_parse.h:424
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
Definition dbuff.h:1072
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
Definition dbuff.h:911
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
Definition dbuff.h:354
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
Definition dbuff.h:743
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
Definition dbuff.h:1799
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
#define MEM(x)
Definition debug.h:36
static fr_slen_t in
Definition dict.h:824
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
ssize_t fr_dns_label_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *dst, uint8_t const *src, size_t len, uint8_t const *label, bool tainted, fr_dns_labels_t *lb)
Decode a fr_value_box_t from one DNS label.
Definition dns.c:1225
#define fr_event_timer_in(...)
Definition event.h:255
static xlat_action_t xlat_unbound(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Perform a DNS lookup using libunbound.
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:1359
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1403
#define PERROR(_fmt,...)
Definition log.h:228
#define RHEXDUMP4(_data, _len, _fmt,...)
Definition log.h:706
#define RERROR(fmt,...)
Definition log.h:298
#define RDEBUG4(fmt,...)
Definition log.h:344
talloc_free(reap)
int fr_event_timer_delete(fr_event_timer_t const **ev_p)
Delete a timer event from the event list.
Definition event.c:1611
Stores all information relating to an event list.
Definition event.c:411
A timer event.
Definition event.c:102
unsigned short uint16_t
fr_type_t
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_VOID
User data.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
static size_t used
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * thread
Thread specific instance data.
Definition module_ctx.h:43
fr_event_list_t * el
Event list to register any IO handlers and timers against.
Definition module_ctx.h:68
void * thread
Thread instance data.
Definition module_ctx.h:67
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:64
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Definition module_rlm.c:257
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
int unbound_io_init(TALLOC_CTX *ctx, unbound_io_event_base_t **ev_b_out, fr_event_list_t *el)
Alloc a new event base, and unbound ctx initialised from that event base.
Definition io.c:482
Function prototypes and datatypes for the REST (HTTP) transport.
struct ub_ctx * ub
Unbound ctx instantiated from this event base.
Definition io.h:51
fr_event_list_t * el
Event loop events should be inserted into.
Definition io.h:53
Wrapper around our event loop specifying callbacks for creating new event handles.
Definition io.h:48
int unbound_log_init(TALLOC_CTX *ctx, unbound_log_t **u_log_out, struct ub_ctx *ub)
Setup an unbound context for log, and initialise a u_log struct.
Definition log.c:129
Function prototypes and datatypes for the REST (HTTP) transport.
Logging state.
Definition log.h:44
static const conf_parser_t config[]
Definition base.c:183
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
int async_id
Id of async query.
Definition rlm_unbound.c:53
uint16_t count
Number of results to return.
Definition rlm_unbound.c:61
static xlat_arg_parser_t const xlat_unbound_args[]
static void xlat_unbound_callback(void *mydata, int rcode, void *packet, int packet_len, int sec, char *why_bogus)
Callback called by unbound when resolution started with ub_resolve_event() completes.
Definition rlm_unbound.c:98
#define RCODEERROR(_code, _message)
fr_value_box_list_t list
Where to put the parsed results.
Definition rlm_unbound.c:62
TALLOC_CTX * out_ctx
CTX to allocate parsed results in.
Definition rlm_unbound.c:63
int done
Indicator that the callback has been called Negative values indicate errors.
Definition rlm_unbound.c:56
bool timedout
Request timedout.
Definition rlm_unbound.c:58
static int _unbound_request_free(unbound_request_t *ur)
Definition rlm_unbound.c:78
char const * filename
Unbound configuration file.
Definition rlm_unbound.c:41
static int mod_bootstrap(module_inst_ctx_t const *mctx)
#define UB_QUERY(_record, _rrvalue, _return, _hasprio)
fr_event_timer_t const * ev
Event for timeout.
Definition rlm_unbound.c:64
bool has_priority
Does the returned data start with a priority field.
Definition rlm_unbound.c:60
rlm_unbound_t * inst
Instance data.
Definition rlm_unbound.c:48
static void xlat_unbound_timeout(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
Callback from our timeout event to cancel a request.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
fr_type_t return_type
Data type to parse results into.
Definition rlm_unbound.c:59
unbound_io_event_base_t * ev_b
Unbound event base.
Definition rlm_unbound.c:47
static xlat_action_t xlat_unbound_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
static void xlat_unbound_signal(xlat_ctx_t const *xctx, request_t *request, UNUSED fr_signal_t action)
char const * hosts
hosts file to load
Definition rlm_unbound.c:43
request_t * request
Current request being processed.
Definition rlm_unbound.c:54
static const conf_parser_t module_config[]
Definition rlm_unbound.c:70
rlm_unbound_thread_t * t
Thread running this request.
Definition rlm_unbound.c:55
char const * resolvconf
resolv.conf file to use
Definition rlm_unbound.c:42
module_rlm_t rlm_unbound
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
unbound_log_t * u_log
Unbound log structure.
Definition rlm_unbound.c:49
uint32_t timeout
Definition rlm_unbound.c:39
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:329
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
void * boot
Data allocated during the boostrap phase.
Definition module.h:274
fr_signal_t
Signals that can be generated/processed by request signal handlers.
Definition signal.h:38
@ FR_SIGNAL_CANCEL
Request has been cancelled.
Definition signal.h:40
eap_aka_sim_process_conf_t * inst
#define talloc_get_type_abort_const
Definition talloc.h:282
static fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
Definition time.h:575
"server local" time.
Definition time.h:69
static fr_event_list_t * el
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
Definition xlat.c:573
bool required
Argument must be present, and non-empty.
Definition xlat.h:148
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:168
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumend by an xlat function.
Definition xlat.h:147
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
Definition value.c:1754
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:632
static size_t char ** out
Definition value.h:997
void * rctx
Resume context.
Definition xlat_ctx.h:54
module_ctx_t const * mctx
Synthesised module calling ctx.
Definition xlat_ctx.h:52
An xlat calling ctx.
Definition xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:365