From: Arran Cudbard-Bell Date: Mon, 19 Jun 2017 04:23:39 +0000 (-0400) Subject: First pass over proto_radius_* modules converting them to the new IO framework X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8740fae211c9929358034915ec06fd599bc107b;p=thirdparty%2Ffreeradius-server.git First pass over proto_radius_* modules converting them to the new IO framework --- diff --git a/src/modules/proto_radius/proto_radius_acct.c b/src/modules/proto_radius/proto_radius_acct.c index f956f478f0e..95da4f4d0fc 100644 --- a/src/modules/proto_radius/proto_radius_acct.c +++ b/src/modules/proto_radius/proto_radius_acct.c @@ -1,8 +1,4 @@ /* - * 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 @@ -16,21 +12,24 @@ * 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 */ -#include -#include +/** + * $Id$ + * @file proto_radius_acct.c + * @brief RADIUS accounting processing. + * + * @copyright 2016 The FreeRADIUS server project. + * @copyright 2016 Alan DeKok (aland@deployingradius.com) + */ +#include #include -#include -#include -#include -#include +#include +#include +#include #include -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; @@ -215,148 +214,6 @@ static fr_io_final_t acct_process(REQUEST *request) 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; @@ -374,13 +231,15 @@ static int acct_compile_section(CONF_SECTION *server_cs, char const *name1, char 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; @@ -407,33 +266,10 @@ static int acct_listen_compile(CONF_SECTION *server_cs, UNUSED CONF_SECTION *lis 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, }; diff --git a/src/modules/proto_radius/proto_radius_auth.c b/src/modules/proto_radius/proto_radius_auth.c index 37c67a1c02a..8e7640c1e9d 100644 --- a/src/modules/proto_radius/proto_radius_auth.c +++ b/src/modules/proto_radius/proto_radius_auth.c @@ -1,8 +1,4 @@ /* - * 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 @@ -16,19 +12,21 @@ * 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 */ -#include -#include +/** + * $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 #include -#include +#include +#include #include -#include -#include -#include #include #ifndef USEC @@ -695,22 +693,21 @@ static fr_io_final_t auth_process(REQUEST *request) 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: @@ -721,7 +718,7 @@ static void auth_running(REQUEST *request, fr_state_action_t action) 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. @@ -803,7 +800,7 @@ static void auth_running(REQUEST *request, fr_state_action_t action) (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 */ @@ -822,8 +819,11 @@ cleanup_delay: 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 */ @@ -835,119 +835,10 @@ cleanup_delay: 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; @@ -1025,11 +916,19 @@ static int auth_listen_compile(CONF_SECTION *server_cs, UNUSED CONF_SECTION *lis 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"); @@ -1074,43 +973,10 @@ static int auth_listen_bootstrap(CONF_SECTION *server_cs, UNUSED CONF_SECTION *l 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, }; diff --git a/src/modules/proto_radius/proto_radius_coa.c b/src/modules/proto_radius/proto_radius_coa.c index efac64ca9c2..0d458c196d5 100644 --- a/src/modules/proto_radius/proto_radius_coa.c +++ b/src/modules/proto_radius/proto_radius_coa.c @@ -1,8 +1,4 @@ /* - * 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 @@ -16,22 +12,23 @@ * 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 */ -#include -#include +/** + * $Id$ + * @file proto_radius_coa.c + * @brief RADIUS CoA processing. + * + * @copyright 2016 The FreeRADIUS server project. + * @copyright 2016 Alan DeKok (aland@deployingradius.com) + */ +#include #include -#include -#include -#include -#include +#include +#include #include - -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; @@ -255,150 +252,6 @@ static fr_io_final_t coa_process(REQUEST *request) 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; @@ -416,16 +269,17 @@ static int coa_compile_section(CONF_SECTION *server_cs, char const *name1, char 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; @@ -475,32 +329,10 @@ static int coa_listen_compile(CONF_SECTION *server_cs, UNUSED CONF_SECTION *list 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, }; diff --git a/src/modules/proto_radius/proto_radius_status.c b/src/modules/proto_radius/proto_radius_status.c index 69df368706e..b40d52812a7 100644 --- a/src/modules/proto_radius/proto_radius_status.c +++ b/src/modules/proto_radius/proto_radius_status.c @@ -16,7 +16,7 @@ /** * $Id$ - * @file proto_radius.c + * @file proto_radius_status.c * @brief RADIUS Status-Server processing. * * @copyright 2016 The FreeRADIUS server project.