From: Nick Porter Date: Mon, 14 Oct 2024 16:59:33 +0000 (+0100) Subject: Update rlm_sql_firebird to use trunk connections X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9cf3b40cfbb59bb199041a88d80ba553ea21212;p=thirdparty%2Ffreeradius-server.git Update rlm_sql_firebird to use trunk connections --- diff --git a/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c b/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c index 6ddbf2947c6..d73362e7c79 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c @@ -24,110 +24,153 @@ RCSID("$Id$") #include "sql_fbapi.h" #include +#include "rlm_sql_trunk.h" -static int _sql_socket_destructor(rlm_sql_firebird_conn_t *conn) +static char tpb[] = {isc_tpb_version3, isc_tpb_wait, isc_tpb_write, + isc_tpb_read_committed, isc_tpb_no_rec_version}; + +/** Establish connection to the db + * + */ +CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function */ +static connection_state_t _sql_connection_init(void **h, connection_t *conn, void *uctx) { - DEBUG2("socket destructor called, closing socket"); + rlm_sql_t const *sql = talloc_get_type_abort_const(uctx, rlm_sql_t); + rlm_sql_firebird_conn_t *c; - fb_commit(conn); - if (conn->dbh) { - fb_free_statement(conn); - isc_detach_database(conn->status, &(conn->dbh)); + MEM(c = talloc_zero(conn, rlm_sql_firebird_conn_t)); - if (fb_error(conn)) WARN("Got error when closing socket: %s", conn->error); - } + /* + * Firebird uses a client assigned structure to write info about output data. + * Based on standard authorize queries, we pre-allocate a structure + * for 5 columns in SELECT queries. + */ + MEM(c->sqlda_out = (XSQLDA *)_talloc_array(conn, 1, XSQLDA_LENGTH(5), "XSQLDA")); + c->sqlda_out->sqln = 5; + c->sqlda_out->version = SQLDA_VERSION1; + c->sql_dialect = 3; - talloc_free_children(conn); + /* + * Set tpb to read_committed/wait/no_rec_version + */ + c->tpb = tpb; + c->tpb_len = NUM_ELEMENTS(tpb); - return 0; + if (fb_connect(c, &sql->config)) { + ERROR("Connection failed: %s", c->error); + return CONNECTION_STATE_FAILED; + } + + *h = c; + return CONNECTION_STATE_CONNECTED; } -/** Establish connection to the db - * - */ -static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, - UNUSED fr_time_delta_t timeout) +static void _sql_connection_close(UNUSED fr_event_list_t *el, void *h, UNUSED void *uctx) { - rlm_sql_firebird_conn_t *conn; - - long res; + rlm_sql_firebird_conn_t *c = talloc_get_type_abort(h, rlm_sql_firebird_conn_t); - MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_firebird_conn_t)); - talloc_set_destructor(conn, _sql_socket_destructor); + DEBUG2("Socket destructor called, closing socket"); - res = fb_init_socket(conn); - if (res) return RLM_SQL_ERROR; + fb_commit(c); + if (c->dbh) { + fb_free_statement(c); + isc_detach_database(c->status, &(c->dbh)); - if (fb_connect(conn, config)) { - ERROR("Connection failed: %s", conn->error); - - return RLM_SQL_RECONNECT; + if (fb_error(c)) WARN("Got error when closing socket: %s", c->error); } - return 0; + talloc_free_children(c); } -/** Issue a query to the database. - * - */ -static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) +SQL_TRUNK_CONNECTION_ALLOC + +CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function */ +static void sql_trunk_request_mux(UNUSED fr_event_list_t *el, trunk_connection_t *tconn, + connection_t *conn, UNUSED void *uctx) { - fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); - rlm_sql_firebird_conn_t *conn = query_ctx->handle->conn; + rlm_sql_firebird_conn_t *sql_conn = talloc_get_type_abort(conn->h, rlm_sql_firebird_conn_t); + trunk_request_t *treq; + request_t *request; + fr_sql_query_t *query_ctx; + bool deadlock = false; - int deadlock = 0; + if (trunk_connection_pop_request(&treq, tconn) != 0) return; + if (!treq) return; + + query_ctx = talloc_get_type_abort(treq->preq, fr_sql_query_t); + request = query_ctx->request; + query_ctx->tconn = tconn; + + ROPTIONAL(RDEBUG2, DEBUG2, "Executing query: %s", query_ctx->query_str); try_again: /* * Try again query when deadlock, because in any case it * will be retried. */ - if (fb_sql_query(conn, query_ctx->query_str)) { + if (fb_sql_query(sql_conn, query_ctx->query_str)) { /* but may be lost for short sessions */ - if ((conn->sql_code == DEADLOCK_SQL_CODE) && - !deadlock) { - DEBUG("conn_id deadlock. Retry query %s", query_ctx->query_str); + if ((sql_conn->sql_code == DEADLOCK_SQL_CODE) && !deadlock) { + ROPTIONAL(RWARN, WARN, "SQL deadlock. Retry query %s", query_ctx->query_str); /* * @todo For non READ_COMMITED transactions put * rollback here * fb_rollback(conn); */ - deadlock = 1; + deadlock = true; goto try_again; } - ERROR("conn_id rlm_sql_firebird,sql_query error: sql_code=%li, error='%s', query=%s", - (long int) conn->sql_code, conn->error, query_ctx->query_str); - if (conn->sql_code == DOWN_SQL_CODE) { + ROPTIONAL(RERROR, ERROR, "conn_id rlm_sql_firebird,sql_query error: sql_code=%li, error='%s', query=%s", + (long int) sql_conn->sql_code, sql_conn->error, query_ctx->query_str); + + query_ctx->status = SQL_QUERY_FAILED; + trunk_request_signal_fail(treq); + + if (sql_conn->sql_code == DOWN_SQL_CODE) { + reconnect: query_ctx->rcode = RLM_SQL_RECONNECT; - RETURN_MODULE_FAIL; + connection_signal_reconnect(conn, CONNECTION_FAILED); + return; } /* Free problem query */ - if (fb_rollback(conn)) { + if (fb_rollback(sql_conn)) { //assume the network is down if rollback had failed - ERROR("Fail to rollback transaction after previous error: %s", conn->error); + ROPTIONAL(RERROR, ERROR, "Fail to rollback transaction after previous error: %s", sql_conn->error); - query_ctx->rcode = RLM_SQL_RECONNECT; - RETURN_MODULE_FAIL; + goto reconnect; } - // conn->in_use=0; query_ctx->rcode = RLM_SQL_ERROR; - RETURN_MODULE_FAIL; - } - - if (conn->statement_type != isc_info_sql_stmt_select) { - if (fb_commit(conn)) { - query_ctx->rcode = RLM_SQL_ERROR; - RETURN_MODULE_FAIL; - } + return; } query_ctx->rcode = RLM_SQL_OK; - RETURN_MODULE_OK; + query_ctx->status = SQL_QUERY_RETURNED; + trunk_request_signal_reapable(treq); + if (request) unlang_interpret_mark_runnable(request); +} + +SQL_QUERY_RESUME + +static void sql_request_complete(UNUSED request_t *request, void *preq, UNUSED void *rctx, UNUSED void *uctx) +{ + fr_sql_query_t *query_ctx = talloc_get_type_abort(preq, fr_sql_query_t); + rlm_sql_firebird_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_firebird_conn_t); + + fb_commit(conn); +} + +static void sql_request_fail(UNUSED request_t *request, void *preq, UNUSED void *rctx, + UNUSED trunk_request_state_t state, UNUSED void *uctx) +{ + fr_sql_query_t *query_ctx = talloc_get_type_abort(preq, fr_sql_query_t); + + query_ctx->treq = NULL; + if (query_ctx->rcode == RLM_SQL_OK) query_ctx->rcode = RLM_SQL_ERROR; } /** Returns name of fields. @@ -135,7 +178,7 @@ static unlang_action_t sql_query(rlm_rcode_t *p_result, UNUSED int *priority, UN */ static sql_rcode_t sql_fields(char const **out[], fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config) { - rlm_sql_firebird_conn_t *conn = query_ctx->handle->conn; + rlm_sql_firebird_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_firebird_conn_t); int fields, i; char const **names; @@ -157,8 +200,7 @@ static sql_rcode_t sql_fields(char const **out[], fr_sql_query_t *query_ctx, UNU static unlang_action_t sql_fetch_row(rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, void *uctx) { fr_sql_query_t *query_ctx = talloc_get_type_abort(uctx, fr_sql_query_t); - rlm_sql_handle_t *handle = query_ctx->handle; - rlm_sql_firebird_conn_t *conn = handle->conn; + rlm_sql_firebird_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_firebird_conn_t); int res; query_ctx->row = NULL; @@ -186,29 +228,16 @@ static unlang_action_t sql_fetch_row(rlm_rcode_t *p_result, UNUSED int *priority RETURN_MODULE_OK; } -/** End the select query, such as freeing memory or result. - * - */ -static sql_rcode_t sql_finish_select_query(fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config) -{ - rlm_sql_firebird_conn_t *conn = (rlm_sql_firebird_conn_t *) query_ctx->handle->conn; - - fb_commit(conn); - fb_free_statement(conn); - talloc_free_children(conn->sqlda_out); - - return 0; -} - -/** End the query +/** End the query, such as freeing memory or result. * */ -static sql_rcode_t sql_finish_query(UNUSED fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config) +static sql_rcode_t sql_finish_query(fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config) { - rlm_sql_firebird_conn_t *conn = (rlm_sql_firebird_conn_t *) query_ctx->handle->conn; + rlm_sql_firebird_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_firebird_conn_t); fb_free_statement(conn); talloc_free_children(conn->sqlda_out); + query_ctx->status = SQL_QUERY_PREPARED; return 0; } @@ -235,7 +264,7 @@ static sql_rcode_t sql_free_result(UNUSED fr_sql_query_t *query_ctx, UNUSED rlm_ static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], NDEBUG_UNUSED size_t outlen, fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config) { - rlm_sql_firebird_conn_t *conn = query_ctx->handle->conn; + rlm_sql_firebird_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_firebird_conn_t); fr_assert(conn); fr_assert(outlen > 0); @@ -253,7 +282,9 @@ static size_t sql_error(UNUSED TALLOC_CTX *ctx, sql_log_entry_t out[], NDEBUG_UN */ static int sql_affected_rows(fr_sql_query_t *query_ctx, UNUSED rlm_sql_config_t const *config) { - return fb_affected_rows(query_ctx->handle->conn); + rlm_sql_firebird_conn_t *conn = talloc_get_type_abort(query_ctx->tconn->conn->h, rlm_sql_firebird_conn_t); + + return fb_affected_rows(conn); } /* Exported to rlm_sql */ @@ -263,14 +294,20 @@ rlm_sql_driver_t rlm_sql_firebird = { .name = "sql_firebird", .magic = MODULE_MAGIC_INIT }, - .sql_socket_init = sql_socket_init, - .sql_query = sql_query, - .sql_select_query = sql_query, + .sql_query_resume = sql_query_resume, + .sql_select_query_resume = sql_query_resume, .sql_affected_rows = sql_affected_rows, .sql_fetch_row = sql_fetch_row, .sql_fields = sql_fields, .sql_free_result = sql_free_result, .sql_error = sql_error, .sql_finish_query = sql_finish_query, - .sql_finish_select_query = sql_finish_select_query + .sql_finish_select_query = sql_finish_query, + .uses_trunks = true, + .trunk_io_funcs = { + .connection_alloc = sql_trunk_connection_alloc, + .request_mux = sql_trunk_request_mux, + .request_complete = sql_request_complete, + .request_fail = sql_request_fail + } }; diff --git a/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c b/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c index 4a5f6baf4ff..2b699817830 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c @@ -25,22 +25,6 @@ RCSID("$Id$") #include -static void fb_set_tpb(rlm_sql_firebird_conn_t *conn, int count, ...) -{ - int i; - va_list arg; - - va_start(arg, count); - MEM(conn->tpb = talloc_array(conn, char, count)); - - for (i = 0; i < count; i++) conn->tpb[i] = (char) va_arg(arg, int); - - conn->tpb_len = count; - - va_end(arg); -} - - static void fb_dpb_add_str(char **dpb, char name, char const *value) { int l; @@ -315,23 +299,6 @@ sql_rcode_t fb_store_row(rlm_sql_firebird_conn_t *conn) return RLM_SQL_OK; } -int fb_init_socket(rlm_sql_firebird_conn_t *conn) -{ - MEM(conn->sqlda_out = (XSQLDA *)_talloc_array(conn, 1, XSQLDA_LENGTH(5), "XSQLDA")); - conn->sqlda_out->sqln = 5; - conn->sqlda_out->version = SQLDA_VERSION1; - conn->sql_dialect = 3; - - /* - * Set tpb to read_committed/wait/no_rec_version - */ - fb_set_tpb(conn, 5, isc_tpb_version3, isc_tpb_wait, isc_tpb_write, - isc_tpb_read_committed, isc_tpb_no_rec_version); - if (!conn->tpb) return -1; - - return 0; -} - int fb_connect(rlm_sql_firebird_conn_t *conn, rlm_sql_config_t const *config) { char *p, *buff = NULL; diff --git a/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.h b/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.h index c353d975b3f..8553b54bdf6 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.h +++ b/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.h @@ -67,7 +67,6 @@ typedef struct { int fb_free_result(rlm_sql_firebird_conn_t *conn); int fb_error(rlm_sql_firebird_conn_t *conn); -int fb_init_socket(rlm_sql_firebird_conn_t *conn); int fb_connect(rlm_sql_firebird_conn_t *conn, rlm_sql_config_t const *config); int fb_disconnect(rlm_sql_firebird_conn_t *conn); int fb_sql_query(rlm_sql_firebird_conn_t *conn, char const *query);