The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
base.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: fcc678adc9df1444d66856dfa82eeeed84aef8bd $
19 * @file lib/bio/base.c
20 * @brief Binary IO abstractions.
21 *
22 * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
23 */
24
25#include <freeradius-devel/bio/bio_priv.h>
26#include <freeradius-devel/bio/null.h>
27#include <freeradius-devel/util/syserror.h>
28
29/** Free this bio.
30 *
31 * We allow talloc_free() to be called on just about anything in the
32 * bio chain. But we ensure that the chain is always shut down in an
33 * orderly fashion.
34 */
36{
37 fr_bio_common_t *my = (fr_bio_common_t *) bio;
38
40
41 return 0;
42}
43
44/** Internal bio function which just reads from the "next" bio.
45 *
46 * It is mainly used when the current bio needs to modify the write
47 * path, but does not need to do anything on the read path.
48 */
49ssize_t fr_bio_next_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
50{
51 fr_bio_t *next;
52
53 next = fr_bio_next(bio);
54 fr_assert(next != NULL);
55
56 return next->read(next, packet_ctx, buffer, size);
57}
58
59/** Internal bio function which just writes to the "next" bio.
60 *
61 * It is mainly used when the current bio needs to modify the read
62 * path, but does not need to do anything on the write path.
63 */
64ssize_t fr_bio_next_write(fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
65{
66 fr_bio_t *next;
67
68 next = fr_bio_next(bio);
69 fr_assert(next != NULL);
70
71 return next->write(next, packet_ctx, buffer, size);
72}
73
75{
76 return fr_bio_error(SHUTDOWN);
77}
78
80{
81 return fr_bio_error(SHUTDOWN);
82}
83
84/** Tear down every bio from "first" to the end of the chain.
85 *
86 * Running a bio's own shutdown routine twice is harmless, because the routine is cleared once it
87 * has run.
88 */
90{
91 int rcode;
92 fr_bio_t *this;
94
95 for (this = first; this != NULL; this = fr_bio_next(this)) {
96 my = (fr_bio_common_t *) this;
97
98 if (my->priv_cb.shutdown) {
99 rcode = my->priv_cb.shutdown(&my->bio);
100 if (rcode < 0) return rcode;
101 my->priv_cb.shutdown = NULL;
102 }
103
104 my->bio.read = fr_bio_shutdown_read;
105 my->bio.write = fr_bio_shutdown_write;
106 talloc_set_destructor(my, NULL);
107 }
108
109 return 0;
110}
111
112/** Finish a shutdown: tear down the whole chain, and tell the application.
113 *
114 * Called either from fr_bio_shutdown() when nothing was buffered, or from fr_bio_eof() once the
115 * application has drained everything which had already been received.
116 */
118{
119 int rcode;
120 fr_bio_t *head = fr_bio_head(bio);
122
123 my->shutdown_pending = false;
124
126 if (rcode < 0) return rcode;
127
128 /*
129 * Call the application shutdown routine to tell it that the BIO has been successfully shut
130 * down. The read and write routines above are already dead, so a shutdown routine which
131 * calls back into us does nothing.
132 */
133 if (my->cb.shutdown) {
134 rcode = my->cb.shutdown(head);
135 if (rcode < 0) return rcode;
136 my->cb.shutdown = NULL;
137 }
138
139 return 0;
140}
141
142/** Shut down a set of BIOs
143 *
144 * We shut down the BIOs from the top to the bottom. This gives the TLS BIO an opportunity to call
145 * the SSL_shutdown() routine, which should then write to the FD BIO. Once that write is
146 * completed, the FD BIO can then close its socket.
147 *
148 * Any shutdown is "stop read / write", but is not "free all resources". A shutdown can happen
149 * when one of the intermediary BIOs hits a fatal error. It can't free the BIO, but it has to mark
150 * the entire BIO chain as being unusable.
151 *
152 * Writes stop at once. Reads do not: a bio which still holds data which the application has not
153 * collected keeps its read routine, and the rest of the shutdown waits until that data has been
154 * drained. fr_bio_shutdown_discard() is the version which does not wait.
155 *
156 * A destructor will first shutdown the BIOs, and then free all resources.
157 */
159{
160 fr_bio_t *head, *this, *stopped;
161 fr_bio_common_t *my;
162
163 /*
164 * Find the first bio in the chain.
165 */
166 head = fr_bio_head(bio);
167 my = (fr_bio_common_t *) head;
168
169 /*
170 * We're in the process of shutting down, or we have already shut down. Don't call ourselves
171 * recursively.
172 */
173 if (my->shutdown_pending || (my->bio.read == fr_bio_shutdown_read)) return 0;
174
175 /*
176 * Writes die immediately, everywhere. Whatever killed the transport means that no write can
177 * ever succeed, and the application must not be told "nothing written, try again later".
178 *
179 * Reads are left alone, so that the application can still collect data which arrived before
180 * the transport went away.
181 */
182 for (this = head; this != NULL; this = fr_bio_next(this)) {
183 ((fr_bio_common_t *) this)->bio.write = fr_bio_shutdown_write;
184 }
185
186 my->shutdown_pending = true;
187
188 /*
189 * Walk back up the chain from the bio which failed. If nothing is holding data,
190 * fr_bio_eof() runs the teardown itself and returns NULL.
191 */
192 stopped = fr_bio_eof(bio);
193 if (!stopped) return 0;
194
195 /*
196 * Something upstream still has data for the application. Everything downstream of it is
197 * finished with, so tear that down now, and leave the rest until the drain completes.
198 */
199 return fr_bio_shutdown_chain(fr_bio_next(stopped));
200}
201
202/** Shut down the chain now, discarding anything which is still buffered.
203 *
204 * For a caller which has decided that the buffered data is the problem, such as a verify failure,
205 * and for a free, which cannot wait for the application to drain anything.
206 */
208{
210
211 if (my->bio.read == fr_bio_shutdown_read) return 0;
212
213 return fr_bio_shutdown_final(&my->bio);
214}
215
216/** Like fr_bio_shutdown(), but can be called by anyone in the chain.
217 *
218 * fr_bio_shutdown() finds the head itself, so this is now the same function.
219 */
221{
222 return fr_bio_shutdown(bio);
223}
224
225char const *fr_bio_strerror(ssize_t error)
226{
227 switch (error) {
228 case fr_bio_error(NONE):
229 return "";
230
231 case fr_bio_error(IO_WOULD_BLOCK):
232 return "IO operation would block";
233
234 case fr_bio_error(IO):
235 return fr_syserror(errno);
236
237 case fr_bio_error(GENERIC):
238 return fr_strerror();
239
240 case fr_bio_error(OOM):
241 return "Out of memory";
242
243 case fr_bio_error(VERIFY):
244 return "Packet fails verification";
245
246 case fr_bio_error(BUFFER_FULL):
247 return "Output buffer is full";
248
249 case fr_bio_error(BUFFER_TOO_SMALL):
250 return "Output buffer is too small to cache the data";
251
252 case fr_bio_error(SHUTDOWN):
253 return "The IO handler is not available. It has been shut down due to a previous error";
254
255 default:
256 return "<unknown>";
257 }
258}
259
261{
262 fr_bio_common_t *my = (fr_bio_common_t *) bio;
263
264 if (!cb) {
265 memset(&my->cb, 0, sizeof(my->cb));
266 } else {
267 my->cb = *cb;
268 }
269}
270
271/** Internal BIO function to run EOF callbacks.
272 *
273 * When a BIO hits EOF, it MUST call this function. This function will take care of changing the read()
274 * function to return nothing. It will also take care of walking back up the hierarchy, and calling any
275 * BIO EOF callbacks.
276 *
277 * Once all of the BIOs have been marked as blocked, it will call the application EOF callback.
278 */
280{
281 fr_bio_common_t *this = (fr_bio_common_t *) bio;
282
283 /*
284 * This BIO is at EOF. So we can't call read() any more.
285 *
286 * @todo - we have to fix ordering of priv.cb.eof() versus cb.eof() the application may signal
287 * EOF on the BIO, in which case we have to do various things in the right order, so that the
288 * various callbacks can be set / updated correctly. See mem.c and pipe.c for examples.
289 *
290 * What we probably want is to ensure that there is no NEXT bio, OR that the next BIO is already
291 * at EOF. So the FD BIO can call "eof" when it hits EOF, and the various upstream BIOs have
292 * their EOF callbacks run when they hit EOF.
293 *
294 * We probably want to also add "bool eof" to fr_bio_common_s. And perhaps also read/write
295 * blocked.
296 */
297 this->bio.read = fr_bio_null_read;
298
299 while (true) {
300 fr_bio_common_t *prev = (fr_bio_common_t *) fr_bio_prev(&this->bio);
301
302 /*
303 * There are no more BIOs. Tell the application that the entire BIO chain is at EOF.
304 */
305 if (!prev) {
306 if (this->cb.eof) {
307 this->cb.eof(&this->bio);
308 this->cb.eof = NULL;
309 }
310
311 /*
312 * A shutdown was deferred so that the application could drain whatever had
313 * already been received. There is nothing left to drain, so finish it.
314 */
315 if (this->shutdown_pending) (void) fr_bio_shutdown_final(&this->bio);
316
317 return NULL;
318 }
319
320 /*
321 * Go to the previous BIO. If it doesn't have an EOF handler, then keep going back up
322 * the chain until we're at the top.
323 */
324 this = prev;
325 if (!this->priv_cb.eof) continue;
326
327 /*
328 * The EOF handler said it's an error or NOT at EOF, so we stop processing here.
329 */
330 if (this->priv_cb.eof((fr_bio_t *) this) <= 0) return (fr_bio_t *) this;
331
332 /*
333 * Don't run the EOF callback multiple times, and continue the loop.
334 */
335 this->priv_cb.eof = NULL;
336 }
337}
338
339/** Internal BIO function to tell all BIOs that it's blocked.
340 *
341 * When a BIO blocks on write, it MUST call this function. This function will take care of walking back up
342 * the hierarchy, and calling any write_blocked callbacks.
343 *
344 * Once all of the BIOs have been marked as blocked, it will call the application write_blocked callback.
345 */
347{
348 fr_bio_common_t *this = (fr_bio_common_t *) bio;
349 int is_blocked = 1;
350
351 while (true) {
352 fr_bio_common_t *prev = (fr_bio_common_t *) fr_bio_prev(&this->bio);
353 int rcode;
354
355 /*
356 * There are no more BIOs. Tell the application that the entire BIO chain is blocked.
357 */
358 if (!prev) {
359 if (this->cb.write_blocked) {
360 rcode = this->cb.write_blocked(&this->bio);
361 if (rcode < 0) return rcode;
362 is_blocked &= (rcode == 1);
363 }
364 break;
365 }
366
367 /*
368 * Go to the previous BIO. If it doesn't have a write_blocked handler, then keep going
369 * back up the chain until we're at the top.
370 */
371 this = prev;
372 if (!this->priv_cb.write_blocked) continue;
373
374 /*
375 * Run this BIO's write_blocked handler. On error we bail out immediately;
376 * otherwise we record whether it considers itself blocked and keep walking up
377 * the chain so that every BIO is told that writes are blocked.
378 */
379 rcode = this->priv_cb.write_blocked((fr_bio_t *) this);
380 if (rcode < 0) return rcode;
381 is_blocked &= (rcode == 1);
382 }
383
384 return is_blocked;
385}
static int const char char buffer[256]
Definition acutest.h:635
fr_bio_write_t _CONST write
write to the underlying bio
Definition base.h:117
static fr_bio_t * fr_bio_prev(fr_bio_t *bio)
Definition base.h:122
fr_bio_read_t _CONST read
read from the underlying bio
Definition base.h:116
static fr_bio_t * fr_bio_next(fr_bio_t *bio)
Definition base.h:131
static fr_bio_t * fr_bio_head(fr_bio_t *bio)
Definition base.h:140
#define fr_bio_error(_x)
Definition base.h:200
static int packet_ctx
the tests pass only the address of packet_ctx
#define FR_BIO_DESTRUCTOR_COMMON
Define a common destructor pattern.
Definition bio_priv.h:65
#define UNUSED
Definition build.h:384
char const * fr_bio_strerror(ssize_t error)
Definition base.c:225
int fr_bio_write_blocked(fr_bio_t *bio)
Internal BIO function to tell all BIOs that it's blocked.
Definition base.c:346
ssize_t fr_bio_shutdown_read(UNUSED fr_bio_t *bio, UNUSED void *packet_ctx, UNUSED void *buffer, UNUSED size_t size)
Definition base.c:74
void fr_bio_cb_set(fr_bio_t *bio, fr_bio_cb_funcs_t const *cb)
Definition base.c:260
int fr_bio_shutdown_intermediate(fr_bio_t *bio)
Like fr_bio_shutdown(), but can be called by anyone in the chain.
Definition base.c:220
int fr_bio_shutdown_discard(fr_bio_t *bio)
Shut down the chain now, discarding anything which is still buffered.
Definition base.c:207
static int fr_bio_shutdown_final(fr_bio_t *bio)
Finish a shutdown: tear down the whole chain, and tell the application.
Definition base.c:117
int fr_bio_destructor(fr_bio_t *bio)
Free this bio.
Definition base.c:35
ssize_t fr_bio_shutdown_write(UNUSED fr_bio_t *bio, UNUSED void *packet_ctx, UNUSED void const *buffer, UNUSED size_t size)
Definition base.c:79
ssize_t fr_bio_next_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
Internal bio function which just reads from the "next" bio.
Definition base.c:49
fr_bio_t * fr_bio_eof(fr_bio_t *bio)
Internal BIO function to run EOF callbacks.
Definition base.c:279
ssize_t fr_bio_next_write(fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
Internal bio function which just writes to the "next" bio.
Definition base.c:64
int fr_bio_shutdown(fr_bio_t *bio)
Shut down a set of BIOs.
Definition base.c:158
static int fr_bio_shutdown_chain(fr_bio_t *first)
Tear down every bio from "first" to the end of the chain.
Definition base.c:89
long int ssize_t
ssize_t fr_bio_null_read(UNUSED fr_bio_t *bio, UNUSED void *packet_ctx, UNUSED void *buffer, UNUSED size_t size)
Always return 0 on read.
Definition null.c:31
#define fr_assert(_expr)
Definition rad_assert.h:37
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define VERIFY(_x)
Definition trie.c:130
static fr_slen_t head
Definition xlat.h:410
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:558