26 RCSID(
"$Id: 1c373916d2d1fc60836177b635694370b12e7f44 $")
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/server/module_rlm.h>
30 #include <freeradius-devel/util/debug.h>
31 #include <freeradius-devel/server/connection.h>
94 char const *group_str;
205 char const *
fmt, va_list ap,
void *uctx)
274 slen = write(sock,
msg, talloc_array_length(
msg) - 1) ;
279 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
305 if (slen < 0)
goto write_error;
319 int fd = *((
int *)t->
conn->h);
321 DEBUG3(
"Marking socket (%i) as idle", fd);
327 PERROR(
"Failed inserting FD event");
339 int fd = *((
int *)t->
conn->h);
341 DEBUG3(
"Marking socket (%i) as active - Draining requests", fd);
347 PERROR(
"Failed inserting FD event");
356 int fd = *((
int *)h);
358 DEBUG3(
"Closing socket (%i)", fd);
359 if (shutdown(fd, SHUT_RDWR) < 0)
DEBUG3(
"Shutdown on socket (%i) failed: %s", fd,
fr_syserror(errno));
370 DEBUG2(
"Socket connected");
397 switch (
inst->log_dst) {
399 DEBUG2(
"Opening UNIX socket at \"%s\"",
inst->unix_sock.path);
405 DEBUG2(
"Opening TCP connection to %pV:%u",
412 DEBUG2(
"Opening UDP connection to %pV:%u",
430 MEM(fd_s = talloc(conn,
int));
456 char const *
fmt, va_list ap,
void *uctx)
489 dst = request->log.dst;
490 request->log.dst = NULL;
491 if (
tmpl_aexpand(t, &exp, request,
inst->log_fmt, NULL, NULL) < 0)
goto finish;
492 request->log.dst = dst;
529 for (dst = request->log.dst; dst; dst = dst->
next) {
578 .init = _logtee_conn_init,
579 .open = _logtee_conn_open,
580 .close = _logtee_conn_close
583 .connection_timeout = inst->connection_timeout,
584 .reconnection_delay = inst->reconnection_delay
587 if (t->
conn == NULL)
return -1;
606 if (
inst->file.escape) {
618 snprintf(prefix,
sizeof(prefix),
"rlm_logtee (%s)",
inst->name);
626 switch (
inst->log_dst) {
632 #ifndef HAVE_SYS_UN_H
633 cf_log_err(
conf,
"Unix sockets are not supported on this system");
648 inst->delimiter_len = talloc_array_length(
inst->delimiter) - 1;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
static int const char char buffer[256]
static int const char * fmt
#define L(_str)
Helper for initialising arrays of string literals.
#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_SIZE_BOUND_CHECK(_name, _var, _op, _bound)
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
#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
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_FILE_OUTPUT
File matching value must exist, and must be writable.
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
@ CONF_FLAG_XLAT
string will be dynamically expanded.
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
@ FR_CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
@ FR_CONNECTION_STATE_FAILED
Connection has failed.
@ FR_CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
@ FR_CONNECTION_FAILED
Connection is being reconnected because it failed.
Holds a complete set of functions for a connection.
static void * fr_dcursor_remove(fr_dcursor_t *cursor)
Remove the current item.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
static int fr_dcursor_prepend(fr_dcursor_t *cursor, void *v)
Insert a single item at the start of the list.
static void * fr_dcursor_head(fr_dcursor_t *cursor)
Rewind cursor to the start of the list.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
CONF_SECTION *_CONST conf
Module's instance configuration.
#define fr_event_fd_insert(...)
void * fr_fring_next(fr_fring_t *fring)
Remove an item from the buffer.
fr_fring_t * fr_fring_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock)
Initialise a ring buffer with fixed element size.
int fr_fring_overwrite(fr_fring_t *fring, void *in)
Insert a new item into the circular buffer, freeing the tail if we hit it.
Standard thread safe circular buffer.
void * uctx
Context to pass to the logging function.
log_dst_t * next
Next logging destination.
log_func_t func
Function to call to log to this destination.
size_t rad_filename_make_safe(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Ensures that a filename cannot walk up the directory structure.
size_t rad_filename_escape(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Escapes the raw string such that it should be safe to use as part of a file path.
Stores all information relating to an event list.
size_t(* xlat_escape_legacy_t)(request_t *request, char *out, size_t outlen, char const *in, void *arg)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
void * thread
Thread specific instance data.
fr_event_list_t * el
Event list to register any IO handlers and timers against.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
void * thread
Thread instance data.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
Specifies a module method identifier.
module_t common
Common fields presented by all modules.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
#define RETURN_MODULE_NOOP
rlm_rcode_t
Return codes indicating the result of the module call.
static void logtee_it(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt, va_list ap, void *uctx))
static void logtee_fd_idle(rlm_logtee_thread_t *t)
Set the socket to idle.
fr_ipaddr_t src_ipaddr
Send requests from a given src_ipaddr.
static void _logtee_conn_error(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, int fd_errno, void *uctx)
Connection errored.
logtee_dst_t log_dst
Logging destination.
static void logtee_fd_active(rlm_logtee_thread_t *t)
Set the socket to active.
static void _logtee_conn_close(UNUSED fr_event_list_t *el, void *h, UNUSED void *uctx)
Shutdown/close a file descriptor.
static fr_dict_attr_t const * attr_log_type
static const conf_parser_t file_config[]
char const * name
Module instance name.
char const * log_dst_str
Logging destination string.
static fr_dict_attr_t const * attr_log_message
static fr_dict_t const * dict_freeradius
char const * delimiter
Line termination string (usually ).
static fr_dict_attr_t const * attr_log_level
size_t buffer_depth
How big our circular buffer should be.
fr_pair_t * msg
Temporary value pair holding the message value.
fr_dict_attr_autoload_t rlm_logtee_dict_attr[]
static void _logtee_conn_writable(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
There's space available to write data, so do that...
static const conf_parser_t udp_config[]
tmpl_t * log_fmt
Source of log messages.
fr_fring_t * fring
Circular buffer used to batch up messages.
fr_time_delta_t connection_timeout
How long to wait to open a socket.
static fr_table_num_sorted_t const logtee_dst_table[]
fr_dict_autoload_t rlm_logtee_dict[]
fr_pair_t * type
Temporary value pair holding the message type.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Create thread-specific connections and buffers.
static fr_connection_state_t _logtee_conn_init(void **h_out, fr_connection_t *conn, void *uctx)
Initialise a new outbound connection.
bool pending
We have pending messages to write.
static size_t logtee_dst_table_len
static fr_connection_state_t _logtee_conn_open(UNUSED fr_event_list_t *el, UNUSED void *h, void *uctx)
Process notification that fd is open.
fr_pair_t * lvl
Temporary value pair holding the log lvl.
@ LOGTEE_DST_FILE
Log to a file.
@ LOGTEE_DST_TCP
Log via TCP.
@ LOGTEE_DST_UNIX
Log via Unix socket.
@ LOGTEE_DST_UDP
Log via UDP.
logtee_net_t tcp
TCP server.
static unlang_action_t mod_insert_logtee(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Add our logging destination to the linked list of logging destinations (if it doesn't already exist)
fr_event_list_t * el
This thread's event list.
fr_ipaddr_t dst_ipaddr
Network server.
static const conf_parser_t module_config[]
fr_connection_t * conn
Connection to our log destination.
static const conf_parser_t unix_config[]
logtee_net_t udp
UDP server.
size_t delimiter_len
Length of line termination string.
static int mod_instantiate(module_inst_ctx_t const *mctx)
fr_time_delta_t reconnection_delay
How long to wait to retry.
uint16_t port
Network port.
TALLOC_CTX * msg_pool
A 1k talloc pool to hold the log message whilst it's being expanded.
rlm_logtee_t const * inst
Instance of logtee.
static void _logtee_conn_read(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
Drain any data we received.
static const conf_parser_t tcp_config[]
Per-thread instance data.
void fr_connection_signal_init(fr_connection_t *conn)
Asynchronously signal a halted connection to start.
int fr_connection_signal_on_fd(fr_connection_t *conn, int fd)
Setup the connection to change states to connected or failed based on I/O events.
fr_connection_t * fr_connection_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, fr_connection_funcs_t const *funcs, fr_connection_conf_t const *conf, char const *log_prefix, void const *uctx)
Allocate a new connection.
void fr_connection_signal_reconnect(fr_connection_t *conn, fr_connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
#define MODULE_NAME_TERMINATOR
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
int fr_socket_client_udp(char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected UDP socket.
int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
Stores an attribute, a value and various bits of other data.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Call talloc vasprintf, setting the type on the new chunk correctly.
A time delta, a difference in time measured in nanoseconds.
static fr_event_list_t * el
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
int fr_value_box_bstrdup_buffer_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a talloced buffer containing a nul terminated string to a box, but don't copy it.
#define fr_box_ipaddr(_val)
int format(printf, 5, 0))