From: Arran Cudbard-Bell Date: Sat, 20 Mar 2021 18:20:39 +0000 (+0000) Subject: Use internal times for the state tree X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0fea6e3bddbfdf45445daadd13b539aa8d5cfe24;p=thirdparty%2Ffreeradius-server.git Use internal times for the state tree Don't has the current server cs, use a unique id provided by the process module. --- diff --git a/src/lib/server/state.c b/src/lib/server/state.c index 2f3b83b95cd..50a6d9d7dad 100644 --- a/src/lib/server/state.c +++ b/src/lib/server/state.c @@ -75,7 +75,7 @@ typedef struct { //!< to locate authentication sessions originating //!< from a particular backend authentication server. - uint32_t server_hash; //!< Hash of the current virtual server, xor'd with + uint32_t context_id; //!< Hash of the current virtual server, xor'd with //!< r1, r2, r3, r4 after the original state value //!< is sent, but before the state entry is inserted //!< into the tree. The receiving virtual server @@ -100,7 +100,7 @@ typedef struct { }; uint64_t seq_start; //!< Number of first request in this sequence. - time_t cleanup; //!< When this entry should be cleaned up. + fr_time_t cleanup; //!< When this entry should be cleaned up. fr_dlist_t list; //!< Entry in the list of things to expire. int tries; @@ -139,12 +139,14 @@ struct fr_state_tree_s { rbtree_t *tree; //!< rbtree used to lookup state value. fr_dlist_head_t to_expire; //!< Linked list of entries to free. - uint32_t timeout; //!< How long to wait before cleaning up state entires. + fr_time_delta_t timeout; //!< How long to wait before cleaning up state entires. bool thread_safe; //!< Whether we lock the tree whilst modifying it. pthread_mutex_t mutex; //!< Synchronisation mutex. uint8_t server_id; //!< ID to use for load balancing. + uint32_t context_id; //!< ID binding state values to a context such + ///< as a virtual server. fr_dict_attr_t const *da; //!< State attribute used. }; @@ -197,12 +199,15 @@ static int _state_tree_free(fr_state_tree_t *state) * @param[in] max_sessions we track state for. * @param[in] timeout How long to wait before cleaning up entries. * @param[in] server_id ID byte to use in load-balancing operations. + * @param[in] context_id Specifies a unique ctx id to prevent states being + * used in contexts for which they weren't intended. * @return * - A new state tree. * - NULL on failure. */ fr_state_tree_t *fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, bool thread_safe, - uint32_t max_sessions, uint32_t timeout, uint8_t server_id) + uint32_t max_sessions, fr_time_delta_t timeout, + uint8_t server_id, uint32_t context_id) { fr_state_tree_t *state; @@ -243,6 +248,7 @@ fr_state_tree_t *fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, b state->da = da; /* Remember which attribute we use to load/store state */ state->server_id = server_id; + state->context_id = context_id; state->thread_safe = thread_safe; return state; @@ -312,7 +318,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, request_t *r { size_t i; uint32_t x; - time_t now = time(NULL); + fr_time_t now = fr_time(); fr_pair_t *vp; fr_state_entry_t *entry, *next; @@ -506,7 +512,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, request_t *r * only succeed in the virtual server that created the state * value. */ - *((uint32_t *)(&entry->state_comp.server_hash)) ^= fr_hash_string(cf_section_name2(request->server_cs)); + *((uint32_t *)(&entry->state_comp.context_id)) ^= state->context_id; if (!rbtree_insert(state->tree, entry)) { RERROR("Failed inserting state entry - Insertion into state tree failed"); @@ -527,7 +533,7 @@ static fr_state_entry_t *state_entry_create(fr_state_tree_t *state, request_t *r /** Find the entry, based on the State attribute * */ -static fr_state_entry_t *state_entry_find(fr_state_tree_t *state, request_t *request, fr_value_box_t const *vb) +static fr_state_entry_t *state_entry_find(fr_state_tree_t *state, fr_value_box_t const *vb) { fr_state_entry_t *entry, my_entry; @@ -556,7 +562,7 @@ static fr_state_entry_t *state_entry_find(fr_state_tree_t *state, request_t *req /* * Make it unique for different virtual servers handling the same request */ - my_entry.state_comp.server_hash ^= fr_hash_string(cf_section_name2(request->server_cs)); + my_entry.state_comp.context_id ^= state->context_id; entry = rbtree_find_data(state->tree, &my_entry); @@ -577,7 +583,7 @@ void fr_state_discard(fr_state_tree_t *state, request_t *request) if (!vp) return; PTHREAD_MUTEX_LOCK(&state->mutex); - entry = state_entry_find(state, request, &vp->data); + entry = state_entry_find(state, &vp->data); if (!entry) { PTHREAD_MUTEX_UNLOCK(&state->mutex); return; @@ -634,7 +640,7 @@ void fr_state_to_request(fr_state_tree_t *state, request_t *request) } PTHREAD_MUTEX_LOCK(&state->mutex); - entry = state_entry_find(state, request, &vp->data); + entry = state_entry_find(state, &vp->data); if (entry) { (void)talloc_get_type_abort(entry, fr_state_entry_t); if (entry->thawed) { @@ -698,7 +704,7 @@ int fr_request_to_state(fr_state_tree_t *state, request_t *request) vp = fr_pair_find_by_da(&request->request_pairs, state->da); PTHREAD_MUTEX_LOCK(&state->mutex); - if (vp) old = state_entry_find(state, request, &vp->data); + if (vp) old = state_entry_find(state, &vp->data); entry = state_entry_create(state, request, &request->reply_pairs, old); if (!entry) { diff --git a/src/lib/server/state.h b/src/lib/server/state.h index 6a75500056d..3f37ea0cb08 100644 --- a/src/lib/server/state.h +++ b/src/lib/server/state.h @@ -36,7 +36,8 @@ extern "C" { typedef struct fr_state_tree_s fr_state_tree_t; fr_state_tree_t *fr_state_tree_init(TALLOC_CTX *ctx, fr_dict_attr_t const *da, bool thread_safe, - uint32_t max_sessions, uint32_t timeout, uint8_t server_id); + uint32_t max_sessions, fr_time_delta_t timeout, + uint8_t server_id, uint32_t context_id); void fr_state_discard(fr_state_tree_t *state, request_t *request); diff --git a/src/process/radius/base.c b/src/process/radius/base.c index e0fafe77118..d4b6ea32c04 100644 --- a/src/process/radius/base.c +++ b/src/process/radius/base.c @@ -127,7 +127,7 @@ typedef struct { char const *denied_msg; //!< Additional text to append if the user is already logged //!< in (simultaneous use check failed). - uint32_t session_timeout; //!< Maximum time between the last response and next request. + fr_time_delta_t session_timeout; //!< Maximum time between the last response and next request. uint32_t max_session; //!< Maximum ongoing session allowed. uint8_t state_server_id; //!< Sets a specific byte in the state to allow the @@ -152,7 +152,7 @@ typedef struct { #include static const CONF_PARSER session_config[] = { - { FR_CONF_OFFSET("timeout", FR_TYPE_UINT32, process_radius_auth_t, session_timeout), .dflt = "15" }, + { FR_CONF_OFFSET("timeout", FR_TYPE_TIME_DELTA, process_radius_auth_t, session_timeout), .dflt = "15" }, { FR_CONF_OFFSET("max", FR_TYPE_UINT32, process_radius_auth_t, max_session), .dflt = "4096" }, { FR_CONF_OFFSET("state_server_id", FR_TYPE_UINT8, process_radius_auth_t, state_server_id) }, @@ -691,7 +691,8 @@ static int mod_instantiate(void *instance, UNUSED CONF_SECTION *process_app_cs) process_radius_t *inst = instance; inst->auth.state_tree = fr_state_tree_init(inst, attr_state, main_config->spawn_workers, inst->auth.max_session, - inst->auth.session_timeout, inst->auth.state_server_id); + inst->auth.session_timeout, inst->auth.state_server_id, + fr_hash_string(cf_section_name2(inst->server_cs))); return 0; } diff --git a/src/process/tacacs/base.c b/src/process/tacacs/base.c index 04e583d27d0..09ed6f5eb4c 100644 --- a/src/process/tacacs/base.c +++ b/src/process/tacacs/base.c @@ -56,7 +56,7 @@ typedef struct { } tacacs_unlang_t; typedef struct { - uint32_t session_timeout; //!< Maximum time between the last response and next request. + fr_time_delta_t session_timeout; //!< Maximum time between the last response and next request. uint32_t max_session; //!< Maximum ongoing session allowed. uint8_t state_server_id; //!< Sets a specific byte in the state to allow the @@ -69,10 +69,12 @@ typedef struct { tacacs_unlang_t auth_cont; tacacs_unlang_t autz; tacacs_unlang_t acct; + + CONF_SECTION *server_cs; } process_tacacs_t; static const CONF_PARSER session_config[] = { - { FR_CONF_OFFSET("timeout", FR_TYPE_UINT32, process_tacacs_t, session_timeout), .dflt = "15" }, + { FR_CONF_OFFSET("timeout", FR_TYPE_TIME_DELTA, process_tacacs_t, session_timeout), .dflt = "15" }, { FR_CONF_OFFSET("max", FR_TYPE_UINT32, process_tacacs_t, max_session), .dflt = "4096" }, { FR_CONF_OFFSET("state_server_id", FR_TYPE_UINT8, process_tacacs_t, state_server_id) }, @@ -190,11 +192,11 @@ static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mc ctx = &inst->auth_start; break; - case FR_PACKET_TYPE_VALUE_AUTHORIZATION_REQUEST: + case FR_PACKET_TYPE_VALUE_AUTHORIZATION_REQUEST: ctx = &inst->autz; break; - case FR_PACKET_TYPE_VALUE_ACCOUNTING_REQUEST: + case FR_PACKET_TYPE_VALUE_ACCOUNTING_REQUEST: ctx = &inst->acct; break; @@ -351,7 +353,7 @@ static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mc } else if (ctx->attr_process == attr_tacacs_accounting_flags) { vp = fr_pair_find_by_da(&request->request_pairs, attr_tacacs_accounting_flags); if (!vp) goto setup_send; - + dv = fr_dict_enum_by_value(vp->da, &vp->data); if (!dv) goto setup_send; @@ -367,7 +369,7 @@ static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mc } request->request_state = REQUEST_PROCESS; - + } else { goto setup_send; } @@ -499,7 +501,8 @@ static int mod_instantiate(void *instance, UNUSED CONF_SECTION *process_app_cs) * connection. */ inst->state_tree = fr_state_tree_init(inst, attr_tacacs_state, main_config->spawn_workers, inst->max_session, - inst->session_timeout, inst->state_server_id); + inst->session_timeout, inst->state_server_id, + fr_hash_string(cf_section_name2(inst->server_cs))); return 0; } @@ -514,6 +517,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *process_app_cs) fr_assert(strcmp(cf_section_name1(server_cs), "server") == 0); + inst->server_cs = server_cs; if (virtual_server_section_attribute_define(server_cs, "authenticate", attr_auth_type) < 0) return -1; /* @@ -599,7 +603,7 @@ static virtual_server_compile_t compile_list[] = { }, /* authorization */ - + { .name = "recv", .name2 = "Authorization-Request",