25 RCSID(
"$Id: 14a4371bf4a4ef91a23980d43956188a8af52813 $")
27 #define LOG_PREFIX mctx->mi->name
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>
100 #
if UNBOUND_VERSION_MAJOR > 1 || (UNBOUND_VERSION_MAJOR == 1 && UNBOUND_VERSION_MINOR > 7)
109 uint16_t qdcount = 0, ancount = 0, i, rdlength = 0;
110 uint8_t pktrcode = 0, skip = 0;
130 RHEXDUMP4((
uint8_t const *)packet, packet_len,
"Unbound callback called with packet [length %d]", packet_len);
142 rcode = pktrcode & 0x0f;
144 ur->
done = 0 - rcode;
145 REDEBUG(
"DNS rcode is %d", rcode);
151 RERROR(
"DNS results packet with multiple questions");
158 RDEBUG4(
"Unbound returned %d answers", ancount);
186 fr_value_box_list_init(&ur->
list);
189 for (i = 0; i < ancount; i++) {
197 RDEBUG4(
"RDLENGTH is %d", rdlength);
205 &dbuff, rdlength,
true) < 0) {
208 fr_value_box_list_talloc_free(&ur->
list);
222 REDEBUG(
"Invalid data returned");
227 &dbuff, 2,
true) < 0) {
231 fr_value_box_list_insert_tail(&ur->
list, priority_vb);
237 if (
used < 0)
goto error;
242 RERROR(
"No meaningful output type set");
246 fr_value_box_list_insert_tail(&ur->
list, vb);
264 REDEBUG(
"Timeout waiting for DNS resolution");
279 RDEBUG2(
"Forcefully cancelling pending unbound request");
298 #define RCODEERROR(_code, _message) case _code: \
299 REDEBUG(_message, xctx->mctx->mi->name); \
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");
320 RCODEERROR(-32,
"%s - Error parsing DNS response");
326 while ((vb = fr_value_box_list_pop_head(&ur->
list))) {
357 if (host_vb->vb_length == 0) {
358 REDEBUG(
"Can't resolve zero length host");
368 if ((count_vb) && (count_vb->type ==
FR_TYPE_UINT16) && (count_vb->vb_uint16 > 0)) {
369 ur->
count = count_vb->vb_uint16;
371 ur->
count = UINT16_MAX;
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); \
395 REDEBUG(
"Invalid / unsupported DNS query type");
413 REDEBUG(
"Unable to attach unbound timeout_envent");
429 PERROR(
"Unable to create unbound event base");
436 res = ub_ctx_async(t->
ev_b->
ub, 1);
439 PERROR(
"%s", ub_strerror(res));
452 PERROR(
"Failed to initialise unbound log");
459 if (
inst->resolvconf) ub_ctx_resolvconf(t->
ev_b->
ub,
inst->resolvconf);
471 ub_ctx_data_remove(t->
ev_b->
ub,
"notar33lsite.foo123.nottld A 127.0.0.1");
491 if (
inst->timeout > 10000) {
512 .thread_inst_type =
"rlm_unbound_thread_t",
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define CONF_PARSER_TERMINATOR
#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
#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
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Defines a CONF_PAIR to C data type mapping.
#define cf_log_err(_cf, _fmt,...)
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
fr_dcursor_eval_t void const * uctx
static fr_time_delta_t timeout
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
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.
#define fr_event_timer_in(...)
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.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
#define RHEXDUMP4(_data, _len, _fmt,...)
int fr_event_timer_delete(fr_event_timer_t const **ev_p)
Delete a timer event from the event list.
Stores all information relating to an event list.
@ 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_OCTETS
Raw octets.
module_instance_t const * mi
Instance of the module being instantiated.
void * thread
Thread specific instance data.
fr_event_list_t * el
Event list to register any IO handlers and timers against.
void * thread
Thread instance data.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
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)
module_t common
Common fields presented by all modules.
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.
Function prototypes and datatypes for the REST (HTTP) transport.
struct ub_ctx * ub
Unbound ctx instantiated from this event base.
fr_event_list_t * el
Event loop events should be inserted into.
Wrapper around our event loop specifying callbacks for creating new event handles.
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.
Function prototypes and datatypes for the REST (HTTP) transport.
static const conf_parser_t config[]
int async_id
Id of async query.
uint16_t count
Number of results to return.
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.
#define RCODEERROR(_code, _message)
fr_value_box_list_t list
Where to put the parsed results.
TALLOC_CTX * out_ctx
CTX to allocate parsed results in.
int done
Indicator that the callback has been called Negative values indicate errors.
bool timedout
Request timedout.
static int _unbound_request_free(unbound_request_t *ur)
char const * filename
Unbound configuration file.
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.
bool has_priority
Does the returned data start with a priority field.
rlm_unbound_t * inst
Instance data.
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.
unbound_io_event_base_t * ev_b
Unbound event base.
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
request_t * request
Current request being processed.
static const conf_parser_t module_config[]
rlm_unbound_thread_t * t
Thread running this request.
char const * resolvconf
resolv.conf file to use
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
unbound_log_t * u_log
Unbound log structure.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
void * boot
Data allocated during the boostrap phase.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
#define talloc_get_type_abort_const
static fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
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.
bool required
Argument must be present, and non-empty.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
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.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
static size_t char ** out
void * rctx
Resume context.
module_ctx_t const * mctx
Synthesised module calling ctx.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.