sync

Backup service to store encrypted wallet databases (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit f90a202b4b79807395c1cbd918d076d0a8594413
parent d654a65837823aa25c9d8af8ac397acd41e42588
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 15 Jun 2025 19:58:51 +0200

adjust to API changes needed for #10024

Diffstat:
Mconfigure.ac | 13+++++++++++++
Msrc/sync/sync-httpd.c | 201++++++++++++++++++++++++-------------------------------------------------------
Msrc/sync/sync-httpd2.c | 113+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
3 files changed, 142 insertions(+), 185 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -100,6 +100,19 @@ AS_IF([test $libgnunetutil != 1], *** ]])]) +AC_CHECK_HEADERS([taler/taler_mhd_lib.h], + [AC_CHECK_LIB([talermhd], [TALER_MHD_listen_bind], libtalermhd=1)]) +AM_CONDITIONAL(HAVE_TALERMHD, test x$libtalermhd = x1) +AS_IF([test $libtalermhd != 1], + [AC_MSG_ERROR([[ +*** +*** You need libtalermhd >= 1.1.0 (API v6) to build this program. +*** This library is part of the GNU Taler exchange, available at +*** https://taler.net +*** ]])]) + + + # test for postgres AX_LIB_POSTGRESQL([15]) AS_IF([test "x$found_postgresql" = "xyes"],[postgres=true]) diff --git a/src/sync/sync-httpd.c b/src/sync/sync-httpd.c @@ -28,11 +28,6 @@ #include "sync-httpd_backup.h" #include "sync-httpd_config.h" -/** - * Backlog for listen operation on unix-domain sockets. - */ -#define UNIX_BACKLOG 500 - /** * Should a "Connection: close" header be added to each HTTP response? @@ -70,19 +65,14 @@ struct GNUNET_CURL_Context *SH_ctx; static struct GNUNET_CURL_RescheduleContext *rc; /** - * Task running the HTTP server. - */ -static struct GNUNET_SCHEDULER_Task *mhd_task; - -/** * Global return code */ static int global_ret; /** - * The MHD Daemon + * Set to true if we have started an MHD daemons. */ -static struct MHD_Daemon *mhd; +static bool have_daemons; /** * Connection handle to the our database @@ -335,11 +325,7 @@ do_shutdown (void *cls) { (void) cls; SH_resume_all_bc (); - if (NULL != mhd_task) - { - GNUNET_SCHEDULER_cancel (mhd_task); - mhd_task = NULL; - } + TALER_MHD_daemons_halt (); if (NULL != SH_ctx) { GNUNET_CURL_fini (SH_ctx); @@ -350,11 +336,7 @@ do_shutdown (void *cls) GNUNET_CURL_gnunet_rc_destroy (rc); rc = NULL; } - if (NULL != mhd) - { - MHD_stop_daemon (mhd); - mhd = NULL; - } + TALER_MHD_daemons_destroy (); if (NULL != db) { SYNC_DB_plugin_unload (db); @@ -398,39 +380,6 @@ handle_mhd_completion_callback (void *cls, /** - * Function that queries MHD's select sets and - * starts the task waiting for them. - */ -static struct GNUNET_SCHEDULER_Task * -prepare_daemon (void); - - -/** - * Set if we should immediately #MHD_run again. - */ -static int triggered; - - -/** - * Call MHD to process pending requests and then go back - * and schedule the next run. - * - * @param cls the `struct MHD_Daemon` of the HTTP server to run - */ -static void -run_daemon (void *cls) -{ - (void) cls; - mhd_task = NULL; - do { - triggered = 0; - GNUNET_assert (MHD_YES == MHD_run (mhd)); - } while (0 != triggered); - mhd_task = prepare_daemon (); -} - - -/** * Kick MHD to run now, to be called after MHD_resume_connection(). * Basically, we need to explicitly resume MHD's event loop whenever * we made progress serving a request. This function re-schedules @@ -439,16 +388,7 @@ run_daemon (void *cls) void SH_trigger_daemon () { - if (NULL != mhd_task) - { - GNUNET_SCHEDULER_cancel (mhd_task); - mhd_task = GNUNET_SCHEDULER_add_now (&run_daemon, - NULL); - } - else - { - triggered = 1; - } + TALER_MHD_daemon_trigger (); } @@ -463,55 +403,40 @@ SH_trigger_curl () /** - * Function that queries MHD's select sets and - * starts the task waiting for them. + * Callback invoked on every listen socket to start the + * respective MHD HTTP daemon. * - * @return task that runs the HTTP server + * @param cls unused + * @param lsock the listen socket */ -static struct GNUNET_SCHEDULER_Task * -prepare_daemon (void) +static void +start_daemon (void *cls, + int lsock) { - struct GNUNET_SCHEDULER_Task *ret; - fd_set rs; - fd_set ws; - fd_set es; - struct GNUNET_NETWORK_FDSet *wrs; - struct GNUNET_NETWORK_FDSet *wws; - int max; - MHD_UNSIGNED_LONG_LONG timeout; - int haveto; - struct GNUNET_TIME_Relative tv; - - FD_ZERO (&rs); - FD_ZERO (&ws); - FD_ZERO (&es); - wrs = GNUNET_NETWORK_fdset_create (); - wws = GNUNET_NETWORK_fdset_create (); - max = -1; - GNUNET_assert (MHD_YES == - MHD_get_fdset (mhd, - &rs, - &ws, - &es, - &max)); - haveto = MHD_get_timeout (mhd, &timeout); - if (haveto == MHD_YES) - tv.rel_value_us = (uint64_t) timeout * 1000LL; - else - tv = GNUNET_TIME_UNIT_FOREVER_REL; - GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); - GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Adding run_daemon select task\n"); - ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, - tv, - wrs, - wws, - &run_daemon, - NULL); - GNUNET_NETWORK_fdset_destroy (wrs); - GNUNET_NETWORK_fdset_destroy (wws); - return ret; + struct MHD_Daemon *mhd; + + (void) cls; + GNUNET_assert (-1 != lsock); + mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME | MHD_USE_DUAL_STACK, + 0 /* port */, + NULL, NULL, + &url_handler, NULL, + MHD_OPTION_LISTEN_SOCKET, lsock, + MHD_OPTION_NOTIFY_COMPLETED, + &handle_mhd_completion_callback, NULL, + MHD_OPTION_CONNECTION_TIMEOUT, + (unsigned int) 10 /* 10s */, + MHD_OPTION_END); + if (NULL == mhd) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to launch HTTP service, exiting.\n"); + global_ret = EXIT_NO_RESTART; + GNUNET_SCHEDULER_shutdown (); + return; + } + have_daemons = true; + TALER_MHD_daemon_start (mhd); } @@ -530,9 +455,7 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { - int fh; enum TALER_MHD_GlobalOptions go; - uint16_t port; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting sync-httpd\n"); @@ -656,36 +579,34 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - fh = TALER_MHD_bind (config, - "sync", - &port); - if ( (0 == port) && - (-1 == fh) ) { - global_ret = EXIT_NO_RESTART; - GNUNET_SCHEDULER_shutdown (); - return; - } - mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME | MHD_USE_DUAL_STACK, - port, - NULL, NULL, - &url_handler, NULL, - MHD_OPTION_LISTEN_SOCKET, fh, - MHD_OPTION_NOTIFY_COMPLETED, - &handle_mhd_completion_callback, NULL, - MHD_OPTION_CONNECTION_TIMEOUT, - (unsigned int) 10 /* 10s */, - MHD_OPTION_END); - if (NULL == mhd) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to launch HTTP service, exiting.\n"); - global_ret = EXIT_NO_RESTART; - GNUNET_SCHEDULER_shutdown (); - return; + enum GNUNET_GenericReturnValue ret; + + ret = TALER_MHD_listen_bind (config, + "sync", + &start_daemon, + NULL); + switch (ret) + { + case GNUNET_SYSERR: + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + case GNUNET_NO: + if (! have_daemons) + { + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Could not open all configured listen sockets\n"); + break; + case GNUNET_OK: + break; + } } global_ret = EXIT_SUCCESS; - mhd_task = prepare_daemon (); } diff --git a/src/sync/sync-httpd2.c b/src/sync/sync-httpd2.c @@ -26,11 +26,6 @@ #include "sync-httpd2_backup.h" #include "sync-httpd2_config.h" -/** - * Backlog for listen operation on unix-domain sockets. - */ -#define UNIX_BACKLOG 500 - /** * Should a "Connection: close" header be added to each HTTP response? @@ -73,6 +68,11 @@ static struct GNUNET_CURL_RescheduleContext *rc; static int global_ret; /** + * Set to true if we have started an MHD daemons. + */ +static bool have_daemons; + +/** * Connection handle to the our database */ struct SYNC_DatabasePlugin *db; @@ -307,9 +307,8 @@ url_handler (void *cls, static void do_shutdown (void *cls) { - struct MHD_Daemon *mhd; - (void) cls; + TALER_MHD2_daemons_halt (); SH_resume_all_bc (); if (NULL != SH_ctx) { @@ -321,12 +320,7 @@ do_shutdown (void *cls) GNUNET_CURL_gnunet_rc_destroy (rc); rc = NULL; } - mhd = TALER_MHD2_daemon_stop (); - if (NULL != mhd) - { - MHD_daemon_destroy (mhd); - mhd = NULL; - } + TALER_MHD2_daemons_destroy (); if (NULL != db) { SYNC_DB_plugin_unload (db); @@ -345,7 +339,7 @@ do_shutdown (void *cls) void SH_trigger_daemon () { - TALER_MHD2_daemon_trigger (); + TALER_MHD2_daemons_trigger (); } @@ -360,6 +354,41 @@ SH_trigger_curl () /** + * Callback invoked on every listen socket to start the + * respective MHD HTTP daemon. + * + * @param cls unused + * @param lsock the listen socket + */ +static void +start_daemon (void *cls, + int lsock) +{ + struct MHD_Daemon *mhd; + + (void) cls; + GNUNET_assert (-1 != lsock); + mhd = MHD_daemon_create (&url_handler, + NULL); + if (NULL == mhd) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to launch HTTP service, exiting.\n"); + global_ret = EXIT_NO_RESTART; + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_assert (MHD_SC_OK == + MHD_DAEMON_SET_OPTIONS ( + mhd, + MHD_D_OPTION_DEFAULT_TIMEOUT (10), + MHD_D_OPTION_LISTEN_SOCKET (lsock))); + have_daemons = true; + TALER_MHD2_daemon_start (mhd); +} + + +/** * Main function that will be run by the scheduler. * * @param cls closure @@ -374,11 +403,7 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { - int fh; enum TALER_MHD2_GlobalOptions go; - uint16_t port; - struct MHD_Daemon *mhd; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting sync-httpd\n"); @@ -502,36 +527,34 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - fh = TALER_MHD_bind (config, - "sync", - &port); - if ( (0 == port) && - (-1 == fh) ) - { - global_ret = EXIT_NO_RESTART; - GNUNET_SCHEDULER_shutdown (); - return; - } - mhd = MHD_daemon_create (&url_handler, - NULL); - if (NULL == mhd) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to launch HTTP service, exiting.\n"); - global_ret = EXIT_NO_RESTART; - GNUNET_SCHEDULER_shutdown (); - return; + enum GNUNET_GenericReturnValue ret; + + ret = TALER_MHD_listen_bind (config, + "sync", + &start_daemon, + NULL); + switch (ret) + { + case GNUNET_SYSERR: + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + case GNUNET_NO: + if (! have_daemons) + { + global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Could not open all configured listen sockets\n"); + break; + case GNUNET_OK: + break; + } } - GNUNET_assert (MHD_SC_OK == - MHD_DAEMON_SET_OPTIONS ( - mhd, - MHD_D_OPTION_DEFAULT_TIMEOUT (10), - (-1 == fh) - ? MHD_D_OPTION_BIND_PORT (MHD_AF_AUTO, - port) - : MHD_D_OPTION_LISTEN_SOCKET (fh))); global_ret = EXIT_SUCCESS; - TALER_MHD2_daemon_start (mhd); }