The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
bio_priv.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: 13908e0885c18cd435e43b77016349a51813c1b7 $
20 * @file lib/bio/bio_priv.h
21 * @brief Binary IO private functions
22 *
23 * Create abstract binary input / output buffers.
24 *
25 * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
26 */
27RCSIDH(lib_bio_bio_priv_h, "$Id: 13908e0885c18cd435e43b77016349a51813c1b7 $")
28
29#define _BIO_PRIVATE 1
30#include <freeradius-devel/bio/base.h>
31
33
46
47/** Common elements at the start of each private #fr_bio_t
48 *
49 */
50#define FR_BIO_COMMON \
51 fr_bio_t bio; \
52 fr_bio_cb_funcs_t cb; \
53 fr_bio_priv_callback_t priv_cb; \
54 bool shutdown_pending /*!< only meaningful on the head bio, see fr_bio_shutdown() */
55
59
60/** Define a common destructor pattern.
61 *
62 * Ensure that talloc_free() is safe no matter what. The caller can free any BIO at any time. If that
63 * happens, then the entire chain is shut down. On successful shutdown, this BIO is removed from the chain.
64 */
65#define FR_BIO_DESTRUCTOR_COMMON \
66do { \
67 if (my->priv_cb.shutdown) { \
68 int rcode; \
69 /* \
70 * A free cannot wait for the application to drain any buffered data, so this \
71 * tears the chain down now even if a shutdown was deferred. \
72 */ \
73 rcode = fr_bio_shutdown_discard(&my->bio); \
74 if (rcode < 0) return rcode; \
75 } \
76 if (fr_bio_prev(&my->bio) || fr_bio_next(&my->bio)) \
77 fr_bio_unchain(&my->bio); \
78} while (0)
79
80
81ssize_t fr_bio_next_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size);
82
83ssize_t fr_bio_next_write(fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size);
84
85/** Chain one bio after another.
86 *
87 * @todo - this likely needs to be public
88 */
89static inline void CC_HINT(nonnull) fr_bio_chain(fr_bio_t *first, fr_bio_t *second)
90{
91 fr_assert(first->entry.prev == NULL);
92 fr_assert(first->entry.next == NULL);
93
94 fr_assert(second->entry.prev == NULL);
95
96 first->entry.next = &second->entry;
97 second->entry.prev = &first->entry;
98}
99
100/** Remove a bio from a chain
101 *
102 * And reset prev/next ptrs to NULL.
104 * @todo - this likely needs to be public
105 */
106static inline void CC_HINT(nonnull) fr_bio_unchain(fr_bio_t *bio)
107{
108 fr_bio_t *prev = fr_bio_prev(bio);
109 fr_bio_t *next = fr_bio_next(bio);
110
111 fr_assert(prev || next);
112
113 if (prev) prev->entry.next = bio->entry.next;
114
115 if (next) next->entry.prev = bio->entry.prev;
116
117 bio->entry.prev = bio->entry.next = NULL;
118}
119
120/** Tell the chain that a bio is at EOF, and let the application drain whatever is buffered.
121 *
122 * @return
123 * - NULL if every bio in the chain is at EOF
124 * - the bio which still holds data, and which therefore stopped the walk
125 */
126fr_bio_t *fr_bio_eof(fr_bio_t *bio) CC_HINT(nonnull);
127
128int fr_bio_write_blocked(fr_bio_t *bio) CC_HINT(nonnull);
static int const char char buffer[256]
Definition acutest.h:635
static fr_bio_t * fr_bio_prev(fr_bio_t *bio)
Definition base.h:122
fr_dlist_t _CONST entry
in the linked list of multiple bios
Definition base.h:119
static fr_bio_t * fr_bio_next(fr_bio_t *bio)
Definition base.h:131
int(* fr_bio_io_t)(fr_bio_t *bio)
Definition base.h:84
void(* fr_bio_callback_t)(fr_bio_t *bio)
Definition base.h:86
static int packet_ctx
the tests pass only the address of packet_ctx
fr_bio_io_t read_resume
"unblocked" is too similar to "blocked"
Definition bio_priv.h:43
fr_bio_io_t write_blocked
Definition bio_priv.h:41
fr_bio_io_t connected
Definition bio_priv.h:35
fr_bio_callback_t failed
Definition bio_priv.h:38
static void fr_bio_chain(fr_bio_t *first, fr_bio_t *second)
Chain one bio after another.
Definition bio_priv.h:86
int fr_bio_write_blocked(fr_bio_t *bio)
Internal BIO function to tell all BIOs that it's blocked.
Definition base.c:346
fr_bio_io_t shutdown
Definition bio_priv.h:36
fr_bio_io_t write_resume
Definition bio_priv.h:44
fr_bio_io_t read_blocked
Definition bio_priv.h:40
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)
Tell the chain that a bio is at EOF, and let the application drain whatever is buffered.
Definition base.c:279
static void fr_bio_unchain(fr_bio_t *bio)
Remove a bio from a chain.
Definition bio_priv.h:103
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
#define RCSIDH(h, id)
Definition build.h:561
fr_dlist_t * next
Definition dlist.h:43
fr_dlist_t * prev
Definition dlist.h:42
long int ssize_t
#define fr_assert(_expr)
Definition rad_assert.h:37
int nonnull(2, 5))