The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_unbound.c
Go to the documentation of this file.
1/*
2 * This program 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: b238419547b3311d77ede43f035133fae67a2eb0 $
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: b238419547b3311d77ede43f035133fae67a2eb0 $")
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/unlang/xlat_func.h>
32#include <fcntl.h>
33
34#include "io.h"
35#include "log.h"
36
37typedef struct {
39
40 char const *filename; //!< Unbound configuration file
41 char const *resolvconf; //!< resolv.conf file to use
42 char const *hosts; //!< hosts file to load
44
45typedef struct {
46 unbound_io_event_base_t *ev_b; //!< Unbound event base
47 rlm_unbound_t *inst; //!< Instance data
48 unbound_log_t *u_log; //!< Unbound log structure
50
51typedef struct {
52 int async_id; //!< Id of async query
53 request_t *request; //!< Current request being processed
54 rlm_unbound_thread_t *t; //!< Thread running this request
55 int done; //!< Indicator that the callback has been called
56 ///< Negative values indicate errors.
57 bool timedout; //!< Request timedout.
58 fr_type_t return_type; //!< Data type to parse results into
59 bool has_priority; //!< Does the returned data start with a priority field
60 uint16_t count; //!< Number of results to return
61 fr_value_box_list_t list; //!< Where to put the parsed results
62 TALLOC_CTX *out_ctx; //!< CTX to allocate parsed results in
63 fr_timer_t *ev; //!< Event for timeout
65
66/*
67 * A mapping of configuration file names to internal variables.
68 */
69static const conf_parser_t module_config[] = {
70 { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_FILE_READABLE, rlm_unbound_t, filename), .dflt = "${modconfdir}/unbound/default.conf" },
71 { FR_CONF_OFFSET("timeout", rlm_unbound_t, timeout), .dflt = "3000" },
72 { FR_CONF_OFFSET_FLAGS("resolvconf", CONF_FLAG_FILE_READABLE, rlm_unbound_t, resolvconf) },
75};
76
78{
79 /*
80 * Cancel an outstanding async unbound call if the request is being freed
81 */
82 if ((ur->async_id != 0) && (ur->done == 0)) ub_cancel(ur->t->ev_b->ub, ur->async_id);
83
84 return 0;
85}
86
87/** Callback called by unbound when resolution started with ub_resolve_event() completes
88 *
89 * @param mydata the request tracking structure set up before ub_resolve_event() was called
90 * @param rcode should be the rcode from the reply packet, but appears not to be
91 * @param packet wire format reply packet
92 * @param packet_len length of wire format packet
93 * @param sec DNSSEC status code
94 * @param why_bogus String describing DNSSEC issue if sec = 1
95 * @param rate_limited Was the request rate limited due to unbound workload
96 */
97static void xlat_unbound_callback(void *mydata, int rcode, void *packet, int packet_len, int sec,
98 char *why_bogus
99#if UNBOUND_VERSION_MAJOR > 1 || (UNBOUND_VERSION_MAJOR == 1 && UNBOUND_VERSION_MINOR > 7)
100 , UNUSED int rate_limited
101#endif
102 )
103
104{
105 unbound_request_t *ur = talloc_get_type_abort(mydata, unbound_request_t);
106 request_t *request = ur->request;
107 fr_dbuff_t dbuff;
108 uint16_t qdcount = 0, ancount = 0, i, rdlength = 0;
109 uint8_t pktrcode = 0, skip = 0;
111 fr_value_box_t *vb;
112
113 /*
114 * Request has completed remove timeout event and set
115 * async_id to 0 so ub_cancel() is not called when ur is freed
116 */
117 FR_TIMER_DISARM(ur->ev);
118 ur->async_id = 0;
119
120 /*
121 * Bogus responses have the "sec" flag set to 1
122 */
123 if (sec == 1) {
124 RERROR("%s", why_bogus);
125 ur->done = -16;
126 goto resume;
127 }
128
129 RHEXDUMP4((uint8_t const *)packet, packet_len, "Unbound callback called with packet [length %d]", packet_len);
130
131 fr_dbuff_init(&dbuff, (uint8_t const *)packet, (size_t)packet_len);
132
133 /* Skip initial header entries */
134 fr_dbuff_advance(&dbuff, 3);
135
136 /*
137 * Extract rcode - it doesn't appear to be passed in as a
138 * parameter, contrary to the documentation...
139 */
140 fr_dbuff_out(&pktrcode, &dbuff);
141 rcode = pktrcode & 0x0f;
142 if (rcode != 0) {
143 ur->done = 0 - rcode;
144 REDEBUG("DNS rcode is %d", rcode);
145 goto resume;
146 }
147
148 fr_dbuff_out(&qdcount, &dbuff);
149 if (qdcount > 1) {
150 RERROR("DNS results packet with multiple questions");
151 ur->done = -32;
152 goto resume;
153 }
154
155 /* How many answer records do we have? */
156 fr_dbuff_out(&ancount, &dbuff);
157 RDEBUG4("Unbound returned %d answers", ancount);
158
159 /* Skip remaining header entries */
160 fr_dbuff_advance(&dbuff, 4);
161
162 /* Skip the QNAME */
163 fr_dbuff_out(&skip, &dbuff);
164 while (skip > 0) {
165 if (skip > 63) {
166 /*
167 * This is a pointer to somewhere else in the the packet
168 * Pointers use two octets
169 * Just move past the pointer to the next label in the question
170 */
171 fr_dbuff_advance(&dbuff, 1);
172 } else {
173 if (fr_dbuff_remaining(&dbuff) < skip) break;
174 fr_dbuff_advance(&dbuff, skip);
175 }
176 fr_dbuff_out(&skip, &dbuff);
177 }
178
179 /* Skip QTYPE and QCLASS */
180 fr_dbuff_advance(&dbuff, 4);
181
182 /* We only want a limited number of replies */
183 if (ancount > ur->count) ancount = ur->count;
184
185 fr_value_box_list_init(&ur->list);
186
187 /* Read the answer RRs */
188 for (i = 0; i < ancount; i++) {
189 fr_dbuff_out(&skip, &dbuff);
190 if (skip > 63) fr_dbuff_advance(&dbuff, 1);
191
192 /* Skip TYPE, CLASS and TTL */
193 fr_dbuff_advance(&dbuff, 8);
194
195 fr_dbuff_out(&rdlength, &dbuff);
196 RDEBUG4("RDLENGTH is %d", rdlength);
197
199 switch (ur->return_type) {
202 case FR_TYPE_OCTETS:
203 if (fr_value_box_from_network(ur->out_ctx, vb, ur->return_type, NULL,
204 &dbuff, rdlength, true) < 0) {
205 error:
206 talloc_free(vb);
207 fr_value_box_list_talloc_free(&ur->list);
208 ur->done = -32;
209 goto resume;
210 }
211 break;
212
213 case FR_TYPE_STRING:
214 if (ur->has_priority) {
215 /*
216 * This record type has a priority before the label
217 * add the priority first as a separate box
218 */
219 fr_value_box_t *priority_vb;
220 if (rdlength < 3) {
221 REDEBUG("Invalid data returned");
222 goto error;
223 }
224 MEM(priority_vb = fr_value_box_alloc_null(ur->out_ctx));
225 if (fr_value_box_from_network(ur->out_ctx, priority_vb, FR_TYPE_UINT16, NULL,
226 &dbuff, 2, true) < 0) {
227 talloc_free(priority_vb);
228 goto error;
229 }
230 fr_value_box_list_insert_tail(&ur->list, priority_vb);
231 }
232
233 /* String types require decoding of dns format labels */
234 used = fr_dns_label_to_value_box(ur->out_ctx, vb, (uint8_t const *)packet, packet_len,
235 (uint8_t const *)fr_dbuff_current(&dbuff), true, NULL);
236 if (used < 0) goto error;
237 fr_dbuff_advance(&dbuff, (size_t)used);
238 break;
239
240 default:
241 RERROR("No meaningful output type set");
242 goto error;
243 }
244
245 fr_value_box_list_insert_tail(&ur->list, vb);
246
247 }
248
249 ur->done = 1;
250
251resume:
253}
254
255/** Callback from our timeout event to cancel a request
256 *
257 */
259{
260 unbound_request_t *ur = talloc_get_type_abort(uctx, unbound_request_t);
261 request_t *request = ur->request;
262
263 REDEBUG("Timeout waiting for DNS resolution");
265
266 ur->timedout = true;
267}
268
269/*
270 * Xlat signal callback if an unbound request needs cancelling
271 */
272static void xlat_unbound_signal(xlat_ctx_t const *xctx, request_t *request, UNUSED fr_signal_t action)
273{
274 unbound_request_t *ur = talloc_get_type_abort(xctx->rctx, unbound_request_t);
275
276 FR_TIMER_DISARM(ur->ev);
277
278 RDEBUG2("Forcefully cancelling pending unbound request");
279}
280
281/*
282 * Xlat resume callback after unbound has either returned or timed out
283 * Move the parsed results to the xlat output cursor
284 */
286 xlat_ctx_t const *xctx,
287 request_t *request, UNUSED fr_value_box_list_t *in)
288{
289 fr_value_box_t *vb;
290 unbound_request_t *ur = talloc_get_type_abort(xctx->rctx, unbound_request_t);
291
292 /*
293 * Request timed out
294 */
295 if (ur->timedout) return XLAT_ACTION_FAIL;
296
297#define RCODEERROR(_code, _message) case _code: \
298 REDEBUG(_message, xctx->mctx->mi->name); \
299 goto error
300
301 /* Check for unbound errors */
302 switch (ur->done) {
303 case 1:
304 break;
305
306 default:
307 REDEBUG("Unknown DNS error");
308 error:
309 talloc_free(ur);
310 return XLAT_ACTION_FAIL;
311
312 RCODEERROR(0, "%s - No result");
313 RCODEERROR(-1, "%s - Query format error");
314 RCODEERROR(-2, "%s - DNS server failure");
315 RCODEERROR(-3, "%s - Nonexistent domain name");
316 RCODEERROR(-4, "%s - DNS server does not support query type");
317 RCODEERROR(-5, "%s - DNS server refused query");
318 RCODEERROR(-16, "%s - Bogus DNS response");
319 RCODEERROR(-32, "%s - Error parsing DNS response");
320 }
321
322 /*
323 * Move parsed results into xlat cursor
324 */
325 while ((vb = fr_value_box_list_pop_head(&ur->list))) {
327 }
328
329 talloc_free(ur);
330 return XLAT_ACTION_DONE;
331}
332
333
335 { .required = true, .concat = true, .type = FR_TYPE_STRING },
336 { .required = true, .concat = true, .type = FR_TYPE_STRING },
337 { .single = true, .type = FR_TYPE_UINT16 },
339};
340
341/** Perform a DNS lookup using libunbound
342 *
343 * @ingroup xlat_functions
344 */
346 xlat_ctx_t const *xctx,
347 request_t *request, fr_value_box_list_t *in)
348{
350 rlm_unbound_thread_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_unbound_thread_t);
351 fr_value_box_t *host_vb = fr_value_box_list_head(in);
352 fr_value_box_t *query_vb = fr_value_box_list_next(in, host_vb);
353 fr_value_box_t *count_vb = fr_value_box_list_next(in, query_vb);
355
356 if (host_vb->vb_length == 0) {
357 REDEBUG("Can't resolve zero length host");
358 return XLAT_ACTION_FAIL;
359 }
360
361 MEM(ur = talloc_zero(unlang_interpret_frame_talloc_ctx(request), unbound_request_t));
362 talloc_set_destructor(ur, _unbound_request_free);
363
364 /*
365 * Set the maximum number of records we want to return
366 */
367 if ((count_vb) && (count_vb->type == FR_TYPE_UINT16) && (count_vb->vb_uint16 > 0)) {
368 ur->count = count_vb->vb_uint16;
369 } else {
370 ur->count = UINT16_MAX;
371 }
372
373 ur->request = request;
374 ur->t = t;
375 ur->out_ctx = ctx;
376
377#define UB_QUERY(_record, _rrvalue, _return, _hasprio) \
378 if (strcmp(query_vb->vb_strvalue, _record) == 0) { \
379 ur->return_type = _return; \
380 ur->has_priority = _hasprio; \
381 ub_resolve_event(t->ev_b->ub, host_vb->vb_strvalue, _rrvalue, 1, ur, \
382 xlat_unbound_callback, &ur->async_id); \
383 }
384
385 /* coverity[dereference] */
386 UB_QUERY("A", 1, FR_TYPE_IPV4_ADDR, false)
387 else UB_QUERY("AAAA", 28, FR_TYPE_IPV6_ADDR, false)
388 else UB_QUERY("PTR", 12, FR_TYPE_STRING, false)
389 else UB_QUERY("MX", 15, FR_TYPE_STRING, true)
390 else UB_QUERY("SRV", 33, FR_TYPE_STRING, true)
391 else UB_QUERY("TXT", 16, FR_TYPE_STRING, false)
392 else UB_QUERY("CERT", 37, FR_TYPE_OCTETS, false)
393 else {
394 REDEBUG("Invalid / unsupported DNS query type");
395 return XLAT_ACTION_FAIL;
396 }
397
398 /*
399 * unbound returned before we yielded - run the callback
400 * This is when serving results from local data
401 */
402 if (ur->async_id == 0) {
403 xlat_ctx_t our_xctx = *xctx;
404
405 our_xctx.rctx = ur; /* Make the rctx available to the resume function */
406
407 return xlat_unbound_resume(ctx, out, &our_xctx, request, in);
408 }
409
410 if (fr_timer_in(ur, ur->t->ev_b->el->tl, &ur->ev, fr_time_delta_from_msec(inst->timeout),
411 false, xlat_unbound_timeout, ur) < 0) {
412 REDEBUG("Unable to attach unbound timeout_envent");
413 ub_cancel(t->ev_b->ub, ur->async_id);
414 return XLAT_ACTION_FAIL;
415 }
416
418}
419
421{
422 rlm_unbound_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_unbound_t);
423 rlm_unbound_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_unbound_thread_t);
424 int res;
425
426 t->inst = inst;
427 if (unbound_io_init(t, &t->ev_b, mctx->el) < 0) {
428 PERROR("Unable to create unbound event base");
429 return -1;
430 }
431
432 /*
433 * Ensure unbound uses threads
434 */
435 res = ub_ctx_async(t->ev_b->ub, 1);
436 if (res) {
437 error:
438 PERROR("%s", ub_strerror(res));
439 free_error:
440 talloc_free(t->ev_b);
441 return -1;
442 }
443
444 /*
445 * Load settings from the unbound config file
446 */
447 res = ub_ctx_config(t->ev_b->ub, UNCONST(char *, inst->filename));
448 if (res) goto error;
449
450 if (unbound_log_init(t, &t->u_log, t->ev_b->ub) < 0) {
451 PERROR("Failed to initialise unbound log");
452 goto free_error;
453 }
454
455 /*
456 * Load resolv.conf if specified
457 */
458 if (inst->resolvconf) ub_ctx_resolvconf(t->ev_b->ub, inst->resolvconf);
459
460 /*
461 * Load hosts file if specified
462 */
463 if (inst->hosts) ub_ctx_hosts(t->ev_b->ub, inst->hosts);
464
465 /*
466 * The unbound context needs to be "finalised" to fix its settings.
467 * The API does not expose a method to do this, rather it happens on first
468 * use. A quick workaround is to delete data which won't be present
469 */
470 ub_ctx_data_remove(t->ev_b->ub, "notar33lsite.foo123.nottld A 127.0.0.1");
471
472 return 0;
473}
474
476{
477 rlm_unbound_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_unbound_thread_t);
478
479 talloc_free(t->u_log);
480 talloc_free(t->ev_b);
481
482 return 0;
483}
484
485static int mod_bootstrap(module_inst_ctx_t const *mctx)
486{
487 rlm_unbound_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_unbound_t);
488 xlat_t *xlat;
489
490 if (inst->timeout > 10000) {
491 cf_log_err(mctx->mi->conf, "timeout must be 0 to 10000");
492 return -1;
493 }
494
495 if(!(xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, NULL, xlat_unbound, FR_TYPE_VOID))) return -1;
497
498 return 0;
499}
500
503 .common = {
504 .magic = MODULE_MAGIC_INIT,
505 .name = "unbound",
506 .inst_size = sizeof(rlm_unbound_t),
508 .bootstrap = mod_bootstrap,
509
510 .thread_inst_size = sizeof(rlm_unbound_thread_t),
511 .thread_inst_type = "rlm_unbound_thread_t",
512 .thread_instantiate = mod_thread_instantiate,
513 .thread_detach = mod_thread_detach
514 }
515};
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:506
#define UNUSED
Definition build.h:336
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#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:280
#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:268
@ CONF_FLAG_FILE_READABLE
File matching value must exist, and must be readable.
Definition cf_parse.h:435
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
Definition dbuff.h:1081
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
Definition dbuff.h:919
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
Definition dbuff.h:362
#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:751
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
Definition dbuff.h:1808
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:46
static fr_slen_t in
Definition dict.h:882
#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:1224
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.
talloc_free(hp)
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:1636
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1681
#define PERROR(_fmt,...)
Definition log.h:228
#define RHEXDUMP4(_data, _len, _fmt,...)
Definition log.h:718
#define RERROR(fmt,...)
Definition log.h:310
#define RDEBUG4(fmt,...)
Definition log.h:356
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:247
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:469
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:163
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
int async_id
Id of async query.
Definition rlm_unbound.c:52
uint16_t count
Number of results to return.
Definition rlm_unbound.c:60
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:97
#define RCODEERROR(_code, _message)
fr_value_box_list_t list
Where to put the parsed results.
Definition rlm_unbound.c:61
TALLOC_CTX * out_ctx
CTX to allocate parsed results in.
Definition rlm_unbound.c:62
int done
Indicator that the callback has been called Negative values indicate errors.
Definition rlm_unbound.c:55
bool timedout
Request timedout.
Definition rlm_unbound.c:57
static int _unbound_request_free(unbound_request_t *ur)
Definition rlm_unbound.c:77
char const * filename
Unbound configuration file.
Definition rlm_unbound.c:40
static int mod_bootstrap(module_inst_ctx_t const *mctx)
#define UB_QUERY(_record, _rrvalue, _return, _hasprio)
fr_timer_t * ev
Event for timeout.
Definition rlm_unbound.c:63
bool has_priority
Does the returned data start with a priority field.
Definition rlm_unbound.c:59
rlm_unbound_t * inst
Instance data.
Definition rlm_unbound.c:47
static void xlat_unbound_timeout(UNUSED fr_timer_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:58
unbound_io_event_base_t * ev_b
Unbound event base.
Definition rlm_unbound.c:46
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:42
request_t * request
Current request being processed.
Definition rlm_unbound.c:53
static const conf_parser_t module_config[]
Definition rlm_unbound.c:69
rlm_unbound_thread_t * t
Thread running this request.
Definition rlm_unbound.c:54
char const * resolvconf
resolv.conf file to use
Definition rlm_unbound.c:41
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:48
uint32_t timeout
Definition rlm_unbound.c:38
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
void * boot
Data allocated during the boostrap phase.
Definition module.h:296
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:110
static fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
Definition time.h:575
"server local" time.
Definition time.h:69
An event timer list.
Definition timer.c:49
A timer event.
Definition timer.c:83
#define fr_timer_in(...)
Definition timer.h:87
#define FR_TIMER_DISARM(_ev)
Definition timer.h:91
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:543
unsigned int required
Argument must be present, and non-empty.
Definition xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:170
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 consumed by an xlat function.
Definition xlat.h:145
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:1892
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:655
static size_t char ** out
Definition value.h:1030
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:363