challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

commit a6fb529dddc757000bdc88084b0d28daa86b18ca
parent d775278abdc10146b7234bcd8388f210bdf7d69e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat, 13 Jun 2026 20:58:23 +0200

refactor to use new more robust GNUNET_PQ_init() style to handle database connection drops better

Diffstat:
Msrc/challenger/challenger-admin.c | 3+--
Msrc/challenger/challenger-httpd.c | 11+----------
Msrc/challengerdb/challenger-dbinit.c | 3+--
Msrc/challengerdb/create_tables.c | 31++++++++++++++-----------------
Msrc/challengerdb/drop_tables.c | 21++-------------------
Msrc/challengerdb/pg.c | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/challengerdb/preflight.c | 59+++--------------------------------------------------------
Msrc/challengerdb/test_challenger_db.c | 3+--
Msrc/include/challenger_database_lib.h | 6+-----
9 files changed, 108 insertions(+), 126 deletions(-)

diff --git a/src/challenger/challenger-admin.c b/src/challenger/challenger-admin.c @@ -100,8 +100,7 @@ run (void *cls, return; } if (NULL == - (db = CHALLENGERDB_connect (cfg, - false))) + (db = CHALLENGERDB_connect (cfg))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to initialize database connection.\n"); diff --git a/src/challenger/challenger-httpd.c b/src/challenger/challenger-httpd.c @@ -741,21 +741,12 @@ run (void *cls, &rc); rc = GNUNET_CURL_gnunet_rc_create (CH_ctx); if (NULL == - (CH_context = CHALLENGERDB_connect (config, - false))) + (CH_context = CHALLENGERDB_connect (config))) { global_ret = EXIT_NOTINSTALLED; GNUNET_SCHEDULER_shutdown (); return; } - if (GNUNET_OK != - CHALLENGERDB_preflight (CH_context)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Database not setup. Did you run challenger-dbinit?\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } { enum GNUNET_GenericReturnValue ret; diff --git a/src/challengerdb/challenger-dbinit.c b/src/challengerdb/challenger-dbinit.c @@ -63,8 +63,7 @@ run (void *cls, (void) args; (void) cfgfile; if (NULL == - (db = CHALLENGERDB_connect (cfg, - true))) + (db = CHALLENGERDB_connect (cfg))) { fprintf (stderr, "Failed to initialize database connection.\n"); diff --git a/src/challengerdb/create_tables.c b/src/challengerdb/create_tables.c @@ -29,22 +29,19 @@ enum GNUNET_GenericReturnValue CHALLENGERDB_create_tables (struct CHALLENGERDB_PostgresContext *pc) { - struct GNUNET_PQ_Context *conn; - struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("SET search_path TO challenger;"), - GNUNET_PQ_EXECUTE_STATEMENT_END - }; - enum GNUNET_GenericReturnValue ret; - - conn = GNUNET_PQ_connect_with_cfg (pc->cfg, - "challengerdb-postgres", - "challenger-", - es, - NULL); - if (NULL == conn) + if (GNUNET_OK != + GNUNET_PQ_load_versioning (pc->conn)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_PQ_run_sql (pc->conn, + "challenger-")) + { + GNUNET_break (0); return GNUNET_SYSERR; - ret = GNUNET_PQ_exec_sql (conn, - "procedures"); - GNUNET_PQ_disconnect (conn); - return ret; + } + return GNUNET_PQ_exec_sql (pc->conn, + "procedures"); } diff --git a/src/challengerdb/drop_tables.c b/src/challengerdb/drop_tables.c @@ -29,23 +29,6 @@ enum GNUNET_GenericReturnValue CHALLENGERDB_drop_tables (struct CHALLENGERDB_PostgresContext *pg) { - struct GNUNET_PQ_Context *conn; - enum GNUNET_GenericReturnValue ret; - - if (NULL != pg->conn) - { - GNUNET_PQ_disconnect (pg->conn); - pg->conn = NULL; - } - conn = GNUNET_PQ_connect_with_cfg (pg->cfg, - "challengerdb-postgres", - NULL, - NULL, - NULL); - if (NULL == conn) - return GNUNET_SYSERR; - ret = GNUNET_PQ_exec_sql (conn, - "drop"); - GNUNET_PQ_disconnect (conn); - return ret; + return GNUNET_PQ_exec_sql (pg->conn, + "drop"); } diff --git a/src/challengerdb/pg.c b/src/challengerdb/pg.c @@ -18,20 +18,93 @@ * @brief database helper functions for postgres used by challenger * @author Christian Grothoff */ -#include "platform.h" +struct CHALLENGERDB_PostgresContext; +#define GNUNET_PQ_RECONNECT_CALLBACK_CLOSURE \ + struct CHALLENGERDB_PostgresContext #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_db_lib.h> #include <gnunet/gnunet_pq_lib.h> #include <taler/taler_pq_lib.h> #include "challenger_database_lib.h" #include "challenger_util.h" -#include "challenger-database/preflight.h" #include "pg_helper.h" +/** + * Function called each time we connect or reconnect to the + * database. Gives the application a chance to run some + * per-connection initialization logic. + * + * @param pg database conntext in the auditor + * @param pq database connection handle + */ +static void +reconnect_cb (struct CHALLENGERDB_PostgresContext *pg, + struct GNUNET_PQ_Context *pq) +{ +#if AUTO_EXPLAIN + /* Enable verbose logging to see where queries do not + properly use indices */ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"), + GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"), + GNUNET_PQ_make_try_execute ("SET auto_explain.log_timing=TRUE;"), + GNUNET_PQ_make_try_execute ("SET auto_explain.log_analyze=TRUE;"), + /* https://wiki.postgresql.org/wiki/Serializable suggests to really + force the default to 'serializable' if SSI is to be used. */ + GNUNET_PQ_make_try_execute ( + "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"), + GNUNET_PQ_make_execute ("SET search_path TO challenger;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; +#else + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ("SET search_path TO challenger;"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; +#endif + + if (GNUNET_OK != + GNUNET_PQ_exec_statements (pq, + es)) + { + GNUNET_break (0); + return; + } + pg->prep_gen++; +} + + +/** + * Connect to the db if the connection does not exist yet. + * + * @param[in,out] pg the database state + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +internal_setup (struct CHALLENGERDB_PostgresContext *pg) +{ + struct GNUNET_PQ_Context *db_conn; + + if (NULL != pg->conn) + return GNUNET_OK; + db_conn = GNUNET_PQ_init (pg->cfg, + "challengerdb-postgres", + &reconnect_cb, + pg); + if (NULL == db_conn) + return GNUNET_SYSERR; + if (0 == pg->prep_gen) + { + GNUNET_PQ_disconnect (db_conn); + return GNUNET_SYSERR; + } + pg->conn = db_conn; + return GNUNET_OK; +} + struct CHALLENGERDB_PostgresContext * -CHALLENGERDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, - bool skip_preflight) +CHALLENGERDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct CHALLENGERDB_PostgresContext *pg; @@ -49,15 +122,13 @@ CHALLENGERDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_free (pg); return NULL; } - if (! skip_preflight) + if (GNUNET_OK != + internal_setup (pg)) { - if (GNUNET_OK != - CHALLENGERDB_preflight (pg)) - { - GNUNET_free (pg->sql_dir); - GNUNET_free (pg); - return NULL; - } + CHALLENGERDB_disconnect (pg); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to ensure DB is initialized\n"); + return NULL; } return pg; } @@ -75,4 +146,4 @@ CHALLENGERDB_disconnect (struct CHALLENGERDB_PostgresContext *pg) } -/* end of plugin_challengerdb_postgres.c */ +/* end of pg.c */ diff --git a/src/challengerdb/preflight.c b/src/challengerdb/preflight.c @@ -24,51 +24,6 @@ #include "pg_helper.h" -static enum GNUNET_GenericReturnValue -internal_setup (struct CHALLENGERDB_PostgresContext *pg) -{ - if (NULL == pg->conn) - { -#if AUTO_EXPLAIN - /* Enable verbose logging to see where queries do not - properly use indices */ - struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"), - GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"), - GNUNET_PQ_make_try_execute ("SET auto_explain.log_timing=TRUE;"), - GNUNET_PQ_make_try_execute ("SET auto_explain.log_analyze=TRUE;"), - /* https://wiki.postgresql.org/wiki/Serializable suggests to really - force the default to 'serializable' if SSI is to be used. */ - GNUNET_PQ_make_try_execute ( - "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"), - GNUNET_PQ_make_execute ("SET search_path TO challenger;"), - GNUNET_PQ_EXECUTE_STATEMENT_END - }; -#else - struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("SET search_path TO challenger;"), - GNUNET_PQ_EXECUTE_STATEMENT_END - }; -#endif - struct GNUNET_PQ_Context *db_conn; - - db_conn = GNUNET_PQ_connect_with_cfg2 (pg->cfg, - "challengerdb-postgres", - "challenger-", - es, - NULL, - GNUNET_PQ_FLAG_CHECK_CURRENT); - if (NULL == db_conn) - return GNUNET_SYSERR; - pg->conn = db_conn; - pg->prep_gen++; - } - if (NULL == pg->transaction_name) - GNUNET_PQ_reconnect_if_down (pg->conn); - return GNUNET_OK; -} - - enum GNUNET_GenericReturnValue CHALLENGERDB_preflight (struct CHALLENGERDB_PostgresContext *pg) { @@ -77,19 +32,11 @@ CHALLENGERDB_preflight (struct CHALLENGERDB_PostgresContext *pg) GNUNET_PQ_EXECUTE_STATEMENT_END }; - if (NULL == pg->conn) - { - if (GNUNET_OK != - internal_setup (pg)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to ensure DB is initialized\n"); - return GNUNET_SYSERR; - } - } - GNUNET_PQ_reconnect_if_down (pg->conn); if (NULL == pg->transaction_name) + { + GNUNET_PQ_reconnect_if_down (pg->conn); return GNUNET_OK; /* all good */ + } if (GNUNET_OK == GNUNET_PQ_exec_statements (pg->conn, es)) diff --git a/src/challengerdb/test_challenger_db.c b/src/challengerdb/test_challenger_db.c @@ -62,8 +62,7 @@ run (void *cls) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; - if (NULL == (pg = CHALLENGERDB_connect (cfg, - true))) + if (NULL == (pg = CHALLENGERDB_connect (cfg))) { result = 77; return; diff --git a/src/include/challenger_database_lib.h b/src/include/challenger_database_lib.h @@ -29,14 +29,10 @@ struct CHALLENGERDB_PostgresContext; * Connect to the challenger database. * * @param cfg configuration to use - * @param skip_preflight true if we should skip the usual - * preflight check which assures us that the DB is actually - * operational; only challenger-dbinit should use true here. * @return NULL on failure */ struct CHALLENGERDB_PostgresContext * -CHALLENGERDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, - bool skip_preflight); +CHALLENGERDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); /**