The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
packet.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: 67853fd048f654ca4e0d5094fcfdfb72b21164d7 $
20  * @file lib/bio/packet.h
21  * @brief Binary IO abstractions for #fr_packet_t
22  *
23  * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
24  */
25 RCSIDH(lib_bio_packet_h, "$Id: 67853fd048f654ca4e0d5094fcfdfb72b21164d7 $")
26 
27 #include <freeradius-devel/util/packet.h>
28 #include <freeradius-devel/bio/base.h>
29 
30 // @todo - _CONST
31 
32 typedef struct fr_bio_packet_s fr_bio_packet_t;
33 
34 /** Read a packet and pairs from the network
35  *
36  * @param bio the packet-based bio
37  * @param request_ctx_p the request context associated with the response
38  * @param packet_p the response packet. Contains raw protocol data (IDs, counts, etc.)
39  * @param out_ctx talloc context for the list
40  * @param out the decoded pairs from the packet
41  * @return
42  * - <0 on error
43  * - 0 for success (*packet_p may still be NULL tho)
44  */
45 typedef int (*fr_bio_packet_read_t)(fr_bio_packet_t *bio, void **request_ctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out);
46 
47 /** Write a packet and pairs from the network
48  *
49  * @param bio the packet-based bio
50  * @param rctx the request context
51  * @param packet the request packet. Contains raw protocol data (IDs, counts, etc.)
52  * @param list the pairs to encode in the packet
53  * @return
54  * - <0 on error (EOF, fail, etc,)
55  * - 0 for success
56  */
57 typedef int (*fr_bio_packet_write_t)(fr_bio_packet_t *bio, void *rctx, fr_packet_t *packet, fr_pair_list_t *list);
58 
59 /** Signal an outgoing packet.
60  *
61  * @param bio the packet-based bio
62  * @param packet the output packet descriptor. Contains raw protocol data (IDs, counts, etc.)
63  */
65 
67 
69 
70 typedef struct {
75 
78 
81 
85 
87  void *uctx; //!< user ctx, caller can manually set it.
88 
89  fr_bio_packet_read_t read; //!< read from the underlying bio
90  fr_bio_packet_write_t write; //!< write to the underlying bio
91 
93 
94  fr_event_timer_t const *ev; //!< connection timeout
95 
96  bool connected;
99 
100  fr_bio_t *bio; //!< underlying BIO(s) for IO
101 };
102 
103 
104 /** Read a packet from a packet BIO
105  *
106  * Note that the bio MAY return fr_bio_error(IO_WOULD_BLOCK), which is not a fatal error. The caller has to
107  * check for that case, and handle blocking errors. Typically by pushing the packet to a queue, and trying
108  * it again later.
109  *
110  * @param my the packet-based bio
111  * @param[out] pctx_p the larger context for the original request packet
112  * @param[out] packet_p Where the allocated #fr_packet_t will be stored
113  * @param[out] out_ctx for the output pairs
114  * @param[out] out decoded output pairs
115  * @return
116  * - <0 on error. This is fr_bio_error(FOO)
117  * - 0 for success
118  */
119 static inline CC_HINT(nonnull) int fr_bio_packet_read(fr_bio_packet_t *my, void **pctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out)
120 {
121  return my->read(my, pctx_p, packet_p, out_ctx, out);
122 }
123 
124 /** Write a packet to a packet BIO
125  *
126  * Note that the bio MAY return fr_bio_error(IO_WOULD_BLOCK), which is not a fatal error. The caller has to
127  * check for that case, and handle blocking errors. Typically by pushing the packet to a queue, and trying
128  * it again later.
129  *
130  * @param my the packet-based bio
131  * @param pctx the larger context for the packet
132  * @param packet the output packet descriptor. Contains raw protocol data (IDs, counts, etc.)
133  * @param list of pairs to write
134  * @return
135  * - <0 on error. This is fr_bio_error(FOO)
136  * - 0 for success
137  */
138 static inline CC_HINT(nonnull) int fr_bio_packet_write(fr_bio_packet_t *my, void *pctx, fr_packet_t *packet, fr_pair_list_t *list)
139 {
140  int rcode;
141 
142  /*
143  * We don't allow more writes if the bio is blocked.
144  */
145  if (my->write_blocked) return fr_bio_error(IO_WOULD_BLOCK);
146 
147  rcode = my->write(my, pctx, packet, list);
148  if (rcode == 0) return 0;
149 
150  my->write_blocked = (rcode == fr_bio_error(IO_WOULD_BLOCK));
151  return rcode;
152 }
153 
154 /** Flush a bio which is blocked.
155  *
156  * Note that the bio MAY return fr_bio_error(IO_WOULD_BLOCK), which is not a fatal error. The caller has to
157  * check for that case, and handle blocking errors. Typically by pushing the packet to a queue, and trying
158  * it again later.
159  *
160  * @param my the packet-based bio
161  * @return
162  * - <0 on error. This is fr_bio_error(FOO)
163  * - 0 for success
164  */
166 {
167  ssize_t slen;
168 
169  if (!my->write_blocked) return 0;
170 
171  /*
172  * Note that "wrote no data" means that there's no pending data, so we're no longer blocked.
173  */
174  slen = my->bio->write(my->bio, NULL, NULL, SIZE_MAX);
175  if (slen >= 0) {
176  my->write_blocked = false;
177  }
178 
179  return slen;
180 }
181 
182 void fr_bio_packet_connected(fr_bio_t *bio) CC_HINT(nonnull);
184 
#define fr_bio_error(_x)
Definition: base.h:192
Definition: base.h:112
fr_bio_t * bio
underlying BIO(s) for IO
Definition: packet.h:100
fr_bio_packet_io_t read_blocked
Definition: packet.h:76
fr_bio_packet_cb_funcs_t cb
Definition: packet.h:92
fr_bio_packet_callback_t shutdown
Definition: packet.h:72
fr_bio_packet_callback_t eof
Definition: packet.h:73
fr_bio_packet_signal_t release
Definition: packet.h:83
void fr_bio_packet_init(fr_bio_packet_t *my)
Definition: packet.c:177
void fr_bio_packet_connected(fr_bio_t *bio)
Called when a particular BIO is connected.
Definition: packet.c:116
fr_bio_packet_write_t write
write to the underlying bio
Definition: packet.h:90
int(* fr_bio_packet_read_t)(fr_bio_packet_t *bio, void **request_ctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out)
Read a packet and pairs from the network.
Definition: packet.h:45
fr_bio_packet_io_t write_blocked
Definition: packet.h:77
fr_bio_packet_signal_t retry
Definition: packet.h:82
fr_bio_packet_io_t write_resume
Definition: packet.h:80
bool read_blocked
Definition: packet.h:98
fr_bio_packet_io_t read_resume
Definition: packet.h:79
static int fr_bio_packet_read(fr_bio_packet_t *my, void **pctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out)
Read a packet from a packet BIO.
Definition: packet.h:119
fr_bio_packet_callback_t connected
Definition: packet.h:71
void(* fr_bio_packet_signal_t)(fr_bio_packet_t *bio, fr_packet_t *packet)
Signal an outgoing packet.
Definition: packet.h:64
fr_bio_packet_callback_t failed
Definition: packet.h:74
fr_event_timer_t const * ev
connection timeout
Definition: packet.h:94
bool write_blocked
Definition: packet.h:97
int(* fr_bio_packet_io_t)(fr_bio_packet_t *bio)
Definition: packet.h:66
void * uctx
user ctx, caller can manually set it.
Definition: packet.h:87
fr_bio_packet_read_t read
read from the underlying bio
Definition: packet.h:89
static int fr_bio_packet_write_flush(fr_bio_packet_t *my)
Flush a bio which is blocked.
Definition: packet.h:165
int fr_bio_packet_connect(fr_bio_t *bio)
int(* fr_bio_packet_write_t)(fr_bio_packet_t *bio, void *rctx, fr_packet_t *packet, fr_pair_list_t *list)
Write a packet and pairs from the network.
Definition: packet.h:57
static int fr_bio_packet_write(fr_bio_packet_t *my, void *pctx, fr_packet_t *packet, fr_pair_list_t *list)
Write a packet to a packet BIO.
Definition: packet.h:138
bool connected
Definition: packet.h:96
void(* fr_bio_packet_callback_t)(fr_bio_packet_t *bio)
Definition: packet.h:68
#define RCSIDH(h, id)
Definition: build.h:482
fr_bio_shutdown & my
Definition: fd_errno.h:59
A timer event.
Definition: event.c:102
long int ssize_t
Definition: merged_model.c:24
int nonnull(2, 5))
static size_t char ** out
Definition: value.h:997