26 RCSID(
"$Id: 6893a40d066975062bf3ea885e90d3b7659add3d $")
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");
398 switch (
inst->log_dst) {
400 DEBUG2(
"Opening UNIX socket at \"%s\"",
inst->unix_sock.path);
406 DEBUG2(
"Opening TCP connection to %pV:%u",
413 DEBUG2(
"Opening UDP connection to %pV:%u",
431 MEM(fd_s = talloc(conn,
int));
457 char const *
fmt, va_list ap,
void *
uctx)
490 dst = request->log.dst;
491 request->log.dst = NULL;
492 if (
tmpl_aexpand(t, &exp, request,
inst->log_fmt, NULL, NULL) < 0)
goto finish;
493 request->log.dst = dst;
530 for (dst = request->log.dst; dst; dst = dst->
next) {
579 .init = _logtee_conn_init,
580 .open = _logtee_conn_open,
581 .close = _logtee_conn_close
584 .connection_timeout = inst->connection_timeout,
585 .reconnection_delay = inst->reconnection_delay
588 if (t->
conn == NULL)
return -1;
607 if (
inst->file.escape) {
619 snprintf(prefix,
sizeof(prefix),
"rlm_logtee (%s)",
inst->name);
627 switch (
inst->log_dst) {
633 #ifndef HAVE_SYS_UN_H
634 cf_log_err(
conf,
"Unix sockets are not supported on this system");
649 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,...)
@ CONNECTION_STATE_FAILED
Connection has failed.
@ CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
@ CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
@ 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.
fr_dcursor_eval_t void const * uctx
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.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
#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.
ssize_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.
ssize_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.
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 module calls.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
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.
bool pending
We have pending messages to write.
static size_t logtee_dst_table_len
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 connection_state_t _logtee_conn_open(UNUSED fr_event_list_t *el, UNUSED void *h, void *uctx)
Process notification that fd is open.
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.
CC_NO_UBSAN(function)
Initialise a new outbound connection.
fr_ipaddr_t dst_ipaddr
Network server.
connection_t * conn
Connection to our log destination.
static const conf_parser_t module_config[]
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.
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
void connection_signal_reconnect(connection_t *conn, connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
int connection_signal_on_fd(connection_t *conn, int fd)
Setup the connection to change states to connected or failed based on I/O events.
void connection_signal_init(connection_t *conn)
Asynchronously signal a halted connection to start.
connection_t * connection_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, connection_funcs_t const *funcs, connection_conf_t const *conf, char const *log_prefix, void const *uctx)
Allocate a new connection.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
#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))