The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
server_udp.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/**
18 * $Id: f753e259b5d9826882fc06effa42bff7bdd8ca74 $
19 *
20 * @file protocols/radius/server_udp.c
21 * @brief Functions to support RADIUS bio handlers for server udp sockets
22 *
23 * @copyright 2024 Network RADIUS SAS (legal@networkradius.com)
24 */
25RCSID("$Id: f753e259b5d9826882fc06effa42bff7bdd8ca74 $")
26
27#include <freeradius-devel/bio/packet.h>
28#include <freeradius-devel/radius/server_udp.h>
29#include <freeradius-devel/radius/server_priv.h>
30
31static bool radius_server_dedup_receive(fr_bio_t *bio, fr_bio_dedup_entry_t *dedup_ctx, void *packet_ctx)
32{
33 fr_radius_server_fd_bio_t *my = talloc_get_type_abort(bio->uctx, fr_radius_server_fd_bio_t);
35 fr_radius_server_bio_pctx_t *ctx = packet_ctx;
36
37 /*
38 * Find any previous entry.
39 */
40 prev = fr_rb_find(&my->rb, dedup_ctx);
41 if (prev) {
42 // @todo - signal duplicate packet
43 return false;
44 }
45
46 if (!fr_rb_insert(&my->rb, dedup_ctx)) {
47 // @todo - signal an error
48 return false;
49 }
50
51 /*
52 * Glue it all together
53 */
54 dedup_ctx->uctx = ctx;
55 ctx->dedup = dedup_ctx;
56
57 return true;
58}
59
61{
62 fr_radius_server_bio_pctx_t *ctx = packet_ctx;
63
64 return ctx->dedup;
65}
66
68{
69 fr_radius_server_fd_bio_t *my = talloc_get_type_abort(bio->uctx, fr_radius_server_fd_bio_t);
70 fr_radius_server_bio_pctx_t *ctx = dedup_ctx->uctx;
71
72 (void) fr_rb_delete(&my->rb, dedup_ctx);
73 ctx->dedup = NULL;
74}
75
76static int fr_radius_server_udp_bio_read(fr_bio_packet_t *bio, void **packet_ctx_p, fr_packet_t **packet_p,
77 TALLOC_CTX *out_ctx, fr_pair_list_t *out)
78{
79 int rcode;
81
82 /*
83 * Read the packet.
84 */
85 rcode = fr_radius_server_fd_bio_read(bio, packet_ctx_p, packet_p, out_ctx, out);
86 if (rcode < 0) return rcode;
87
88 ctx = *packet_ctx_p;
89
90 /*
91 * The dedup_ctx starts off with the raw data in a buffer somewhere. That buffer will get
92 * over-written with a later packet. So be sure to update the dedup_ctx with the long-term
93 * version of the packet contents.
94 */
95 fr_assert(ctx->dedup->packet_size == (*packet_p)->data_len);
96
97 ctx->dedup->packet = (*packet_p)->data;
98 ctx->dedup->packet_size = (*packet_p)->data_len;
99
100 return 0;
101}
102
103/** Allocate a RADIUS bio for receiving packets from clients.
104 *
105 * It also verifies that the packets we receive are valid for RADIUS.
106 */
108{
110
111 my = fr_radius_server_fd_bio_alloc(ctx, 2 * 4096, cfg, fd_cfg);
112 if (!my) return NULL;
113
114 if (fr_bio_mem_set_verify(my->mem, fr_radius_bio_verify_datagram, &my->cfg.verify, true) < 0) {
115 fail:
117 return NULL;
118 }
119
120 /*
121 * Once we've allocated a FD and memory BIO, UDP needs de-duping.
122 */
125 if (!my->dedup) goto fail;
126 my->dedup->uctx = my;
127
128 my->common.bio = my->dedup;
129
130 my->common.read = fr_radius_server_udp_bio_read;
131 my->common.write = fr_radius_server_fd_bio_write;
132
133 // @todo - insert comparison function
134 // @todo - comparison function is different for connected and unconnected sockets
135
136 return (fr_bio_packet_t *) my;
137}
void * uctx
user ctx, caller can manually set it.
Definition base.h:113
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
fr_bio_t * fr_bio_dedup_alloc(TALLOC_CTX *ctx, size_t max_saved, fr_bio_dedup_receive_t receive, fr_bio_dedup_release_t release, fr_bio_dedup_get_item_t get_item, fr_bio_dedup_config_t const *cfg, fr_bio_t *next)
Allocate a fr_bio_dedup_t.
Definition dedup.c:1036
void * uctx
user-writable context
Definition dedup.c:97
size_t packet_size
size of the cached packet data
Definition dedup.c:100
uint8_t * packet
cached packet data for finding duplicates
Definition dedup.c:99
fr_bio_dedup_release_reason_t
Definition dedup.h:58
Definition dedup.c:96
Configuration for sockets.
Definition fd.h:81
fr_bio_shutdown & my
Definition fd_errno.h:59
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:880
talloc_free(reap)
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:70
#define fr_assert(_expr)
Definition rad_assert.h:38
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:577
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition rb.c:626
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
Definition rb.c:741
int fr_radius_server_fd_bio_read(fr_bio_packet_t *bio, UNUSED void **packet_ctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out)
Definition server.c:134
fr_radius_server_fd_bio_t * fr_radius_server_fd_bio_alloc(TALLOC_CTX *ctx, size_t read_size, fr_radius_server_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
Definition server.c:58
int fr_radius_server_fd_bio_write(fr_bio_packet_t *bio, UNUSED void *pctx, fr_packet_t *reply, fr_pair_list_t *list)
Definition server.c:100
fr_bio_dedup_entry_t * dedup
Definition server.h:54
fr_bio_dedup_config_t dedup_cfg
Definition server.h:39
static bool radius_server_dedup_receive(fr_bio_t *bio, fr_bio_dedup_entry_t *dedup_ctx, void *packet_ctx)
Definition server_udp.c:31
fr_bio_packet_t * fr_radius_server_udp_bio_alloc(TALLOC_CTX *ctx, fr_radius_server_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
Allocate a RADIUS bio for receiving packets from clients.
Definition server_udp.c:107
static fr_bio_dedup_entry_t * radius_server_dedup_get_item(UNUSED fr_bio_t *bio, void *packet_ctx)
Definition server_udp.c:60
static void radius_server_dedup_release(fr_bio_t *bio, fr_bio_dedup_entry_t *dedup_ctx, UNUSED fr_bio_dedup_release_reason_t reason)
Definition server_udp.c:67
static int fr_radius_server_udp_bio_read(fr_bio_packet_t *bio, void **packet_ctx_p, fr_packet_t **packet_p, TALLOC_CTX *out_ctx, fr_pair_list_t *out)
Definition server_udp.c:76
static size_t char ** out
Definition value.h:997