From: Alan T. DeKok Date: Tue, 16 May 2017 18:07:47 +0000 (-0400) Subject: move old listener code to a separate function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f34f0bfa083495bc3a339c5ae8f4a06ebfd9ef5;p=thirdparty%2Ffreeradius-server.git move old listener code to a separate function --- diff --git a/src/modules/proto_radius/proto_radius_acct.c b/src/modules/proto_radius/proto_radius_acct.c index 5407b474e0b..e2259533e00 100644 --- a/src/modules/proto_radius/proto_radius_acct.c +++ b/src/modules/proto_radius/proto_radius_acct.c @@ -26,9 +26,11 @@ #include #include #include +#include +#include #include -static void acct_running(REQUEST *request, fr_state_action_t action) +static fr_transport_final_t acct_process(REQUEST *request) { VALUE_PAIR *vp; rlm_rcode_t rcode; @@ -38,24 +40,12 @@ static void acct_running(REQUEST *request, fr_state_action_t action) VERIFY_REQUEST(request); - 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: if (request->packet->data_len != 0) { if (fr_radius_packet_decode(request->packet, NULL, request->client->secret) < 0) { RDEBUG("Failed decoding RADIUS packet: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } if (RDEBUG_ENABLED) common_packet_debug(request, request->packet, true); @@ -65,8 +55,6 @@ static void acct_running(REQUEST *request, fr_state_action_t action) rdebug_proto_pair_list(L_DBG_LVL_1, request, request->packet->vps, ""); } - request->server = request->listener->server; - request->server_cs = request->listener->server_cs; request->component = "radius"; da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); @@ -74,14 +62,14 @@ static void acct_running(REQUEST *request, fr_state_action_t action) dv = fr_dict_enum_by_value(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); - goto done; + return FR_TRANSPORT_FAIL; } unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "recv", "*"); if (!unlang) { REDEBUG("Failed to find 'recv' section"); - goto done; + return FR_TRANSPORT_FAIL; } RDEBUG("Running 'recv %s' from file %s", cf_section_name2(unlang), cf_section_filename(unlang)); @@ -93,9 +81,9 @@ static void acct_running(REQUEST *request, fr_state_action_t action) case REQUEST_RECV: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto done; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -122,7 +110,7 @@ static void acct_running(REQUEST *request, fr_state_action_t action) case RLM_MODULE_REJECT: case RLM_MODULE_USERLOCK: default: - goto done; + return FR_TRANSPORT_FAIL; } /* @@ -157,9 +145,9 @@ static void acct_running(REQUEST *request, fr_state_action_t action) case REQUEST_SEND: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto done; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -182,7 +170,7 @@ static void acct_running(REQUEST *request, fr_state_action_t action) */ if (!request->reply->code) { RDEBUG("Not sending reply to client."); - goto done; + return FR_TRANSPORT_DONE; } /* @@ -192,7 +180,7 @@ static void acct_running(REQUEST *request, fr_state_action_t action) radlog_request(L_DBG, L_DBG_LVL_1, request, "Sent %s ID %i", fr_packet_codes[request->reply->code], request->reply->id); rdebug_proto_pair_list(L_DBG_LVL_1, request, request->reply->vps, ""); - goto done; + return FR_TRANSPORT_DONE; } #ifdef WITH_UDPFROMTO @@ -211,21 +199,60 @@ static void acct_running(REQUEST *request, fr_state_action_t action) if (fr_radius_packet_encode(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed encoding RADIUS reply: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } if (fr_radius_packet_sign(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed signing RADIUS reply: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } + break; + + default: + return FR_TRANSPORT_FAIL; + } + + return FR_TRANSPORT_REPLY; +} + + +static void acct_running(REQUEST *request, fr_state_action_t action) +{ + fr_transport_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_TRANSPORT_YIELD) return; - if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) { - RDEBUG("Failed sending RADIUS reply: %s", fr_strerror()); + if (rcode == FR_TRANSPORT_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; diff --git a/src/modules/proto_radius/proto_radius_auth.c b/src/modules/proto_radius/proto_radius_auth.c index bd434934bac..aacaa09b6c1 100644 --- a/src/modules/proto_radius/proto_radius_auth.c +++ b/src/modules/proto_radius/proto_radius_auth.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #define REQUEST_SIMULTANEOUS_USE (REQUEST_OTHER_1) @@ -277,7 +279,7 @@ static void auth_reject_delay(REQUEST *request, fr_state_action_t action) } -static void auth_running(REQUEST *request, fr_state_action_t action) +static fr_transport_final_t auth_process(REQUEST *request) { VALUE_PAIR *vp, *auth_type; rlm_rcode_t rcode; @@ -288,43 +290,12 @@ static void auth_running(REQUEST *request, fr_state_action_t action) VERIFY_REQUEST(request); - TRACE_STATE_MACHINE; - - switch (action) { - /* - * Async (in the same thread, tho) signal to be done. - */ - case FR_ACTION_DONE: - goto done; - - /* - * DUP: go poke the request, but don't do anything else. - */ - case FR_ACTION_DUP: -#if 0 - unlang_action(request, FR_ACTION_DUP); -#endif - return; - - /* - * Running: continue. - */ - case FR_ACTION_RUN: - break; - - /* - * We ignore all other actions. - */ - default: - break; - } - switch (request->request_state) { case REQUEST_INIT: if (request->packet->data_len != 0) { if (fr_radius_packet_decode(request->packet, NULL, request->client->secret) < 0) { RDEBUG("Failed decoding RADIUS packet: %s", fr_strerror()); - goto done; /* don't reject it, Message-Authenticator might be wrong */ + return FR_TRANSPORT_FAIL; } if (RDEBUG_ENABLED) common_packet_debug(request, request->packet, true); @@ -334,8 +305,6 @@ static void auth_running(REQUEST *request, fr_state_action_t action) rdebug_proto_pair_list(L_DBG_LVL_1, request, request->packet->vps, ""); } - request->server = request->listener->server; - request->server_cs = request->listener->server_cs; request->component = "radius"; da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); @@ -378,9 +347,9 @@ static void auth_running(REQUEST *request, fr_state_action_t action) case REQUEST_RECV: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto stop_processing; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -479,9 +448,9 @@ static void auth_running(REQUEST *request, fr_state_action_t action) case REQUEST_PROCESS: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto stop_processing; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -568,9 +537,9 @@ static void auth_running(REQUEST *request, fr_state_action_t action) case REQUEST_SIMULTANEOUS_USE: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto stop_processing; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -646,9 +615,9 @@ static void auth_running(REQUEST *request, fr_state_action_t action) case REQUEST_SEND: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto stop_processing; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -729,16 +698,12 @@ static void auth_running(REQUEST *request, fr_state_action_t action) /* * Check for "do not respond". + * + * Not that we return REPLY here, specifically for cleanup_delay! */ if (!request->reply->code) { RDEBUG("Not sending reply to client."); - - /* - * If it's an internally generated request, clean it up now. - */ - if (request->packet->data_len == 0) goto done; - - goto cleanup_delay; + return FR_TRANSPORT_REPLY; } /* @@ -750,7 +715,7 @@ static void auth_running(REQUEST *request, fr_state_action_t action) radlog_request(L_DBG, L_DBG_LVL_1, request, "Sent %s ID %i", fr_packet_codes[request->reply->code], request->reply->id); rdebug_proto_pair_list(L_DBG_LVL_1, request, request->reply->vps, ""); - goto done; + return FR_TRANSPORT_DONE; } #ifdef WITH_UDPFROMTO @@ -765,31 +730,89 @@ static void auth_running(REQUEST *request, fr_state_action_t action) } #endif + if (RDEBUG_ENABLED) common_packet_debug(request, request->reply, false); + if (fr_radius_packet_encode(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed encoding RADIUS reply: %s", fr_strerror()); - goto stop_processing; + return FR_TRANSPORT_FAIL; } if (fr_radius_packet_sign(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed signing RADIUS reply: %s", fr_strerror()); + return FR_TRANSPORT_FAIL; + } + break; - /* - * We can't do anything with the packet. - * Mark it as "no reply", discard any - * state we have, and clean up the packet - * immediately. - */ - stop_processing: + default: + return FR_TRANSPORT_FAIL; + } + + return FR_TRANSPORT_REPLY; +} + + +static void auth_running(REQUEST *request, fr_state_action_t action) +{ + fr_transport_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 = auth_process(request); + if (rcode == FR_TRANSPORT_YIELD) return; + + /* + * We can't do anything with the packet. + * Mark it as "no reply", discard any + * state we have, and clean up the packet + * immediately. + */ + if (rcode == FR_TRANSPORT_FAIL) { request->reply->code = 0; fr_state_discard(global_state, request, request->packet); goto done; } /* - * @fixme: on Access-Reject, set up reject_delay, and associated states. + * Forcibly done, don't do anything else. */ + if (rcode == FR_TRANSPORT_DONE) { + request->reply->code = 0; + fr_state_discard(global_state, request, request->packet); + goto done; + } - if (RDEBUG_ENABLED) common_packet_debug(request, request->reply, false); + rad_assert(rcode == FR_TRANSPORT_REPLY); + + /* + * If we're not replying, we still have cleanup_delay. + */ + if (request->reply->code == 0) { + /* + * Internally generated request: clean it + * up now. + */ + if (request->packet->data_len == 0) goto done; + + goto cleanup_delay; + } /* * If we delay rejects, then calculate the @@ -799,6 +822,7 @@ static void auth_running(REQUEST *request, fr_state_action_t action) ((request->root->reject_delay.tv_sec > 0) || (request->root->reject_delay.tv_usec > 0))) { struct timeval when, delay; + VALUE_PAIR *vp; delay = request->root->reject_delay; @@ -839,19 +863,19 @@ static void auth_running(REQUEST *request, fr_state_action_t action) return; } } - - /* else fall through to sending the response immediately. */ - } + } /* else send the response immediately */ if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed sending RADIUS reply: %s", fr_strerror()); - goto done; } - cleanup_delay: + /* + * And do any necessary cleanup delay. + */ if (request->root->cleanup_delay) { struct timeval when; +cleanup_delay: when.tv_sec = request->root->cleanup_delay; when.tv_usec = 0; @@ -860,8 +884,8 @@ static void auth_running(REQUEST *request, fr_state_action_t action) } /* FALL-THROUGH */ - done: default: + done: (void) fr_heap_extract(request->backlog, request); auth_dup_extract(request); request_thread_done(request); diff --git a/src/modules/proto_radius/proto_radius_coa.c b/src/modules/proto_radius/proto_radius_coa.c index e6fa182de90..11bd642fb61 100644 --- a/src/modules/proto_radius/proto_radius_coa.c +++ b/src/modules/proto_radius/proto_radius_coa.c @@ -26,9 +26,12 @@ #include #include #include +#include +#include #include -static void coa_running(REQUEST *request, fr_state_action_t action) + +static fr_transport_final_t coa_process(REQUEST *request) { VALUE_PAIR *vp; rlm_rcode_t rcode; @@ -38,24 +41,12 @@ static void coa_running(REQUEST *request, fr_state_action_t action) VERIFY_REQUEST(request); - 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: if (request->packet->data_len != 0) { if (fr_radius_packet_decode(request->packet, NULL, request->client->secret) < 0) { RDEBUG("Failed decoding RADIUS packet: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } if (RDEBUG_ENABLED) common_packet_debug(request, request->packet, true); @@ -65,8 +56,6 @@ static void coa_running(REQUEST *request, fr_state_action_t action) rdebug_proto_pair_list(L_DBG_LVL_1, request, request->packet->vps, ""); } - request->server = request->listener->server; - request->server_cs = request->listener->server_cs; request->component = "radius"; da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); @@ -74,14 +63,14 @@ static void coa_running(REQUEST *request, fr_state_action_t action) dv = fr_dict_enum_by_value(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); - goto done; + return FR_TRANSPORT_FAIL; } unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); if (!unlang) unlang = cf_subsection_find_name2(request->server_cs, "recv", "*"); if (!unlang) { REDEBUG("Failed to find 'recv' section"); - goto done; + return FR_TRANSPORT_FAIL; } RDEBUG("Running 'recv %s' from file %s", cf_section_name2(unlang), cf_section_filename(unlang)); @@ -93,9 +82,9 @@ static void coa_running(REQUEST *request, fr_state_action_t action) case REQUEST_RECV: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto done; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -161,9 +150,9 @@ static void coa_running(REQUEST *request, fr_state_action_t action) case REQUEST_SEND: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto done; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -221,7 +210,7 @@ static void coa_running(REQUEST *request, fr_state_action_t action) */ if (!request->reply->code) { RDEBUG("Not sending reply to client."); - goto done; + return FR_TRANSPORT_DONE; } /* @@ -231,7 +220,7 @@ static void coa_running(REQUEST *request, fr_state_action_t action) radlog_request(L_DBG, L_DBG_LVL_1, request, "Sent %s ID %i", fr_packet_codes[request->reply->code], request->reply->id); rdebug_proto_pair_list(L_DBG_LVL_1, request, request->reply->vps, ""); - goto done; + return FR_TRANSPORT_DONE; } #ifdef WITH_UDPFROMTO @@ -250,16 +239,54 @@ static void coa_running(REQUEST *request, fr_state_action_t action) if (fr_radius_packet_encode(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed encoding RADIUS reply: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } if (fr_radius_packet_sign(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed signing RADIUS reply: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } + break; + + default: + return FR_TRANSPORT_FAIL; + } + + return FR_TRANSPORT_REPLY; +} + + +static void coa_running(REQUEST *request, fr_state_action_t action) +{ + fr_transport_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_TRANSPORT_YIELD) return; - if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) { - RDEBUG("Failed sending RADIUS reply: %s", fr_strerror()); + if (rcode == FR_TRANSPORT_REPLY) { + if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) { + RDEBUG("Failed sending RADIUS reply: %s", fr_strerror()); + } } /* FALL-THROUGH */ diff --git a/src/modules/proto_radius/proto_radius_status.c b/src/modules/proto_radius/proto_radius_status.c index 7c269978880..029c1db3469 100644 --- a/src/modules/proto_radius/proto_radius_status.c +++ b/src/modules/proto_radius/proto_radius_status.c @@ -26,9 +26,11 @@ #include #include #include +#include +#include #include -static void status_running(REQUEST *request, fr_state_action_t action) +static fr_transport_final_t status_process(REQUEST *request) { rlm_rcode_t rcode; CONF_SECTION *unlang; @@ -37,24 +39,12 @@ static void status_running(REQUEST *request, fr_state_action_t action) VERIFY_REQUEST(request); - 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: if (request->packet->data_len != 0) { if (fr_radius_packet_decode(request->packet, NULL, request->client->secret) < 0) { RDEBUG("Failed decoding RADIUS packet: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } if (RDEBUG_ENABLED) common_packet_debug(request, request->packet, true); @@ -64,8 +54,6 @@ static void status_running(REQUEST *request, fr_state_action_t action) rdebug_proto_pair_list(L_DBG_LVL_1, request, request->packet->vps, ""); } - request->server = request->listener->server; - request->server_cs = request->listener->server_cs; request->component = "radius"; da = fr_dict_attr_by_num(NULL, 0, PW_PACKET_TYPE); @@ -73,7 +61,7 @@ static void status_running(REQUEST *request, fr_state_action_t action) dv = fr_dict_enum_by_value(NULL, da, fr_box_uint32(request->packet->code)); if (!dv) { REDEBUG("Failed to find value for &request:Packet-Type"); - goto done; + return FR_TRANSPORT_FAIL; } unlang = cf_subsection_find_name2(request->server_cs, "recv", dv->alias); @@ -92,9 +80,9 @@ static void status_running(REQUEST *request, fr_state_action_t action) case REQUEST_RECV: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto done; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -136,9 +124,9 @@ static void status_running(REQUEST *request, fr_state_action_t action) case REQUEST_SEND: rcode = unlang_interpret_continue(request); - if (request->master_state == REQUEST_STOP_PROCESSING) goto done; + if (request->master_state == REQUEST_STOP_PROCESSING) return FR_TRANSPORT_DONE; - if (rcode == RLM_MODULE_YIELD) return; + if (rcode == RLM_MODULE_YIELD) return FR_TRANSPORT_YIELD; request->log.unlang_indent = 0; @@ -182,7 +170,7 @@ static void status_running(REQUEST *request, fr_state_action_t action) */ if (!request->reply->code) { RDEBUG("Not sending reply to client."); - goto done; + return FR_TRANSPORT_DONE; } /* @@ -192,7 +180,7 @@ static void status_running(REQUEST *request, fr_state_action_t action) radlog_request(L_DBG, L_DBG_LVL_1, request, "Sent %s ID %i", fr_packet_codes[request->reply->code], request->reply->id); rdebug_proto_pair_list(L_DBG_LVL_1, request, request->reply->vps, ""); - goto done; + return FR_TRANSPORT_DONE; } #ifdef WITH_UDPFROMTO @@ -211,16 +199,54 @@ static void status_running(REQUEST *request, fr_state_action_t action) if (fr_radius_packet_encode(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed encoding RADIUS reply: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } if (fr_radius_packet_sign(request->reply, request->packet, request->client->secret) < 0) { RDEBUG("Failed signing RADIUS reply: %s", fr_strerror()); - goto done; + return FR_TRANSPORT_FAIL; } + break; + + default: + return FR_TRANSPORT_FAIL; + } + + return FR_TRANSPORT_REPLY; +} - if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) { - RDEBUG("Failed sending RADIUS reply: %s", fr_strerror()); + +static void status_running(REQUEST *request, fr_state_action_t action) +{ + fr_transport_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 = status_process(request); + if (rcode == FR_TRANSPORT_YIELD) return; + + if (rcode == FR_TRANSPORT_REPLY) { + if (fr_radius_packet_send(request->reply, request->packet, request->client->secret) < 0) { + RDEBUG("Failed sending RADIUS reply: %s", fr_strerror()); + } } /* FALL-THROUGH */