The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
retry.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: 83bf057f99ae0d3f056ee99360c08e0ea3feafff $
20  * @file lib/bio/retry.h
21  * @brief Binary IO abstractions for retrying of raw packets
22  *
23  * Write packets of data to bios. Once a packet is written, it is
24  * retried until a response is returned. Note that this ONLY works
25  * for datagram bios, where the packets can be retransmitted
26  * identically without any changes.
27  *
28  * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
29  */
30 RCSIDH(lib_bio_retry_h, "$Id: 83bf057f99ae0d3f056ee99360c08e0ea3feafff $")
31 
32 #include <freeradius-devel/util/retry.h>
33 #include <freeradius-devel/util/event.h>
34 
35 #ifdef _CONST
36 # error _CONST can only be defined in the local header
37 #endif
38 #ifndef _BIO_RETRY_PRIVATE
39 # define _CONST const
40 #else
41 # define _CONST
42 #endif
43 
44 typedef struct {
45  fr_event_list_t *el; //!< event list
46 
47  fr_retry_config_t retry_config; //!< base retry config
49 
50 typedef struct {
51  fr_event_list_t *el; //!< event list
52 
53  fr_time_t mrs_time; //!< Most recent sent time which had a reply.
54  fr_time_t last_reply; //!< When we last received a reply.
55  fr_time_t first_sent; //!< first time we sent a packet since going idle
56  fr_time_t last_sent; //!< last time we sent a packet.
57  fr_time_t last_idle; //!< last time we had nothing to do
58 
59  bool write_blocked; //!< are writes blocked?
60 
61  fr_bio_retry_config_t const *cfg; //!< so we know what was asked
63 
65 
66 typedef ssize_t (*fr_bio_retry_rewrite_t)(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size);
67 
68 #ifndef _BIO_RETRY_PRIVATE
69 struct fr_bio_retry_entry_s {
70  void *uctx; //!< user-writable context
71  void *packet_ctx; //!< packet_ctx from the write() call
72  fr_bio_retry_rewrite_t rewrite; //!< per-packet rewrite callback
73  void *rewrite_ctx; //!< context specifically for rewriting this packet
74 
75  fr_retry_t _CONST retry; //!< retry timers and counters
76 };
77 #endif
78 
79 typedef enum {
86 
87 /** Callback for when a packet is sent
88  *
89  * The purpose of the callback is for the application to save the retry_ctx, in case the packet needs to be
90  * cancelled at a later point in time.
91  *
92  * @param bio the binary IO handler
93  * @param packet_ctx per-packet context
94  * @param buffer raw data for the packet
95  * @param size size of the raw data
96  * @param retry_ctx pointer to save for use with later cancellation
97  */
98 typedef void (*fr_bio_retry_sent_t)(fr_bio_t *bio, void *packet_ctx, const void *buffer, size_t size,
99  fr_bio_retry_entry_t *retry_ctx);
100 
101 typedef ssize_t (*fr_bio_retry_rewrite_t)(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size);
102 
103 /** Callback on read to see if a packet is a response
104  *
105  * The callback should manually associate the response with a request, but allow the packet to be returned
106  * to the application.
107  *
108  * The callback should also set item_p, _even if the response is duplicate_. That way the retry bio can
109  * properly track multiple requests and responses.
110  *
111  * If there is a fatal error reading the response, the callback should set a flag (in the bio)? and return.
112  * It should NOT call any bio shutdown routine.
113  *
114  * @param bio the binary IO handler
115  * @param[out] item_p item pointer for request, from #fr_bio_retry_saved_t
116  * @param packet_ctx per-packet context for the response
117  * @param buffer raw data for the response
118  * @param size size of the raw response data
119  * @return
120  * - false - do not pass the packet to the reader
121  * - true - pass the packet through to the reader
122  */
123 typedef bool (*fr_bio_retry_response_t)(fr_bio_t *bio, fr_bio_retry_entry_t **item_p, void *packet_ctx, const void *buffer, size_t size);
124 
125 /** Callback on release the packet (timeout or have all replies)
126  *
127  * The callback function should clean up any resources associated with the packet. The resources MUST NOT be
128  * released until the data is either "released" or "cancelled".
129  *
130  * The packet will be cancelled after this call returns. The cancellation callback will NOT be run.
131  *
132  * @param bio the binary IO handler
133  * @param retry_ctx the retry ctx to release
134  * @param reason why this packet is being released
135  */
137 
138 fr_bio_t *fr_bio_retry_alloc(TALLOC_CTX *ctx, size_t max_saved,
139  fr_bio_retry_sent_t sent,
140  fr_bio_retry_response_t response,
141  fr_bio_retry_rewrite_t rewrite,
142  fr_bio_retry_release_t release,
143  fr_bio_retry_config_t const *cfg,
144  fr_bio_t *next) CC_HINT(nonnull(1,3,4,6,7,8));
145 
146 int fr_bio_retry_entry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx) CC_HINT(nonnull(1));
147 
149 
151 
152 ssize_t fr_bio_retry_rewrite(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size) CC_HINT(nonnull(1,2));
153 
155 
156 size_t fr_bio_retry_outstanding(fr_bio_t *bio) CC_HINT(nonnull);
157 
159 
160 #undef _CONST
static int const char char buffer[256]
Definition: acutest.h:574
Definition: base.h:112
fr_bio_t * fr_bio_retry_alloc(TALLOC_CTX *ctx, size_t max_saved, fr_bio_retry_sent_t sent, fr_bio_retry_response_t response, fr_bio_retry_rewrite_t rewrite, fr_bio_retry_release_t release, fr_bio_retry_config_t const *cfg, fr_bio_t *next))
Allocate a fr_bio_retry_t.
Definition: retry.c:1087
fr_bio_retry_entry_t * fr_bio_retry_item_reserve(fr_bio_t *bio)
Reserve an entry for later use with fr_bio_retry_rewrite()
Definition: retry.c:1184
fr_retry_t _CONST retry
retry timers and counters
Definition: retry.h:75
fr_time_t last_sent
last time we sent a packet.
Definition: retry.h:56
fr_event_list_t * el
event list
Definition: retry.h:51
void * rewrite_ctx
context specifically for rewriting this packet
Definition: retry.c:68
fr_retry_config_t retry_config
base retry config
Definition: retry.h:47
void(* fr_bio_retry_release_t)(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, fr_bio_retry_release_reason_t reason)
Callback on release the packet (timeout or have all replies)
Definition: retry.h:136
int fr_bio_retry_entry_init(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, fr_retry_config_t const *cfg)
fr_bio_retry_release_reason_t
Definition: retry.h:79
@ FR_BIO_RETRY_WRITE_ERROR
Definition: retry.h:83
@ FR_BIO_RETRY_FATAL_ERROR
Definition: retry.h:84
@ FR_BIO_RETRY_CANCELLED
Definition: retry.h:82
@ FR_BIO_RETRY_DONE
Definition: retry.h:80
@ FR_BIO_RETRY_NO_REPLY
Definition: retry.h:81
size_t fr_bio_retry_outstanding(fr_bio_t *bio)
Definition: retry.c:1165
fr_bio_retry_config_t const * cfg
so we know what was asked
Definition: retry.h:61
size_t size
size of the cached packet
Definition: retry.c:81
void(* fr_bio_retry_sent_t)(fr_bio_t *bio, void *packet_ctx, const void *buffer, size_t size, fr_bio_retry_entry_t *retry_ctx)
Callback for when a packet is sent.
Definition: retry.h:98
ssize_t(* fr_bio_retry_rewrite_t)(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size)
Definition: retry.h:66
ssize_t fr_bio_retry_rewrite(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size))
Resend a packet.
Definition: retry.c:554
#define _CONST
Definition: retry.h:39
fr_time_t first_sent
first time we sent a packet since going idle
Definition: retry.h:55
bool(* fr_bio_retry_response_t)(fr_bio_t *bio, fr_bio_retry_entry_t **item_p, void *packet_ctx, const void *buffer, size_t size)
Callback on read to see if a packet is a response.
Definition: retry.h:123
fr_event_list_t * el
event list
Definition: retry.h:45
fr_time_t mrs_time
Most recent sent time which had a reply.
Definition: retry.h:53
void * packet_ctx
packet_ctx from the write() call
Definition: retry.c:66
fr_time_t last_reply
When we last received a reply.
Definition: retry.h:54
const fr_retry_t * fr_bio_retry_entry_info(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx)
int fr_bio_retry_entry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx))
Cancel one item.
Definition: retry.c:993
fr_bio_retry_rewrite_t rewrite
per-packet rewrite callback
Definition: retry.c:67
void * uctx
user-writable context
Definition: retry.c:65
bool write_blocked
are writes blocked?
Definition: retry.h:59
fr_bio_retry_info_t const * fr_bio_retry_info(fr_bio_t *bio)
Definition: retry.c:1158
fr_time_t last_idle
last time we had nothing to do
Definition: retry.h:57
Definition: retry.c:64
#define RCSIDH(h, id)
Definition: build.h:482
next
Definition: dcursor.h:178
Stores all information relating to an event list.
Definition: event.c:411
long int ssize_t
Definition: merged_model.c:24
unsigned char bool
Definition: merged_model.c:19
"server local" time.
Definition: time.h:69
int nonnull(2, 5))