The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
radius_bio_tests.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library 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 GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/** Tests for the RADIUS bio verify callbacks
18 *
19 * The verify callbacks are fr_radius_bio_verify() for stream sockets, and
20 * fr_radius_bio_verify_datagram() for datagram sockets. The tests call
21 * the callbacks directly, and the stream callback also through a memory bio.
22 *
23 * @file src/protocols/radius/tests/radius_bio_tests.c
24 *
25 * @copyright 2026 Network RADIUS SAS (legal@networkradius.com)
26 */
27#include <freeradius-devel/util/test/acutest_common_init.h>
28#include <freeradius-devel/util/test/acutest_helpers.h>
29
30#include <freeradius-devel/bio/bio_priv.h>
31#include <freeradius-devel/bio/mem.h>
32#include <freeradius-devel/bio/pipe.h>
33#include <freeradius-devel/radius/bio.h>
34
35#define MESSAGE_AUTHENTICATOR 80
36
37#define MAX_PACKET_SIZE 4096
38
39static int cb_noop(fr_bio_t *bio) { (void) bio; return 0; }
40static void cb_noop_void(fr_bio_t *bio) { (void) bio; }
41
44 .write_resume = cb_noop,
45 .read_blocked = cb_noop,
46 .write_blocked = cb_noop,
47 .eof = cb_noop_void,
48};
49
50/** Make a verify context which allows Access-Request and Access-Accept.
51 */
53{
54 return (fr_radius_bio_verify_t) {
55 .max_attributes = 200,
56 .max_packet_size = MAX_PACKET_SIZE,
57 .allowed = {
60 },
61 };
62}
63
64/** Build a packet with a header, and the given attributes.
65 *
66 * @param[out] out where to write the packet.
67 * @param[in] code of the packet.
68 * @param[in] attrs to copy after the header, which may be NULL.
69 * @param[in] attrs_len length of the attributes.
70 * @return the length of the packet.
71 */
72static size_t make_packet(uint8_t *out, uint8_t code, uint8_t const *attrs, size_t attrs_len)
73{
74 size_t len = RADIUS_HEADER_LENGTH + attrs_len;
75
76 memset(out, 0, len);
77 out[0] = code;
78 out[1] = 1;
79 out[2] = len >> 8;
80 out[3] = len & 0xff;
81
82 if (attrs_len) memcpy(out + RADIUS_HEADER_LENGTH, attrs, attrs_len);
83
84 return len;
85}
86
87/** Make a packet whose attributes are a User-Name of "ab".
88 */
89static size_t make_valid(uint8_t *out, uint8_t code)
90{
91 static uint8_t const user_name[] = { 1, 4, 'a', 'b' };
92
93 return make_packet(out, code, user_name, sizeof(user_name));
94}
95
96/** Call the stream verify callback on a buffer holding in_buffer bytes.
97 */
98static fr_bio_verify_action_t stream_verify(fr_radius_bio_verify_t *ctx, uint8_t const *buf, size_t in_buffer,
99 size_t *size_out)
100{
101 fr_bio_t dummy = {};
102 size_t size = in_buffer;
104
105 action = fr_radius_bio_verify(&dummy, ctx, NULL, buf, &size);
106 if (size_out) *size_out = size;
107
108 return action;
109}
110
111/** Call the datagram verify callback on a buffer holding in_buffer bytes.
112 */
114 size_t *size_out)
115{
116 fr_bio_t dummy = {};
117 size_t size = in_buffer;
119
120 action = fr_radius_bio_verify_datagram(&dummy, ctx, NULL, buf, &size);
121 if (size_out) *size_out = size;
122
123 return action;
124}
125
126/*
127 * Stream sockets, calling the callback directly.
128 */
129
130/** A buffer which holds less than a header asks for the header.
131 */
133{
136 size_t size;
137 size_t in_buffer;
138
140
141 /*
142 * 3 is less than the length field, 4 is the length field alone, and 19 is one byte short of a
143 * header. None of them is an error, as TCP can split a packet anywhere.
144 */
145 for (in_buffer = 0; in_buffer < RADIUS_HEADER_LENGTH; in_buffer++) {
146 TEST_CASE("less than a header");
147 TEST_MSG("in_buffer = %zu", in_buffer);
148 TEST_CHECK(stream_verify(&ctx, buf, in_buffer, &size) == FR_BIO_VERIFY_WANT_MORE);
150 }
151}
152
153/** A complete packet is returned, and only that packet.
154 */
155static void test_stream_one_packet(void)
156{
159 size_t len, size;
160
162
163 TEST_CASE("exactly one packet");
164 TEST_CHECK(stream_verify(&ctx, buf, len, &size) == FR_BIO_VERIFY_OK);
165 TEST_CHECK_LEN(size, len);
166
167 TEST_CASE("one packet, and the start of another");
169 TEST_CHECK(stream_verify(&ctx, buf, len + 7, &size) == FR_BIO_VERIFY_OK);
170 TEST_CHECK_LEN(size, len);
171
172 TEST_CASE("two packets");
173 TEST_CHECK(stream_verify(&ctx, buf, len * 2, &size) == FR_BIO_VERIFY_OK);
174 TEST_CHECK_LEN(size, len);
175}
176
177/** A packet which is not all in the buffer asks for the rest of the packet.
178 */
180{
183 size_t len, size;
184
186
187 TEST_CASE("the header, and no attributes");
189 TEST_CHECK_LEN(size, len);
190
191 TEST_CASE("all but the last byte");
192 TEST_CHECK(stream_verify(&ctx, buf, len - 1, &size) == FR_BIO_VERIFY_WANT_MORE);
193 TEST_CHECK_LEN(size, len);
194}
195
196/** A packet with a code which the module does not know is skipped, and the packets after it are kept.
197 */
199{
202 size_t len, size;
203 uint8_t code;
204
205 len = make_valid(buf, 0);
207
208 /*
209 * Code 0 is invalid, FR_RADIUS_CODE_MAX is the first code which is too large, and 255 is the
210 * largest value.
211 */
212 for (code = 0; ; code = (code == 0) ? FR_RADIUS_CODE_MAX : 255) {
213 TEST_CASE("unknown code, followed by a valid packet");
214 TEST_MSG("code = %u", code);
215 buf[0] = code;
216 TEST_CHECK(stream_verify(&ctx, buf, len * 2, &size) == FR_BIO_VERIFY_DISCARD);
217 TEST_CHECK_LEN(size, len);
218
219 if (code == 255) break;
220 }
221}
222
223/** A packet with a code which is known, but not allowed, is skipped.
224 */
225static void test_stream_not_allowed(void)
226{
229 size_t len, size;
230
233
234 TEST_CHECK(stream_verify(&ctx, buf, len * 2, &size) == FR_BIO_VERIFY_DISCARD);
235 TEST_CHECK_LEN(size, len);
236}
237
238/** A packet with more attributes than the limit is skipped, and the packets after it are kept.
239 */
241{
244 uint8_t const attrs[] = { 1, 3, 'a', 1, 3, 'b', 1, 3, 'c' };
245 size_t len, size;
246
247 ctx.max_attributes = 2;
248
249 len = make_packet(buf, FR_RADIUS_CODE_ACCESS_REQUEST, attrs, sizeof(attrs));
251
252 TEST_CASE("three attributes, limit of two");
253 TEST_CHECK(stream_verify(&ctx, buf, len * 2, &size) == FR_BIO_VERIFY_DISCARD);
254 TEST_CHECK_LEN(size, len);
255
256 TEST_CASE("two attributes, limit of two");
258 TEST_CHECK(stream_verify(&ctx, buf, len, &size) == FR_BIO_VERIFY_OK);
259 TEST_CHECK_LEN(size, len);
260}
261
262/** Errors which leave the stream without a known start of the next packet close the connection.
263 */
264static void test_stream_fatal(void)
265{
268 size_t len, size;
269 uint8_t const *attrs;
270
271 struct {
272 char const *name;
273 uint8_t const *attrs;
274 size_t len;
275 } const *p, bad[] = {
276#define BAD(_name, ...) { _name, (uint8_t const[]) { __VA_ARGS__ }, sizeof((uint8_t const[]) { __VA_ARGS__ }) }
277 BAD("attribute number zero", 0, 3, 'a'),
278 BAD("attribute length of zero", 1, 0, 'a'),
279 BAD("attribute length of one", 1, 1, 'a'),
280 BAD("attribute runs past the packet", 1, 9, 'a'),
281 BAD("a single byte after the attributes", 1, 3, 'a', 1),
282 BAD("Message-Authenticator is too short", MESSAGE_AUTHENTICATOR, 10, 0, 0, 0, 0, 0, 0, 0, 0),
283 BAD("two Message-Authenticators",
284 MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285 MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
286#undef BAD
287 };
288
289 for (p = bad; p < (bad + NUM_ELEMENTS(bad)); p++) {
290 len = make_packet(buf, FR_RADIUS_CODE_ACCESS_REQUEST, p->attrs, p->len);
291
292 TEST_CASE(p->name);
294 }
295
296 TEST_CASE("length field is less than a header");
298 buf[2] = 0;
299 buf[3] = RADIUS_HEADER_LENGTH - 1;
301
302 TEST_CASE("Message-Authenticator is required, and missing");
306
307 TEST_CASE("Message-Authenticator is required, and present");
308 attrs = (uint8_t const[]) { MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
310 TEST_CHECK(stream_verify(&ctx, buf, len, &size) == FR_BIO_VERIFY_OK);
311 TEST_CHECK_LEN(size, len);
312}
313
314/** A packet which is larger than the module allows closes the connection, even when only the header has arrived.
315 */
316static void test_stream_too_large(void)
317{
320 uint8_t attrs[200];
321 size_t len, size, i;
322
323 ctx.max_packet_size = 64;
324
325 for (i = 0; i < sizeof(attrs); i += 4) {
326 attrs[i] = 1;
327 attrs[i + 1] = 4;
328 attrs[i + 2] = 'a';
329 attrs[i + 3] = 'b';
330 }
331
332 len = make_packet(buf, FR_RADIUS_CODE_ACCESS_REQUEST, attrs, sizeof(attrs));
334
335 TEST_CASE("only the header of a large packet");
337
338 TEST_CASE("all of a large packet");
340
341 TEST_CASE("a packet of exactly the maximum");
344 TEST_CHECK(stream_verify(&ctx, buf, len, &size) == FR_BIO_VERIFY_OK);
345 TEST_CHECK_LEN(size, len);
346}
347
348/*
349 * Datagram sockets, calling the callback directly.
350 */
351
352/** A datagram holds one packet, and trailing bytes are padding.
353 */
355{
358 size_t len, size;
359
361
362 TEST_CASE("exactly one packet");
363 TEST_CHECK(datagram_verify(&ctx, buf, len, &size) == FR_BIO_VERIFY_OK);
364 TEST_CHECK_LEN(size, len);
365
366 TEST_CASE("padding after the packet is not part of the packet");
367 memset(buf + len, 0xff, 9);
368 TEST_CHECK(datagram_verify(&ctx, buf, len + 9, &size) == FR_BIO_VERIFY_OK);
369 TEST_CHECK_LEN(size, len);
370}
371
372/** A datagram which is not a good packet is discarded, and never closes the socket.
373 */
374static void test_datagram_discard(void)
375{
378 uint8_t const attrs[] = { 1, 3, 'a', 1, 3, 'b', 1, 3, 'c' };
379 size_t len, size;
380
382
383 TEST_CASE("less than a header");
385
386 TEST_CASE("the length field is larger than the datagram");
387 TEST_CHECK(datagram_verify(&ctx, buf, len - 1, &size) == FR_BIO_VERIFY_DISCARD);
388
389 TEST_CASE("the length field is less than a header");
390 buf[2] = 0;
391 buf[3] = RADIUS_HEADER_LENGTH - 1;
393
394 TEST_CASE("unknown code");
395 len = make_valid(buf, 0);
399
400 TEST_CASE("code which is not allowed");
403
404 TEST_CASE("bad attribute");
405 len = make_packet(buf, FR_RADIUS_CODE_ACCESS_REQUEST, (uint8_t const[]) { 1, 9, 'a' }, 3);
407
408 TEST_CASE("Message-Authenticator is too short");
410 (uint8_t const[]) { MESSAGE_AUTHENTICATOR, 3, 0 }, 3);
412
413 TEST_CASE("Message-Authenticator is required, and missing");
418
419 TEST_CASE("too many attributes");
420 ctx.max_attributes = 2;
421 len = make_packet(buf, FR_RADIUS_CODE_ACCESS_REQUEST, attrs, sizeof(attrs));
423 ctx.max_attributes = 200;
424
425 TEST_CASE("larger than the maximum");
426 ctx.max_packet_size = 20;
429}
430
431/*
432 * Stream sockets, through a memory bio.
433 */
434
435/** A memory bio in front of a pipe, which stands in for the network.
436 */
437static fr_bio_t *test_mem_alloc(TALLOC_CTX *ctx, fr_bio_t **source_p, fr_radius_bio_verify_t *vctx)
438{
439 fr_bio_t *mem, *source;
440
441 source = fr_bio_pipe_alloc(ctx, &test_cb, 1024);
442 if (!source) return NULL;
443
444 mem = fr_bio_mem_alloc(ctx, 1024, 0, source);
445 if (!mem) return NULL;
446
447 if (fr_bio_mem_set_verify(mem, fr_radius_bio_verify, vctx, false) < 0) return NULL;
448
449 *source_p = source;
450 return mem;
451}
452
453/** Put bytes where the memory bio's reads will find them.
454 */
455static ssize_t test_source_write(fr_bio_t *source, uint8_t const *data, size_t size)
456{
457 return source->write(source, NULL, data, size);
458}
459
460/** A packet which the module does not accept does not take the packets after it.
461 */
463{
464 TALLOC_CTX *ctx = talloc_init_const("test");
466 fr_bio_t *mem, *source;
468 size_t len;
469 ssize_t slen;
470
471 mem = test_mem_alloc(ctx, &source, &vctx);
472 TEST_CHECK(mem != NULL);
473 if (!mem) goto done;
474
475 len = make_valid(in, 200);
478 TEST_CHECK_SLEN(test_source_write(source, in, len * 2), (ssize_t) (len * 2));
479
480 TEST_CASE("the valid packet is returned");
481 slen = fr_bio_read(mem, NULL, out, sizeof(out));
482 TEST_CHECK_SLEN(slen, (ssize_t) len);
483 if (slen == (ssize_t) len) TEST_CHECK(memcmp(out, good, len) == 0);
484
485 TEST_CASE("nothing else is left");
486 TEST_CHECK_SLEN(fr_bio_read(mem, NULL, out, sizeof(out)), 0);
487
488done:
489 talloc_free(ctx);
490}
491
492/** A packet which arrives in pieces is returned when the packet is complete, and the connection stays open.
493 */
494static void test_mem_split_packet(void)
495{
496 TALLOC_CTX *ctx = talloc_init_const("test");
498 fr_bio_t *mem, *source;
500 size_t len;
501
502 mem = test_mem_alloc(ctx, &source, &vctx);
503 TEST_CHECK(mem != NULL);
504 if (!mem) goto done;
505
507
508 /*
509 * The first piece is part of the header, and the second piece ends in the attributes.
510 */
511 TEST_CHECK_SLEN(test_source_write(source, in, 10), 10);
512
513 TEST_CASE("part of the header");
514 TEST_CHECK_SLEN(fr_bio_read(mem, NULL, out, sizeof(out)), 0);
515
516 TEST_CHECK_SLEN(test_source_write(source, in + 10, len - 11), (ssize_t) (len - 11));
517
518 TEST_CASE("all but the last byte");
519 TEST_CHECK_SLEN(fr_bio_read(mem, NULL, out, sizeof(out)), 0);
520
521 TEST_CHECK_SLEN(test_source_write(source, in + len - 1, 1), 1);
522
523 TEST_CASE("the whole packet");
524 TEST_CHECK_SLEN(fr_bio_read(mem, NULL, out, sizeof(out)), (ssize_t) len);
525 TEST_CHECK(memcmp(out, in, len) == 0);
526
527done:
528 talloc_free(ctx);
529}
530
531/** Packets which arrive together are returned one at a time.
532 */
533static void test_mem_two_packets(void)
534{
535 TALLOC_CTX *ctx = talloc_init_const("test");
537 fr_bio_t *mem, *source;
539 size_t len;
540
541 mem = test_mem_alloc(ctx, &source, &vctx);
542 TEST_CHECK(mem != NULL);
543 if (!mem) goto done;
544
547 TEST_CHECK_SLEN(test_source_write(source, in, len * 2), (ssize_t) (len * 2));
548
549 TEST_CASE("first packet");
550 TEST_CHECK_SLEN(fr_bio_read(mem, NULL, out, sizeof(out)), (ssize_t) len);
551 TEST_CHECK(memcmp(out, in, len) == 0);
552
553 TEST_CASE("second packet");
554 TEST_CHECK_SLEN(fr_bio_read(mem, NULL, out, sizeof(out)), (ssize_t) len);
555 TEST_CHECK(memcmp(out, in + len, len) == 0);
556
557done:
558 talloc_free(ctx);
559}
560
561/** A packet which cannot be skipped fails the read.
562 */
563static void test_mem_fatal(void)
564{
565 TALLOC_CTX *ctx = talloc_init_const("test");
567 fr_bio_t *mem, *source;
569 size_t len;
570
571 mem = test_mem_alloc(ctx, &source, &vctx);
572 TEST_CHECK(mem != NULL);
573 if (!mem) goto done;
574
575 len = make_packet(in, FR_RADIUS_CODE_ACCESS_REQUEST, (uint8_t const[]) { 1, 9, 'a' }, 3);
577
578 TEST_CASE("an attribute which runs past the packet");
579 TEST_CHECK(fr_bio_read(mem, NULL, out, sizeof(out)) < 0);
580
581done:
582 talloc_free(ctx);
583}
584
586 { "stream_short_buffer", test_stream_short_buffer },
587 { "stream_one_packet", test_stream_one_packet },
588 { "stream_partial_packet", test_stream_partial_packet },
589 { "stream_unknown_code", test_stream_unknown_code },
590 { "stream_not_allowed", test_stream_not_allowed },
591 { "stream_too_many_attributes", test_stream_too_many_attributes },
592 { "stream_fatal", test_stream_fatal },
593 { "stream_too_large", test_stream_too_large },
594 { "datagram_one_packet", test_datagram_one_packet },
595 { "datagram_discard", test_datagram_discard },
596 { "mem_unknown_code_keeps_next_packet", test_mem_unknown_code_keeps_next_packet },
597 { "mem_split_packet", test_mem_split_packet },
598 { "mem_two_packets", test_mem_two_packets },
599 { "mem_fatal", test_mem_fatal },
600 { NULL, NULL }
601};
#define TEST_CHECK(cond)
Definition acutest.h:101
#define TEST_CASE(name)
Definition acutest.h:203
#define TEST_MSG(...)
Definition acutest.h:234
#define TEST_CHECK_SLEN(_got, _exp)
#define TEST_CHECK_LEN(_got, _exp)
fr_bio_write_t _CONST write
write to the underlying bio
Definition base.h:117
static ssize_t fr_bio_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
Read raw data from a bio.
Definition base.h:161
fr_bio_io_t read_resume
"unblocked" is too similar to "blocked"
Definition base.h:97
#define NUM_ELEMENTS(_t)
Definition build.h:437
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
Definition defs.h:33
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
Definition defs.h:53
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
Definition defs.h:34
@ FR_RADIUS_CODE_ACCOUNTING_RESPONSE
RFC2866 - Accounting-Response.
Definition defs.h:37
talloc_free(hp)
fr_bio_t * fr_bio_mem_alloc(TALLOC_CTX *ctx, size_t read_size, size_t write_size, fr_bio_t *next)
Allocate a memory buffer bio.
Definition mem.c:686
int fr_bio_mem_set_verify(fr_bio_t *bio, fr_bio_verify_t verify, void *verify_ctx, bool datagram)
Set the verification function for memory bios.
Definition mem.c:863
fr_bio_verify_action_t
Status returned by the verification callback.
Definition mem.h:32
@ FR_BIO_VERIFY_ERROR_CLOSE
fatal error, the bio should be closed.
Definition mem.h:36
@ FR_BIO_VERIFY_DISCARD
the packet should be discarded
Definition mem.h:34
@ FR_BIO_VERIFY_OK
packet is OK
Definition mem.h:33
@ FR_BIO_VERIFY_WANT_MORE
not enough data for one packet
Definition mem.h:35
long int ssize_t
unsigned char uint8_t
#define RADIUS_HEADER_LENGTH
Definition net.h:80
fr_bio_t * fr_bio_pipe_alloc(TALLOC_CTX *ctx, fr_bio_cb_funcs_t *cb, size_t buffer_size)
Allocate a thread-safe pipe which can be used for both reads and writes.
Definition pipe.c:187
fr_bio_verify_action_t fr_radius_bio_verify_datagram(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size)
And verify a datagram packet.
Definition bio.c:86
fr_bio_verify_action_t fr_radius_bio_verify(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size)
Callback for RADIUS packet verification.
Definition bio.c:32
uint32_t max_attributes
Definition bio.h:37
bool require_message_authenticator
Definition bio.h:42
uint32_t max_packet_size
Definition bio.h:38
static bool done
Definition radclient.c:80
static void test_stream_unknown_code(void)
A packet with a code which the module does not know is skipped, and the packets after it are kept.
static size_t make_packet(uint8_t *out, uint8_t code, uint8_t const *attrs, size_t attrs_len)
Build a packet with a header, and the given attributes.
static void cb_noop_void(fr_bio_t *bio)
static fr_bio_cb_funcs_t test_cb
static void test_stream_partial_packet(void)
A packet which is not all in the buffer asks for the rest of the packet.
static void test_stream_one_packet(void)
A complete packet is returned, and only that packet.
#define MESSAGE_AUTHENTICATOR
static void test_stream_not_allowed(void)
A packet with a code which is known, but not allowed, is skipped.
static void test_mem_fatal(void)
A packet which cannot be skipped fails the read.
static fr_radius_bio_verify_t test_ctx(void)
Make a verify context which allows Access-Request and Access-Accept.
#define BAD(_name,...)
#define MAX_PACKET_SIZE
static void test_mem_two_packets(void)
Packets which arrive together are returned one at a time.
static fr_bio_verify_action_t datagram_verify(fr_radius_bio_verify_t *ctx, uint8_t const *buf, size_t in_buffer, size_t *size_out)
Call the datagram verify callback on a buffer holding in_buffer bytes.
static void test_datagram_discard(void)
A datagram which is not a good packet is discarded, and never closes the socket.
static void test_stream_too_many_attributes(void)
A packet with more attributes than the limit is skipped, and the packets after it are kept.
static fr_bio_verify_action_t stream_verify(fr_radius_bio_verify_t *ctx, uint8_t const *buf, size_t in_buffer, size_t *size_out)
Call the stream verify callback on a buffer holding in_buffer bytes.
static void test_datagram_one_packet(void)
A datagram holds one packet, and trailing bytes are padding.
static size_t make_valid(uint8_t *out, uint8_t code)
Make a packet whose attributes are a User-Name of "ab".
static void test_mem_split_packet(void)
A packet which arrives in pieces is returned when the packet is complete, and the connection stays op...
static void test_stream_fatal(void)
Errors which leave the stream without a known start of the next packet close the connection.
static fr_bio_t * test_mem_alloc(TALLOC_CTX *ctx, fr_bio_t **source_p, fr_radius_bio_verify_t *vctx)
A memory bio in front of a pipe, which stands in for the network.
static void test_stream_too_large(void)
A packet which is larger than the module allows closes the connection, even when only the header has ...
static ssize_t test_source_write(fr_bio_t *source, uint8_t const *data, size_t size)
Put bytes where the memory bio's reads will find them.
static void test_mem_unknown_code_keeps_next_packet(void)
A packet which the module does not accept does not take the packets after it.
static void test_stream_short_buffer(void)
A buffer which holds less than a header asks for the header.
static int cb_noop(fr_bio_t *bio)
static char const * name
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
Definition talloc.h:127
static fr_sbuff_err_t char size_t fr_sbuff_t * in
Definition value.h:1061
static fr_slen_t data
Definition value.h:1366
static fr_sbuff_err_t char ** out
Definition value.h:1061
static fr_sbuff_err_t char size_t * len
Definition value.h:1061