25 RCSID(
"$Id: 5f3de7e110fe4b8d0ec8f5b1041450db4d9dc70b $")
27 #include <freeradius-devel/io/control.h>
28 #include <freeradius-devel/io/ring_buffer.h>
29 #include <freeradius-devel/util/strerror.h>
30 #include <freeradius-devel/util/syserror.h>
31 #include <freeradius-devel/util/misc.h>
32 #include <freeradius-devel/util/rand.h>
36 #include <sys/event.h>
38 #define FR_CONTROL_MAX_TYPES (32)
44 #define MPRINT(...) fprintf(stderr, __VA_ARGS__)
96 char read_buffer[256];
99 num = read(fd, read_buffer,
sizeof(read_buffer));
100 if (num <= 0)
return;
104 for (i = 0; i < num; i++) {
109 if (!message_size)
return;
161 if (pipe((
int *) &c->
pipe) < 0) {
202 size_t room, message_size;
206 if (room == 0)
break;
221 message_size =
sizeof(*m);
224 message_size &= ~(
size_t) 63;
257 message_size =
sizeof(*m);
258 message_size += data_size;
260 message_size &= ~(
size_t) 63;
277 memcpy(p +
sizeof(*m),
data, data_size);
304 MPRINT(
"CONTROL push aq %p\n", c->
aq);
356 while (write(c->
pipe[1],
".", 1) == 0) {
392 if (data_size < m->data_size) {
399 memcpy(
data, p +
sizeof(*m), data_size);
429 if ((c->
type[
id].
ctx == ctx) &&
482 talloc_set_destructor(c, NULL);
bool fr_atomic_queue_pop(fr_atomic_queue_t *aq, void **p_data)
Pop a pointer from the atomic queue.
bool fr_atomic_queue_push(fr_atomic_queue_t *aq, void *data)
Push a pointer into the atomic queue.
Structure to hold the atomic queue.
void(* fr_control_callback_t)(void *ctx, void const *data, size_t data_size, fr_time_t now)
static fr_ring_buffer_t * rb
static fr_atomic_queue_t * aq
fr_dcursor_eval_t void const * uctx
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
#define fr_event_fd_insert(...)
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
fr_atomic_queue_t * aq
destination AQ
int fr_control_gc(UNUSED fr_control_t *c, fr_ring_buffer_t *rb)
Clean up messages in a control-plane buffer.
ssize_t fr_control_message_pop(fr_atomic_queue_t *aq, uint32_t *p_id, void *data, size_t data_size)
Pop control-plane message.
#define FR_CONTROL_MAX_TYPES
static int _control_free(fr_control_t *c)
Free a control structure.
static fr_control_message_t * fr_control_message_alloc(fr_control_t *c, fr_ring_buffer_t *rb, uint32_t id, void *data, size_t data_size)
Allocate a control message.
bool same_thread
are the two ends in the same thread
fr_event_list_t * el
our event list
void * ctx
context for the callback
fr_control_message_status_t status
status of this message
fr_control_t * fr_control_create(TALLOC_CTX *ctx, fr_event_list_t *el, fr_atomic_queue_t *aq)
Create a control-plane signaling path.
int fr_control_callback_add(fr_control_t *c, uint32_t id, void *ctx, fr_control_callback_t callback)
Register a callback for an ID.
int fr_control_message_send(fr_control_t *c, fr_ring_buffer_t *rb, uint32_t id, void *data, size_t data_size)
Send a control-plane message.
int fr_control_message_push(fr_control_t *c, fr_ring_buffer_t *rb, uint32_t id, void *data, size_t data_size)
Push a control-plane message.
fr_control_callback_t callback
the function to call
uint32_t id
id of this callback
static void pipe_read(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
fr_control_ctx_t type[FR_CONTROL_MAX_TYPES]
callbacks
size_t data_size
size of the data we're sending
fr_control_message_status_t
Status of control messages.
@ FR_CONTROL_MESSAGE_DONE
the message is done (set only by receiver)
@ FR_CONTROL_MESSAGE_FREE
the message is free
@ FR_CONTROL_MESSAGE_USED
the message is used (set only by originator)
uint32_t id
ID of this message.
int fr_control_same_thread(fr_control_t *c)
int fr_control_callback_delete(fr_control_t *c, uint32_t id)
Delete a callback for an ID.
The header for the control message.
int fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uintptr_t armour)
Unarmour an FD.
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
int fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uintptr_t armour)
Armour an FD.
Stores all information relating to an event list.
int fr_ring_buffer_free(fr_ring_buffer_t *rb, size_t size_to_free)
Mark data as free,.
size_t fr_ring_buffer_used(fr_ring_buffer_t *rb)
Get the amount of data used in a ring buffer.
int fr_ring_buffer_start(fr_ring_buffer_t *rb, uint8_t **p_start, size_t *p_size)
Get a pointer to the data at the start of the ring buffer.
uint8_t * fr_ring_buffer_alloc(fr_ring_buffer_t *rb, size_t size)
Mark data as allocated.
#define fr_time()
Allow us to arbitrarily manipulate time.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
static fr_event_list_t * el
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)