The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
channel.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: 0117fc4ee8ac04aefeb3a019b47f781a44ff0a45 $
20 *
21 * @file io/channel.h
22 * @brief 2-way channels based on kqueue and atomic queues.
23 *
24 * @copyright 2016 Alan DeKok (aland@freeradius.org)
25 */
26RCSIDH(channel_h, "$Id: 0117fc4ee8ac04aefeb3a019b47f781a44ff0a45 $")
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#include <freeradius-devel/util/table.h>
33
34/**
35 * A two-way channel (i.e. pipe) for exchanging information
36 *
37 * While the channels are two-way, they are designed to have a
38 * "frontend" writing requests to the channel, and a "worker" reading
39 * requests, and writing replies back to the frontend.
40 */
42
43/*
44 * Forward declaration until such time as we fix the code so that
45 * the network threads can push transports to worker threads.
46 */
47typedef struct fr_listen_s fr_listen_t;
49
50#ifdef __cplusplus
51}
52#endif
53
54#include <freeradius-devel/io/base.h>
55#include <freeradius-devel/io/atomic_queue.h>
56#include <freeradius-devel/io/control.h>
57#include <freeradius-devel/io/message.h>
58#include <freeradius-devel/util/dlist.h>
59#include <freeradius-devel/util/heap.h>
60#include <freeradius-devel/util/log.h>
61
62#include <sys/types.h>
63#include <sys/event.h>
64
65#ifdef __cplusplus
66extern "C" {
67#endif
68
69/** Events channels send, in the FR_CONTROL_EVENTSET_CHANNEL event set
70 *
71 * The control plane dispatches each to its own callback, see
72 * fr_channel_callbacks_add().
73 */
75 FR_CHANNEL_CONTROL_DATA_TO_RESPONDER = 0, //!< Requests are queued for the responder.
76 FR_CHANNEL_CONTROL_DATA_TO_REQUESTOR, //!< Replies are queued for the requestor.
77 FR_CHANNEL_CONTROL_DATA_DONE_RESPONDER, //!< The responder has serviced its requests, and says
78 ///< how many it has seen. Replies may be waiting.
79 FR_CHANNEL_CONTROL_OPEN, //!< A requestor has opened a channel to the responder.
80 FR_CHANNEL_CONTROL_CLOSE, //!< The requestor is closing the channel.
81 FR_CHANNEL_CONTROL_CLOSE_ACK //!< The responder has finished closing it.
83
84/** Statistics for the channel
85 *
86 */
87typedef struct {
88 uint64_t outstanding; //!< Number of outstanding requests with no reply.
89 uint64_t signals; //!< Number of kevent signals we've sent.
90 uint64_t resignals; //!< Number of signals resent.
91 uint64_t spurious; //!< Number of signals we received which found no data waiting.
92
93 uint64_t packets; //!< Number of actual data packets.
94
95 uint64_t kevents; //!< Number of times we've looked at kevents.
96
97 fr_time_t last_write; //!< Last write to the channel.
98 fr_time_t last_read_other; //!< Last time we successfully read a message from the other the channel
99 fr_time_delta_t message_interval; //!< Interval between messages.
100
101 fr_time_t last_sent_signal; //!< The last time when we signaled the other end.
103
104
105/**
106 * Channel information which is added to a message.
107 *
108 * The messages are just for exchanging packet data. The channel
109 * data structure is for exchanging requests and replies.
110 */
111typedef struct {
112 fr_message_t m; //!< the message header
113
114 union {
115 /*
116 * Messages have a sequence number / ack while
117 * they're in a channel.
118 */
119 struct {
120 uint64_t sequence; //!< sequence number
121 uint64_t ack; //!< ACK of the sequence number from the other end
122 } live;
123
124 /*
125 * Once messages are pulled out of a channel by
126 * the scheduler, we need to cache the channel
127 * somewhere. So we cache it in fields which are now unused.
128 */
129 struct {
130 fr_channel_t *ch; //!< channel where this messages was received
131 fr_heap_index_t heap_id; //!< for the various queues
132 } channel;
133 };
134
135 union {
136 struct {
137 fr_time_t recv_time; //!< time original request was received (network -> worker)
138 } request;
139
140 struct {
141 fr_time_delta_t cpu_time; //!< Total CPU time, including predicted work, (only worker -> network).
142 fr_time_delta_t processing_time; //!< Actual processing time for this packet (only worker -> network).
143 fr_time_t request_time; //!< Timestamp of the request packet.
144 } reply;
145 };
146
147 uint32_t priority; //!< Priority of this packet.
148
149 void *packet_ctx; //!< Packet specific context for holding client
150 //!< information, and other proto_* specific information
151 //!< that needs to be passed to the request.
152
153 fr_listen_instance_t *inst; //!< for tracking packet transport, etc.
155
156#define PRIORITY_NOW (1 << 16)
157#define PRIORITY_HIGH (1 << 15)
158#define PRIORITY_NORMAL (1 << 14)
159#define PRIORITY_LOW (1 << 13)
160
162extern size_t channel_signals_len;
164extern size_t channel_packet_priority_len;
165
166fr_channel_t *fr_channel_create(TALLOC_CTX *ctx, fr_control_t *frontend, fr_control_t *worker, bool same) CC_HINT(nonnull);
167
170
173
175
176typedef void (*fr_channel_recv_callback_t)(fr_channel_t *ch, fr_channel_data_t *cd, void *uctx);
177int fr_channel_set_recv_reply(fr_channel_t *ch, fr_channel_recv_callback_t recv_reply, void *uctx) CC_HINT(nonnull(1,2));
178int fr_channel_set_recv_request(fr_channel_t *ch, fr_channel_recv_callback_t recv_request, void *uctx) CC_HINT(nonnull(1,2));
179
180int fr_channel_service_kevent(fr_channel_t *ch, fr_control_t *c, struct kevent const *kev) CC_HINT(nonnull);
181
182/** Called on a responder when a requestor opens a channel to it
183 *
184 * @param[in] ch the new channel.
185 * @param[in] reply_ms the message set the responder allocates replies from.
186 * @param[in] now the current time.
187 * @param[in] uctx registered with the callbacks.
188 */
189typedef void (*fr_channel_open_t)(fr_channel_t *ch, fr_message_set_t *reply_ms, fr_time_t now, void *uctx);
190
191/** Called on a responder when the requestor closes a channel
192 *
193 * The responder calls fr_channel_responder_ack_close() once it has
194 * finished with the channel.
195 *
196 * @param[in] ch the channel.
197 * @param[in] now the current time.
198 * @param[in] uctx registered with the callbacks.
199 */
200typedef void (*fr_channel_close_t)(fr_channel_t *ch, fr_time_t now, void *uctx);
201
202/** Called on a requestor when the responder has finished closing a channel
203 *
204 * @param[in] ch the channel.
205 * @param[in] now the current time.
206 * @param[in] uctx registered with the callbacks.
207 */
208typedef void (*fr_channel_closed_t)(fr_channel_t *ch, fr_time_t now, void *uctx);
209
210/** What the owner of a control plane does with channel lifecycle events
211 *
212 * Data arriving on a channel is drained by the channel code itself,
213 * through the callbacks set with fr_channel_set_recv_request() and
214 * fr_channel_set_recv_reply(). Only the lifecycle events reach the
215 * owner. A responder gets open and close, a requestor gets closed.
216 * Leave the others NULL.
217 */
223
225 void *uctx) CC_HINT(nonnull);
226
227bool fr_channel_active(fr_channel_t *ch) CC_HINT(nonnull);
228
230
232unsigned int fr_channel_responder_discard(fr_channel_t *ch) CC_HINT(nonnull);
233
235
236void fr_channel_responder_uctx_add(fr_channel_t *ch, void *ctx) CC_HINT(nonnull);
238void fr_channel_requestor_uctx_add(fr_channel_t *ch, void *ctx) CC_HINT(nonnull);
240
243
244
245void fr_channel_stats_log(fr_channel_t const *ch, fr_log_t const *log, char const *file, int line);
246
247#ifdef __cplusplus
248}
249#endif
void int line
Definition acutest.h:810
static uint8_t request[4]
static uint8_t reply[4]
#define RCSIDH(h, id)
Definition build.h:604
A full channel, which consists of two ends.
Definition channel.c:129
void * fr_channel_requestor_uctx_get(fr_channel_t *ch)
Get network-specific data from a channel.
Definition channel.c:982
fr_message_t m
the message header
Definition channel.h:112
int fr_channel_service_kevent(fr_channel_t *ch, fr_control_t *c, struct kevent const *kev)
void fr_channel_responder_uctx_add(fr_channel_t *ch, void *ctx)
Add responder-specific data to a channel.
Definition channel.c:945
fr_channel_stats_t const * fr_channel_responder_stats(fr_channel_t const *ch)
Statistics for the responder's end of a channel.
Definition channel.c:1063
fr_table_num_sorted_t const channel_signals[]
Definition channel.c:138
void * packet_ctx
Packet specific context for holding client information, and other proto_* specific information that n...
Definition channel.h:149
bool fr_channel_recv_reply(fr_channel_t *ch)
Receive a reply message from the channel.
Definition channel.c:354
fr_time_delta_t message_interval
Interval between messages.
Definition channel.h:99
int fr_channel_send_request(fr_channel_t *ch, fr_channel_data_t *cm)
Send a request message into the channel.
Definition channel.c:271
unsigned int fr_channel_responder_discard(fr_channel_t *ch)
Discard any requests the requestor queued but we never received.
Definition channel.c:895
size_t channel_signals_len
Definition channel.c:146
size_t channel_packet_priority_len
Definition channel.c:154
int fr_channel_signal_open(fr_channel_t *ch, fr_message_set_t *reply_ms)
Send a channel to a responder.
Definition channel.c:1013
void(* fr_channel_close_t)(fr_channel_t *ch, fr_time_t now, void *uctx)
Called on a responder when the requestor closes a channel.
Definition channel.h:200
uint64_t packets
Number of actual data packets.
Definition channel.h:93
int fr_channel_signal_responder_close(fr_channel_t *ch)
Signal a responder that the channel is closing.
Definition channel.c:862
fr_channel_control_event_t
Events channels send, in the FR_CONTROL_EVENTSET_CHANNEL event set.
Definition channel.h:74
@ FR_CHANNEL_CONTROL_OPEN
A requestor has opened a channel to the responder.
Definition channel.h:79
@ FR_CHANNEL_CONTROL_DATA_TO_REQUESTOR
Replies are queued for the requestor.
Definition channel.h:76
@ FR_CHANNEL_CONTROL_DATA_DONE_RESPONDER
The responder has serviced its requests, and says how many it has seen.
Definition channel.h:77
@ FR_CHANNEL_CONTROL_CLOSE_ACK
The responder has finished closing it.
Definition channel.h:81
@ FR_CHANNEL_CONTROL_CLOSE
The requestor is closing the channel.
Definition channel.h:80
@ FR_CHANNEL_CONTROL_DATA_TO_RESPONDER
Requests are queued for the responder.
Definition channel.h:75
fr_channel_close_t close
Definition channel.h:220
fr_channel_open_t open
Definition channel.h:219
uint64_t resignals
Number of signals resent.
Definition channel.h:90
fr_table_num_sorted_t const channel_packet_priority[]
Definition channel.c:148
void fr_channel_requestor_uctx_add(fr_channel_t *ch, void *ctx)
Add network-specific data to a channel.
Definition channel.c:970
fr_channel_stats_t const * fr_channel_requestor_stats(fr_channel_t const *ch)
Statistics for the requestor's end of a channel.
Definition channel.c:1056
int fr_channel_callbacks_add(fr_control_t *c, fr_channel_callbacks_t const *callbacks, void *uctx)
Register the owner's channel callbacks on its control plane.
Definition channel.c:784
void(* fr_channel_recv_callback_t)(fr_channel_t *ch, fr_channel_data_t *cd, void *uctx)
Definition channel.h:176
uint64_t outstanding
Number of outstanding requests with no reply.
Definition channel.h:88
fr_time_t last_sent_signal
The last time when we signaled the other end.
Definition channel.h:101
int fr_channel_set_recv_reply(fr_channel_t *ch, fr_channel_recv_callback_t recv_reply, void *uctx))
Definition channel.c:990
fr_time_t last_read_other
Last time we successfully read a message from the other the channel.
Definition channel.h:98
fr_channel_t * fr_channel_create(TALLOC_CTX *ctx, fr_control_t *frontend, fr_control_t *worker, bool same)
Create a new channel.
Definition channel.c:167
void(* fr_channel_open_t)(fr_channel_t *ch, fr_message_set_t *reply_ms, fr_time_t now, void *uctx)
Called on a responder when a requestor opens a channel to it.
Definition channel.h:189
fr_channel_closed_t closed
Definition channel.h:221
void * fr_channel_responder_uctx_get(fr_channel_t *ch)
Get responder-specific data from a channel.
Definition channel.c:957
bool fr_channel_recv_request(fr_channel_t *ch)
Receive a request message from the channel.
Definition channel.c:418
int fr_channel_null_reply(fr_channel_t *ch)
Don't send a reply message into the channel.
Definition channel.c:585
fr_listen_instance_t * inst
for tracking packet transport, etc.
Definition channel.h:153
int fr_channel_set_recv_request(fr_channel_t *ch, fr_channel_recv_callback_t recv_request, void *uctx))
Definition channel.c:998
void(* fr_channel_closed_t)(fr_channel_t *ch, fr_time_t now, void *uctx)
Called on a requestor when the responder has finished closing a channel.
Definition channel.h:208
int fr_channel_send_reply(fr_channel_t *ch, fr_channel_data_t *cd)
Send a reply message into the channel.
Definition channel.c:457
void fr_channel_stats_log(fr_channel_t const *ch, fr_log_t const *log, char const *file, int line)
Definition channel.c:1025
fr_time_t last_write
Last write to the channel.
Definition channel.h:97
uint32_t priority
Priority of this packet.
Definition channel.h:147
bool fr_channel_active(fr_channel_t *ch)
Check if a channel is active.
Definition channel.c:850
uint64_t kevents
Number of times we've looked at kevents.
Definition channel.h:95
int fr_channel_responder_ack_close(fr_channel_t *ch)
Acknowledge that the channel is closing.
Definition channel.c:916
uint64_t signals
Number of kevent signals we've sent.
Definition channel.h:89
uint64_t spurious
Number of signals we received which found no data waiting.
Definition channel.h:91
What the owner of a control plane does with channel lifecycle events.
Definition channel.h:218
Channel information which is added to a message.
Definition channel.h:111
Statistics for the channel.
Definition channel.h:87
unsigned int fr_heap_index_t
Definition heap.h:82
The control structure.
Definition control.c:211
unsigned short uint16_t
unsigned int uint32_t
A Message set, composed of message headers and ring buffer data.
Definition message.c:94
Definition log.h:93
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
"server local" time.
Definition time.h:69
int nonnull(2, 5))