uint32_t mrd; //!< Maximum retransmission duration
} rlm_radius_retry_t;
-typedef struct rlm_radius_client_io_ctx_t rlm_radius_client_io_ctx_t;
-
/*
* Define a structure for our module configuration.
*/
struct timeval idle_timeout;
dl_instance_t *io_submodule; //!< As provided by the transport_parse
- fr_radius_client_io_t *client_io; //!< Easy access to the client_io handle
+ fr_radius_client_io_t const *client_io; //!< Easy access to the client_io handle
void *client_io_instance; //!< Easy access to the client_io instance
CONF_SECTION *client_io_conf; //!< Easy access to the client_io's config section
FR_INTEGER_BOUND_CHECK("Disconnect-Request.mrc", inst->packets[FR_CODE_DISCONNECT_REQUEST].mrc, <=, 10);
FR_INTEGER_BOUND_CHECK("Disconnect-Request.mrd", inst->packets[FR_CODE_DISCONNECT_REQUEST].mrd, <=, 30);
+ inst->client_io = (fr_radius_client_io_t const *) inst->io_submodule->module->common;
+ inst->client_io_instance = inst->io_submodule->data;
+ inst->client_io_conf = inst->io_submodule->conf;
+
rad_assert(inst->client_io->io_inst_size > 0);
if (!inst->client_io->bootstrap) return 0;
static int mod_thread_instantiate(CONF_SECTION const *cs, void *instance, fr_event_list_t *el, void *thread)
{
rlm_radius_t *inst = talloc_get_type_abort(instance, rlm_radius_t);
- rlm_radius_thread_t *t = talloc_get_type_abort(thread, rlm_radius_thread_t);
+ rlm_radius_thread_t *t = thread;
rlm_radius_connection_t *c;
+ (void) talloc_set_type(t, rlm_radius_thread_t);
+
+ t->inst = instance;
+
c = talloc_zero(t, rlm_radius_connection_t);
c->name = "<pending>";
c->inst = inst;
.config = module_config,
.bootstrap = mod_bootstrap,
.instantiate = mod_instantiate,
+
+ .thread_inst_size = sizeof(rlm_radius_thread_t),
.thread_instantiate = mod_thread_instantiate,
.thread_detach = mod_thread_detach,
.methods = {
// @todo - finish it!
-// * track packets in RB tree when writing them
-// * do ID allocation based on packet code
-// * simple: just allow for any type of packet code. The rlm_radius will take care of giving us
-// only the codes which are allowed
// * implement remove(), which removes packets from the tracking tree
// * don't make request_io_ctx talloc'd from rlm_radius_link_t, as the link can be used
// * for other connections. it's simpler to just have one remove() func, than to muck with
#include <freeradius-devel/rad_assert.h>
#include "rlm_radius.h"
+#include "track.h"
typedef struct rlm_radius_udp_t {
fr_ipaddr_t dst_ipaddr; //!< IP of the home server
} rlm_radius_udp_t;
-typedef struct udp_io_ctx_t {
+struct rlm_radius_client_io_ctx_t {
rlm_radius_udp_t const *inst; //!< our module instance
uint32_t max_packet_size; //!< our max packet size. may be different from the parent...
int fd; //!< file descriptor
// @todo - track status-server, open, signaling, etc.
- // @todo - track outstanding IDs, one per packet code...
-
uint8_t *buffer; //!< receive buffer
size_t buflen; //!< receive buffer length
-} udp_io_ctx_t;
+
+ rlm_radius_id_t *id[FR_MAX_PACKET_CODE]; //!< ID tracking
+};
typedef struct request_ctx_t {
uint8_t header[20];
static int mod_write(REQUEST *request, void *request_ctx, void *io_ctx)
{
- udp_io_ctx_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
+ rlm_radius_client_io_ctx_t *io = talloc_get_type_abort(io_ctx, rlm_radius_client_io_ctx_t);
request_ctx_t *track = (request_ctx_t *) request_ctx; /* not talloc'd */
ssize_t packet_len, data_size;
+ rlm_radius_request_t *rr;
+
+ rad_assert(request->packet->code > 0);
+ rad_assert(request->packet->code < FR_MAX_PACKET_CODE);
+
+ /*
+ * Create the tracking table if it doesn't already exist.
+ *
+ * @todo - move this into the "init" routine? where was can examine
+ * the rlm_radius_t, and create the relevant data structures.
+ */
+ if (!io->id[request->packet->code]) {
+ io->id[request->packet->code] = rr_track_create(io_ctx);
+ if (!io->id[request->packet->code]) {
+ RDEBUG("Failed creating tracking table for code %d", request->packet->code);
+ return -1;
+ }
+ }
+
+ /*
+ * Allocate an ID
+ */
+ rr = rr_track_alloc(io->id[request->packet->code], request, request->packet->code, io, request_ctx);
+ if (!rr) {
+ RDEBUG("Failed allocating packet ID for code %d", request->packet->code);
+ return -1;
+ }
packet_len = fr_radius_encode(io->buffer, io->buflen, NULL, io->inst->secret, strlen(io->inst->secret),
- request->packet->code, 0, request->packet->vps);
+ rr->code, rr->id, request->packet->vps);
if (packet_len < 0) {
RDEBUG("Failed encoding packet: %s", fr_strerror());
data_size = udp_send(io->fd, io->buffer, packet_len, 0,
&io->dst_ipaddr, io->dst_port,
-// address->if_index,
- 0,
+ 0, /* if_index */
&io->src_ipaddr, io->src_port);
// @todo - put the packet into an RB tree, too, so we can find replies...
- memcpy(&track->header ,io->buffer, 20);
+ memcpy(&track->header, io->buffer, 20);
if (data_size < packet_len) {
rad_assert(0 == 1);
*/
static char const *mod_get_name(TALLOC_CTX *ctx, void *io_ctx)
{
- udp_io_ctx_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
+ rlm_radius_client_io_ctx_t *io = talloc_get_type_abort(io_ctx, rlm_radius_client_io_ctx_t);
char src_buf[FR_IPADDR_STRLEN], dst_buf[FR_IPADDR_STRLEN];
fr_inet_ntop(dst_buf, sizeof(dst_buf), &io->dst_ipaddr);
*/
static void mod_close(int fd, void *io_ctx)
{
- udp_io_ctx_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
+ rlm_radius_client_io_ctx_t *io = talloc_get_type_abort(io_ctx, rlm_radius_client_io_ctx_t);
if (shutdown(fd, SHUT_RDWR) < 0) DEBUG3("Shutdown on socket (%i) failed: %s", fd, fr_syserror(errno));
if (close(fd) < 0) DEBUG3("Closing socket (%i) failed: %s", fd, fr_syserror(errno));
*/
static fr_connection_state_t mod_open(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED void *io_ctx)
{
-// udp_io_ctx_t_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
+// rlm_radius_client_io_ctx_t_t *io = talloc_get_type_abort(io_ctx, rlm_radius_client_io_ctx_t);
// @todo - create the initial Status-Server for negotiation and send that
static fr_connection_state_t mod_init(int *fd_out, void *io_ctx, void const *uctx)
{
int fd;
- udp_io_ctx_t *io = talloc_get_type_abort(io_ctx, udp_io_ctx_t);
+ rlm_radius_client_io_ctx_t *io = talloc_get_type_abort(io_ctx, rlm_radius_client_io_ctx_t);
rlm_radius_udp_t const *inst = talloc_get_type_abort(uctx, rlm_radius_udp_t);
io->inst = inst;
.magic = RLM_MODULE_INIT,
.name = "radius_udp",
.inst_size = sizeof(rlm_radius_udp_t),
+ .io_inst_size = sizeof(rlm_radius_client_io_ctx_t),
.request_inst_size = sizeof(request_ctx_t),
.config = module_config,
.bootstrap = mod_bootstrap,