The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 2caa99839ef3f484e2bbcb3aec4800e2761ba1ab $
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  */
26 RCSIDH(channel_h, "$Id: 2caa99839ef3f484e2bbcb3aec4800e2761ba1ab $")
27 
28 #ifdef __cplusplus
29 extern "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  */
41 typedef struct fr_channel_s fr_channel_t;
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  */
47 typedef struct fr_listen fr_listen_t;
48 
49 #ifdef __cplusplus
50 }
51 #endif
52 
53 #include <freeradius-devel/io/base.h>
54 #include <freeradius-devel/io/control.h>
55 #include <freeradius-devel/io/message.h>
56 #include <freeradius-devel/util/dlist.h>
57 #include <freeradius-devel/util/heap.h>
58 #include <freeradius-devel/util/log.h>
59 
60 #include <sys/types.h>
61 #include <sys/event.h>
62 
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66 
67 typedef enum fr_channel_event_t {
73 
77 
78 /** Statistics for the channel
79  *
80  */
81 typedef struct {
82  uint64_t outstanding; //!< Number of outstanding requests with no reply.
83  uint64_t signals; //!< Number of kevent signals we've sent.
84  uint64_t resignals; //!< Number of signals resent.
85 
86  uint64_t packets; //!< Number of actual data packets.
87 
88  uint64_t kevents; //!< Number of times we've looked at kevents.
89 
90  fr_time_t last_write; //!< Last write to the channel.
91  fr_time_t last_read_other; //!< Last time we successfully read a message from the other the channel
92  fr_time_delta_t message_interval; //!< Interval between messages.
93 
94  fr_time_t last_sent_signal; //!< The last time when we signaled the other end.
96 
97 
98 /**
99  * Channel information which is added to a message.
100  *
101  * The messages are just for exchanging packet data. The channel
102  * data structure is for exchanging requests and replies.
103  */
104 typedef struct {
105  fr_message_t m; //!< the message header
106 
107  union {
108  /*
109  * Messages have a sequence number / ack while
110  * they're in a channel.
111  */
112  struct {
113  uint64_t sequence; //!< sequence number
114  uint64_t ack; //!< ACK of the sequence number from the other end
115  } live;
116 
117  /*
118  * Once messages are pulled out of a channel by
119  * the scheduler, we need to cache the channel
120  * somewhere. So we cache it in fields which are now unused.
121  */
122  struct {
123  fr_channel_t *ch; //!< channel where this messages was received
124  fr_heap_index_t heap_id; //!< for the various queues
125  } channel;
126  };
127 
128  union {
129  struct {
130  fr_time_t recv_time; //!< time original request was received (network -> worker)
131  } request;
132 
133  struct {
134  fr_time_delta_t cpu_time; //!< Total CPU time, including predicted work, (only worker -> network).
135  fr_time_delta_t processing_time; //!< Actual processing time for this packet (only worker -> network).
136  fr_time_t request_time; //!< Timestamp of the request packet.
137  } reply;
138  };
139 
140  uint32_t priority; //!< Priority of this packet.
141 
142  void *packet_ctx; //!< Packet specific context for holding client
143  //!< information, and other proto_* specific information
144  //!< that needs to be passed to the request.
145 
146  fr_listen_t *listen; //!< for tracking packet transport, etc.
148 
149 #define PRIORITY_NOW (1 << 16)
150 #define PRIORITY_HIGH (1 << 15)
151 #define PRIORITY_NORMAL (1 << 14)
152 #define PRIORITY_LOW (1 << 13)
153 
155 extern size_t channel_signals_len;
157 extern size_t channel_packet_priority_len;
158 
159 fr_channel_t *fr_channel_create(TALLOC_CTX *ctx, fr_control_t *frontend, fr_control_t *worker, bool same) CC_HINT(nonnull);
160 
162 bool fr_channel_recv_request(fr_channel_t *ch) CC_HINT(nonnull);
163 
165 int fr_channel_null_reply(fr_channel_t *ch) CC_HINT(nonnull);
166 
167 bool fr_channel_recv_reply(fr_channel_t *ch) CC_HINT(nonnull);
168 
169 typedef void (*fr_channel_recv_callback_t)(void *ctx, fr_channel_t *ch, fr_channel_data_t *cd);
170 int fr_channel_set_recv_reply(fr_channel_t *ch, void *ctx, fr_channel_recv_callback_t recv_reply) CC_HINT(nonnull(1,3));
171 int fr_channel_set_recv_request(fr_channel_t *ch, void *ctx, fr_channel_recv_callback_t recv_reply) CC_HINT(nonnull(1,3));
172 
174 
175 int fr_channel_service_kevent(fr_channel_t *ch, fr_control_t *c, struct kevent const *kev) CC_HINT(nonnull);
176 fr_channel_event_t fr_channel_service_message(fr_time_t when, fr_channel_t **p_channel, void const *data, size_t data_size) CC_HINT(nonnull);
177 
178 bool fr_channel_active(fr_channel_t *ch) CC_HINT(nonnull);
179 
181 
184 
185 void fr_channel_responder_uctx_add(fr_channel_t *ch, void *ctx) CC_HINT(nonnull);
187 void fr_channel_requestor_uctx_add(fr_channel_t *ch, void *ctx) CC_HINT(nonnull);
189 
190 
191 void fr_channel_stats_log(fr_channel_t const *ch, fr_log_t const *log, char const *file, int line);
192 
193 #ifdef __cplusplus
194 }
195 #endif
int const char * file
Definition: acutest.h:702
int const char int line
Definition: acutest.h:702
#define RCSIDH(h, id)
Definition: build.h:482
A full channel, which consists of two ends.
Definition: channel.c:144
fr_message_t m
the message header
Definition: channel.h:105
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:885
void * fr_channel_requestor_uctx_get(fr_channel_t *ch)
Get network-specific data from a channel.
Definition: channel.c:922
fr_table_num_sorted_t const channel_signals[]
Definition: channel.c:153
fr_channel_event_t
Definition: channel.h:67
@ FR_CHANNEL_NOOP
Definition: channel.h:74
@ FR_CHANNEL_EMPTY
Definition: channel.h:75
@ FR_CHANNEL_CLOSE
Definition: channel.h:72
@ FR_CHANNEL_ERROR
Definition: channel.h:68
@ FR_CHANNEL_DATA_READY_REQUESTOR
Definition: channel.h:70
@ FR_CHANNEL_OPEN
Definition: channel.h:71
@ FR_CHANNEL_DATA_READY_RESPONDER
Definition: channel.h:69
void * packet_ctx
Packet specific context for holding client information, and other proto_* specific information that n...
Definition: channel.h:142
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:183
bool fr_channel_recv_reply(fr_channel_t *ch)
Receive a reply message from the channel.
Definition: channel.c:408
fr_time_delta_t message_interval
Interval between messages.
Definition: channel.h:92
int fr_channel_send_request(fr_channel_t *ch, fr_channel_data_t *cm)
Send a request message into the channel.
Definition: channel.c:306
size_t channel_signals_len
Definition: channel.c:162
fr_listen_t * listen
for tracking packet transport, etc.
Definition: channel.h:146
void(* fr_channel_recv_callback_t)(void *ctx, fr_channel_t *ch, fr_channel_data_t *cd)
Definition: channel.h:169
size_t channel_packet_priority_len
Definition: channel.c:170
void * fr_channel_responder_uctx_get(fr_channel_t *ch)
Get responder-specific data from a channel.
Definition: channel.c:897
uint64_t packets
Number of actual data packets.
Definition: channel.h:86
int fr_channel_signal_responder_close(fr_channel_t *ch)
Signal a responder that the channel is closing.
Definition: channel.c:824
uint64_t resignals
Number of signals resent.
Definition: channel.h:84
fr_table_num_sorted_t const channel_packet_priority[]
Definition: channel.c:164
void fr_channel_requestor_uctx_add(fr_channel_t *ch, void *ctx)
Add network-specific data to a channel.
Definition: channel.c:910
uint64_t outstanding
Number of outstanding requests with no reply.
Definition: channel.h:82
fr_time_t last_sent_signal
The last time when we signaled the other end.
Definition: channel.h:94
fr_channel_event_t fr_channel_service_message(fr_time_t when, fr_channel_t **p_channel, void const *data, size_t data_size)
Service a control-plane message.
Definition: channel.c:685
fr_time_t last_read_other
Last time we successfully read a message from the other the channel.
Definition: channel.h:91
int fr_channel_set_recv_request(fr_channel_t *ch, void *ctx, fr_channel_recv_callback_t recv_reply))
Definition: channel.c:938
bool fr_channel_recv_request(fr_channel_t *ch)
Receive a request message from the channel.
Definition: channel.c:472
int fr_channel_null_reply(fr_channel_t *ch)
Don't send a reply message into the channel.
Definition: channel.c:624
int fr_channel_set_recv_reply(fr_channel_t *ch, void *ctx, fr_channel_recv_callback_t recv_reply))
Definition: channel.c:930
int fr_channel_responder_sleeping(fr_channel_t *ch)
Signal a channel that the responder is sleeping.
Definition: channel.c:646
int fr_channel_send_reply(fr_channel_t *ch, fr_channel_data_t *cd)
Send a reply message into the channel.
Definition: channel.c:511
void fr_channel_stats_log(fr_channel_t const *ch, fr_log_t const *log, char const *file, int line)
Definition: channel.c:963
fr_time_t last_write
Last write to the channel.
Definition: channel.h:90
uint32_t priority
Priority of this packet.
Definition: channel.h:140
bool fr_channel_active(fr_channel_t *ch)
Check if a channel is active.
Definition: channel.c:812
uint64_t kevents
Number of times we've looked at kevents.
Definition: channel.h:88
int fr_channel_responder_ack_close(fr_channel_t *ch)
Acknowledge that the channel is closing.
Definition: channel.c:854
int fr_channel_signal_open(fr_channel_t *ch)
Send a channel to a responder.
Definition: channel.c:952
uint64_t signals
Number of kevent signals we've sent.
Definition: channel.h:83
Channel information which is added to a message.
Definition: channel.h:104
Statistics for the channel.
Definition: channel.h:81
unsigned int fr_heap_index_t
Definition: heap.h:80
The control structure.
Definition: control.c:79
unsigned int uint32_t
Definition: merged_model.c:33
Definition: log.h:96
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
static fr_slen_t data
Definition: value.h:1265
int nonnull(2, 5))