/*
- * proto_radius_acct.c RADIUS accounting processing.
- *
- * Version: $Id$
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2016 The FreeRADIUS server project
- * Copyright 2016 Alan DeKok <aland@deployingradius.com>
*/
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+/**
+ * $Id$
+ * @file proto_radius_acct.c
+ * @brief RADIUS accounting processing.
+ *
+ * @copyright 2016 The FreeRADIUS server project.
+ * @copyright 2016 Alan DeKok (aland@deployingradius.com)
+ */
+#include <freeradius-devel/io/application.h>
#include <freeradius-devel/protocol.h>
-#include <freeradius-devel/process.h>
-#include <freeradius-devel/udp.h>
-#include <freeradius-devel/radius/radius.h>
-#include <freeradius-devel/io/io.h>
+#include <freeradius-devel/modules.h>
+#include <freeradius-devel/dict.h>
+#include <freeradius-devel/state.h>
#include <freeradius-devel/rad_assert.h>
-static fr_io_final_t acct_process(REQUEST *request)
+static fr_io_final_t mod_process(REQUEST *request, UNUSED fr_io_action_t action)
{
VALUE_PAIR *vp;
rlm_rcode_t rcode;
return FR_IO_REPLY;
}
-
-static void acct_running(REQUEST *request, fr_state_action_t action)
-{
- fr_io_final_t rcode;
-
- TRACE_STATE_MACHINE;
-
- /*
- * Async (in the same thread, tho) signal to be done.
- */
- if (action == FR_ACTION_DONE) goto done;
-
- /*
- * We ignore all other actions.
- */
- if (action != FR_ACTION_RUN) return;
-
- switch (request->request_state) {
- case REQUEST_INIT:
- request->server = request->listener->server;
- request->server_cs = request->listener->server_cs;
- /* FALL-THROUGH */
-
- case REQUEST_RECV:
- case REQUEST_SEND:
- rcode = acct_process(request);
- if (rcode == FR_IO_YIELD) return;
-
- if (rcode == FR_IO_REPLY) {
- if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) {
- RDEBUG("Failed sending RADIUS reply: %s", fr_strerror());
- }
- }
- /* FALL-THROUGH */
-
- default:
- done:
- (void) fr_heap_extract(request->backlog, request);
- request_thread_done(request);
- request_delete(request);
- break;
- }
-}
-
-
-/** Process events while the request is queued.
- *
- * We give different messages on DUP, and on DONE,
- * remove the request from the queue
- *
- * \dot
- * digraph acct_queued {
- * acct_queued -> done [ label = "TIMER >= max_request_time" ];
- * acct_queued -> acct_running [ label = "RUNNING" ];
- * }
- * \enddot
- */
-static void acct_queued(REQUEST *request, fr_state_action_t action)
-{
- VERIFY_REQUEST(request);
-
- TRACE_STATE_MACHINE;
-
- switch (action) {
- case FR_ACTION_RUN:
- request->process = acct_running;
- request->process(request, action);
- break;
-
- case FR_ACTION_DONE:
- (void) fr_heap_extract(request->backlog, request);
- request_delete(request);
- break;
-
- default:
- break;
- }
-}
-
-
-/*
- * Check if an incoming request is "ok"
- *
- * It takes packets, not requests. It sees if the packet looks
- * OK. If so, it does a number of sanity checks on it.
- */
-static int acct_socket_recv(rad_listen_t *listener)
-{
- RADIUS_PACKET *packet;
- RADCLIENT *client;
- TALLOC_CTX *ctx;
- REQUEST *request;
-
- ctx = talloc_pool(NULL, main_config.talloc_pool_size);
- if (!ctx) {
- (void) udp_recv_discard(listener->fd);
- return 0;
- }
- talloc_set_name_const(ctx, "acct_listener_pool");
-
- packet = fr_radius_packet_recv(ctx, listener->fd, 0, false);
- if (!packet) {
- ERROR("%s", fr_strerror());
- talloc_free(ctx);
- return 0;
- }
-
- if (packet->code != FR_CODE_ACCOUNTING_REQUEST) {
- if (packet->code < FR_MAX_PACKET_CODE) {
- DEBUG2("Invalid packet code %s sent to accounting port", fr_packet_codes[packet->code]);
- } else {
- DEBUG2("Invalid packet code %d sent to accounting port", packet->code);
- }
- talloc_free(ctx);
- return 0;
- }
-
- if ((client = client_listener_find(listener,
- &packet->src_ipaddr,
- packet->src_port)) == NULL) {
- talloc_free(ctx);
- return 0;
- }
-
- if (request_limit(listener, client, packet)) {
- talloc_free(ctx);
- return 0;
- }
-
- request = request_setup(ctx, listener, packet, client, NULL);
- if (!request) {
- talloc_free(ctx);
- return 0;
- }
-
- request->process = acct_queued;
- request_enqueue(request);
-
- return 1;
-}
-
-
static int acct_compile_section(CONF_SECTION *server_cs, char const *name1, char const *name2, rlm_components_t component)
{
CONF_SECTION *cs;
return 1;
}
-
-/*
- * Ensure that the "radius" section is compiled.
- */
-static int acct_listen_compile(CONF_SECTION *server_cs, UNUSED CONF_SECTION *listen_cs)
+static int mod_instantiate(UNUSED void *instance, CONF_SECTION *listen_cs)
{
int rcode;
+ CONF_SECTION *server_cs;
+
+ rad_assert(listen_cs);
+
+ server_cs = cf_item_to_section(cf_parent(listen_cs));
+ rad_assert(strcmp(cf_section_name1(server_cs), "server") == 0);
rcode = acct_compile_section(server_cs, "recv", "Accounting-Request", MOD_PREACCT);
if (rcode < 0) return rcode;
return 0;
}
-static int acct_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
-{
- listen_socket_t *sock = this->data;
-
- if (common_socket_parse(cs, this) < 0) return -1;
-
- if (!sock->my_port) sock->my_port = FR_ACCT_UDP_PORT;
-
- return 0;
-}
-
-
-extern rad_protocol_t proto_radius_acct;
-rad_protocol_t proto_radius_acct = {
+extern fr_app_process_t proto_radius_status;
+fr_app_process_t proto_radius_status = {
.magic = RLM_MODULE_INIT,
- .name = "radius_acct",
- .inst_size = sizeof(listen_socket_t),
- .transports = TRANSPORT_UDP,
- .tls = false,
- .bootstrap = NULL, /* don't do Acct-Type any more */
- .compile = acct_listen_compile,
- .parse = acct_socket_parse,
- .open = common_socket_open,
- .recv = acct_socket_recv,
- .send = NULL,
- .print = common_socket_print,
- .debug = common_packet_debug,
- .encode = NULL,
- .decode = NULL,
+ .name = "radius_coa",
+ .instantiate = mod_instantiate,
+ .process = mod_process,
};
/*
- * proto_radius_auth.c RADIUS Access-Request processing.
- *
- * Version: $Id$
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2016 The FreeRADIUS server project
- * Copyright 2016 Alan DeKok <aland@deployingradius.com>
*/
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+/**
+ * $Id$
+ * @file proto_radius_auth.c
+ * @brief RADIUS Access-Request processing.
+ *
+ * @copyright 2016 The FreeRADIUS server project.
+ * @copyright 2016 Alan DeKok (aland@deployingradius.com)
+ */
+#include <freeradius-devel/io/application.h>
#include <freeradius-devel/protocol.h>
-#include <freeradius-devel/process.h>
+#include <freeradius-devel/modules.h>
+#include <freeradius-devel/dict.h>
#include <freeradius-devel/state.h>
-#include <freeradius-devel/udp.h>
-#include <freeradius-devel/radius/radius.h>
-#include <freeradius-devel/io/io.h>
#include <freeradius-devel/rad_assert.h>
#ifndef USEC
return FR_IO_REPLY;
}
-
-static void auth_running(REQUEST *request, fr_state_action_t action)
+static fr_io_final_t mod_process(REQUEST *request, fr_io_action_t action)
{
- fr_io_final_t rcode;
+ fr_io_final_t rcode = FR_IO_DONE;
TRACE_STATE_MACHINE;
/*
* Async (in the same thread, tho) signal to be done.
*/
- if (action == FR_ACTION_DONE) goto done;
+ if (action == FR_IO_ACTION_DONE) goto done;
/*
* We ignore all other actions.
*/
- if (action != FR_ACTION_RUN) return;
+ if (action != FR_IO_ACTION_RUN) return FR_IO_DONE;
switch (request->request_state) {
case REQUEST_INIT:
case REQUEST_RECV:
case REQUEST_SEND:
rcode = auth_process(request);
- if (rcode == FR_IO_YIELD) return;
+ if (rcode == FR_IO_YIELD) return FR_IO_YIELD;
/*
* We can't do anything with the packet.
(int) delay.tv_sec, (int) delay.tv_usec);
if (unlang_delay(request, &delay, auth_reject_delay) == 0) {
- return;
+ return FR_IO_YIELD;
}
}
} /* else send the response immediately */
when.tv_sec = request->root->cleanup_delay;
when.tv_usec = 0;
- if (unlang_delay(request, &when, auth_cleanup_delay) < 0) goto done;
- return;
+ if (unlang_delay(request, &when, auth_cleanup_delay) < 0) {
+ rcode = FR_IO_FAIL;
+ goto done;
+ }
+ return FR_IO_YIELD;
}
/* FALL-THROUGH */
request_delete(request);
break;
}
-}
-
-
-/** Process events while the request is queued.
- *
- * We give different messages on DUP, and on DONE,
- * remove the request from the queue
- *
- * \dot
- * digraph auth_queued {
- * auth_queued -> done [ label = "TIMER >= max_request_time" ];
- * auth_queued -> auth_running [ label = "RUNNING" ];
- * }
- * \enddot
- */
-static void auth_queued(REQUEST *request, fr_state_action_t action)
-{
- VERIFY_REQUEST(request);
-
- TRACE_STATE_MACHINE;
-
- switch (action) {
- case FR_ACTION_RUN:
- request->process = auth_running;
- request->process(request, action);
- break;
-
- case FR_ACTION_DONE:
- request_delete(request);
- break;
-
- default:
- break;
- }
-}
-
-
-/*
- * Check if an incoming request is "ok"
- *
- * It takes packets, not requests. It sees if the packet looks
- * OK. If so, it does a number of sanity checks on it.
- */
-static int auth_socket_recv(rad_listen_t *listener)
-{
- RADIUS_PACKET *packet;
- RADCLIENT *client;
- TALLOC_CTX *ctx;
- REQUEST *request;
- listen_socket_t *sock = listener->data;
-
- ctx = talloc_pool(NULL, main_config.talloc_pool_size);
- if (!ctx) {
- (void) udp_recv_discard(listener->fd);
- return 0;
- }
- talloc_set_name_const(ctx, "auth_listener_pool");
-
- packet = fr_radius_packet_recv(ctx, listener->fd, 0, false);
- if (!packet) {
- ERROR("%s", fr_strerror());
- talloc_free(ctx);
- return 0;
- }
-
- if (packet->code != FR_CODE_ACCESS_REQUEST) {
- if (packet->code < FR_MAX_PACKET_CODE) {
- DEBUG2("Invalid packet code %s sent to authentication port", fr_packet_codes[packet->code]);
- } else {
- DEBUG2("Invalid packet code %d sent to authentication port", packet->code);
- }
-
- talloc_free(ctx);
- return 0;
- }
-
- if ((client = client_listener_find(listener,
- &packet->src_ipaddr,
- packet->src_port)) == NULL) {
- talloc_free(ctx);
- return 0;
- }
-
- if (request_dup_received(listener, sock->dup_tree, client, packet)) {
- talloc_free(ctx);
- return 0;
- }
-
- if (request_limit(listener, client, packet)) {
- talloc_free(ctx);
- return 0;
- }
-
- request = request_setup(ctx, listener, packet, client, NULL);
- if (!request) {
- talloc_free(ctx);
- return 0;
- }
-
- if (!rbtree_insert(sock->dup_tree, &request->packet)) {
- RERROR("Failed to insert request in the list of live requests: discarding it");
- request_free(request);
- return 1;
- }
- request->in_request_hash = true;
-
- request->process = auth_queued;
- request_enqueue(request);
- return 1;
+ return rcode;
}
-
static int auth_compile_section(CONF_SECTION *server_cs, char const *name1, char const *name2, rlm_components_t component)
{
CONF_SECTION *cs;
return 0;
}
-static int auth_listen_bootstrap(CONF_SECTION *server_cs, UNUSED CONF_SECTION *listen_cs)
+static int mod_instantiate(UNUSED void *instance, CONF_SECTION *listen_cs)
{
CONF_SECTION *subcs = NULL;;
+ CONF_SECTION *server_cs;
fr_dict_attr_t const *da;
+ rad_assert(listen_cs);
+
+ server_cs = cf_item_to_section(cf_parent(listen_cs));
+ rad_assert(strcmp(cf_section_name1(server_cs), "server") == 0);
+
+ if (auth_listen_compile(server_cs, listen_cs) < 0) return -1;
+
da = fr_dict_attr_by_num(NULL, 0, FR_AUTH_TYPE);
if (!da) {
cf_log_err(server_cs, "Failed finding dictionary definition for Auth-Type");
return 0;
}
-static int packet_entry_cmp(void const *one, void const *two)
-{
- RADIUS_PACKET const * const *a = one;
- RADIUS_PACKET const * const *b = two;
-
- return fr_packet_cmp(*a, *b);
-}
-
-static int auth_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
-{
- listen_socket_t *sock = this->data;
-
- if (common_socket_parse(cs, this) < 0) return -1;
-
- if (!sock->my_port) sock->my_port = FR_AUTH_UDP_PORT;
-
- sock->dup_tree = rbtree_create(NULL, packet_entry_cmp, NULL, 0);
-
- return 0;
-}
-
-
-extern rad_protocol_t proto_radius_auth;
-rad_protocol_t proto_radius_auth = {
+extern fr_app_process_t proto_radius_status;
+fr_app_process_t proto_radius_status = {
.magic = RLM_MODULE_INIT,
- .name = "radius_auth",
- .inst_size = sizeof(listen_socket_t),
- .transports = TRANSPORT_UDP,
- .tls = false,
- .bootstrap = auth_listen_bootstrap,
- .compile = auth_listen_compile,
- .parse = auth_socket_parse,
- .open = common_socket_open,
- .recv = auth_socket_recv,
- .send = NULL,
- .print = common_socket_print,
- .debug = common_packet_debug,
- .encode = NULL,
- .decode = NULL,
+ .name = "radius_coa",
+ .instantiate = mod_instantiate,
+ .process = mod_process,
};
/*
- * proto_radius_coa.c RADIUS CoA processing.
- *
- * Version: $Id$
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2016 The FreeRADIUS server project
- * Copyright 2016 Alan DeKok <aland@deployingradius.com>
*/
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+/**
+ * $Id$
+ * @file proto_radius_coa.c
+ * @brief RADIUS CoA processing.
+ *
+ * @copyright 2016 The FreeRADIUS server project.
+ * @copyright 2016 Alan DeKok (aland@deployingradius.com)
+ */
+#include <freeradius-devel/io/application.h>
#include <freeradius-devel/protocol.h>
-#include <freeradius-devel/process.h>
-#include <freeradius-devel/udp.h>
-#include <freeradius-devel/radius/radius.h>
-#include <freeradius-devel/io/io.h>
+#include <freeradius-devel/modules.h>
+#include <freeradius-devel/dict.h>
#include <freeradius-devel/rad_assert.h>
-
-static fr_io_final_t coa_process(REQUEST *request)
+static fr_io_final_t mod_process(REQUEST *request, UNUSED fr_io_action_t action)
{
VALUE_PAIR *vp;
rlm_rcode_t rcode;
return FR_IO_REPLY;
}
-
-static void coa_running(REQUEST *request, fr_state_action_t action)
-{
- fr_io_final_t rcode;
-
- TRACE_STATE_MACHINE;
-
- /*
- * Async (in the same thread, tho) signal to be done.
- */
- if (action == FR_ACTION_DONE) goto done;
-
- /*
- * We ignore all other actions.
- */
- if (action != FR_ACTION_RUN) return;
-
- switch (request->request_state) {
- case REQUEST_INIT:
- request->server = request->listener->server;
- request->server_cs = request->listener->server_cs;
- /* FALL-THROUGH */
-
- case REQUEST_RECV:
- case REQUEST_SEND:
- rcode = coa_process(request);
- if (rcode == FR_IO_YIELD) return;
-
- if (rcode == FR_IO_REPLY) {
- if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) {
- RDEBUG("Failed sending RADIUS reply: %s", fr_strerror());
- }
- }
- /* FALL-THROUGH */
-
- default:
- done:
- (void) fr_heap_extract(request->backlog, request);
- request_thread_done(request);
- request_delete(request);
- break;
- }
-}
-
-
-/** Process events while the request is queued.
- *
- * We give different messages on DUP, and on DONE,
- * remove the request from the queue
- *
- * \dot
- * digraph coa_queued {
- * coa_queued -> done [ label = "TIMER >= max_request_time" ];
- * coa_queued -> coa_running [ label = "RUNNING" ];
- * }
- * \enddot
- */
-static void coa_queued(REQUEST *request, fr_state_action_t action)
-{
- VERIFY_REQUEST(request);
-
- TRACE_STATE_MACHINE;
-
- switch (action) {
- case FR_ACTION_RUN:
- request->process = coa_running;
- request->process(request, action);
- break;
-
- case FR_ACTION_DONE:
- (void) fr_heap_extract(request->backlog, request);
- fr_event_timer_delete(request->el, &request->ev);
-
- RDEBUG2("Cleaning up request packet ID %u with timestamp +%d",
- request->packet->id,
- (unsigned int) (request->packet->timestamp.tv_sec - fr_start_time));
- request_delete(request);
- break;
-
- default:
- break;
- }
-}
-
-
-/*
- * Check if an incoming request is "ok"
- *
- * It takes packets, not requests. It sees if the packet looks
- * OK. If so, it does a number of sanity checks on it.
- */
-static int coa_socket_recv(rad_listen_t *listener)
-{
- RADIUS_PACKET *packet;
- RADCLIENT *client;
- TALLOC_CTX *ctx;
- REQUEST *request;
-
- ctx = talloc_pool(NULL, main_config.talloc_pool_size);
- if (!ctx) {
- (void) udp_recv_discard(listener->fd);
- return 0;
- }
- talloc_set_name_const(ctx, "coa_listener_pool");
-
- packet = fr_radius_packet_recv(ctx, listener->fd, 0, false);
- if (!packet) {
- ERROR("%s", fr_strerror());
- talloc_free(ctx);
- return 0;
- }
-
- if ((packet->code != FR_CODE_COA_REQUEST) &&
- (packet->code != FR_CODE_DISCONNECT_REQUEST)) {
- DEBUG2("Invalid packet code %d", packet->code);
- talloc_free(ctx);
- return 0;
- }
-
- if ((client = client_listener_find(listener,
- &packet->src_ipaddr,
- packet->src_port)) == NULL) {
- talloc_free(ctx);
- return 0;
- }
-
- if (request_limit(listener, client, packet)) {
- talloc_free(ctx);
- return 0;
- }
-
- request = request_setup(ctx, listener, packet, client, NULL);
- if (!request) {
- talloc_free(ctx);
- return 0;
- }
-
- request->process = coa_queued;
- request_enqueue(request);
-
- return 1;
-}
-
-
static int coa_compile_section(CONF_SECTION *server_cs, char const *name1, char const *name2, rlm_components_t component)
{
CONF_SECTION *cs;
return 1;
}
-
-/*
- * Ensure that the "radius" section is compiled.
- */
-static int coa_listen_compile(CONF_SECTION *server_cs, UNUSED CONF_SECTION *listen_cs)
+static int mod_instantiate(UNUSED void *instance, CONF_SECTION *listen_cs)
{
int rcode;
- bool coa_found, dm_found;
+ CONF_SECTION *server_cs;
+
+ bool coa_found = false, dm_found = false;
+
+ rad_assert(listen_cs);
- coa_found = dm_found = false;
+ server_cs = cf_item_to_section(cf_parent(listen_cs));
+ rad_assert(strcmp(cf_section_name1(server_cs), "server") == 0);
rcode = coa_compile_section(server_cs, "recv", "CoA-Request", MOD_RECV_COA);
if (rcode < 0) return rcode;
return 0;
}
-static int coa_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
-{
- listen_socket_t *sock = this->data;
-
- if (common_socket_parse(cs, this) < 0) return -1;
-
- if (!sock->my_port) sock->my_port = FR_COA_UDP_PORT;
-
- return 0;
-}
-
-extern rad_protocol_t proto_radius_coa;
-rad_protocol_t proto_radius_coa = {
+extern fr_app_process_t proto_radius_status;
+fr_app_process_t proto_radius_status = {
.magic = RLM_MODULE_INIT,
.name = "radius_coa",
- .inst_size = sizeof(listen_socket_t),
- .transports = TRANSPORT_UDP,
- .tls = false,
- .bootstrap = NULL,
- .compile = coa_listen_compile,
- .parse = coa_socket_parse,
- .open = common_socket_open,
- .recv = coa_socket_recv,
- .send = NULL,
- .print = common_socket_print,
- .debug = common_packet_debug,
- .encode = NULL,
- .decode = NULL,
+ .instantiate = mod_instantiate,
+ .process = mod_process,
};
/**
* $Id$
- * @file proto_radius.c
+ * @file proto_radius_status.c
* @brief RADIUS Status-Server processing.
*
* @copyright 2016 The FreeRADIUS server project.