From 888895cb8c607de52966ac24545078e452432a96 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 23 Aug 2021 23:35:24 +0200 Subject: fix #6956 in exchange --- src/exchange/taler-exchange-httpd.c | 10 ++++- src/exchange/taler-exchange-httpd_keys.c | 62 ++++++++++++++++++++++++++++++- src/exchange/taler-exchange-httpd_keys.h | 11 +++++- src/exchange/taler-exchange-httpd_wire.c | 63 ++++++++++++++++++++++++++++++++ src/exchange/taler-exchange-httpd_wire.h | 9 +++++ 5 files changed, 150 insertions(+), 5 deletions(-) (limited to 'src/exchange') diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index a39e1032c..50aa85f7b 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -1382,8 +1382,9 @@ do_shutdown (void *cls) TEH_reserves_get_cleanup (); if (NULL != mhd) MHD_stop_daemon (mhd); - TALER_EXCHANGEDB_plugin_unload (TEH_plugin); TEH_WIRE_done (); + TEH_keys_finished (); + TALER_EXCHANGEDB_plugin_unload (TEH_plugin); } @@ -1425,6 +1426,13 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } + if (GNUNET_OK != + TEH_wire_init ()) + { + global_ret = EXIT_FAILURE; + GNUNET_SCHEDULER_shutdown (); + return; + } TEH_load_terms (TEH_cfg); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 3b5616345..5d25600c4 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -21,6 +21,7 @@ #include "platform.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" +#include "taler_dbevents.h" #include "taler-exchange-httpd.h" #include "taler-exchange-httpd_keys.h" #include "taler-exchange-httpd_responses.h" @@ -349,6 +350,12 @@ static struct TEH_KeyStateHandle *key_state; */ static uint64_t key_generation; +/** + * Handler listening for wire updates by other exchange + * services. + */ +static struct GNUNET_DB_EventHandler *keys_eh; + /** * Head of DLL of suspended /keys requests. */ @@ -867,9 +874,35 @@ destroy_key_state (struct TEH_KeyStateHandle *ksh, } -int +/** + * Function called whenever another exchange process has updated + * the keys data in the database. + * + * @param cls NULL + * @param extra unused + * @param extra_size number of bytes in @a extra unused + */ +static void +keys_update_event_cb (void *cls, + const void *extra, + size_t extra_size) +{ + (void) cls; + (void) extra; + (void) extra_size; + key_generation++; + TEH_resume_keys_requests (false); +} + + +enum GNUNET_GenericReturnValue TEH_keys_init () { + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_EXCHANGE_KEYS_UPDATED), + }; + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (TEH_cfg, "exchange", @@ -881,6 +914,16 @@ TEH_keys_init () "SIGNKEY_LEGAL_DURATION"); return GNUNET_SYSERR; } + keys_eh = TEH_plugin->event_listen (TEH_plugin->cls, + GNUNET_TIME_UNIT_FOREVER_REL, + &es, + &keys_update_event_cb, + NULL); + if (NULL == keys_eh) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } return GNUNET_OK; } @@ -888,12 +931,18 @@ TEH_keys_init () /** * Fully clean up our state. */ -void __attribute__ ((destructor)) +void TEH_keys_finished () { if (NULL != key_state) destroy_key_state (key_state, true); + if (NULL != keys_eh) + { + TEH_plugin->event_listen_cancel (TEH_plugin->cls, + keys_eh); + keys_eh = NULL; + } } @@ -1719,6 +1768,15 @@ build_key_state (struct HelperState *hs, void TEH_keys_update_states () { + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_EXCHANGE_KEYS_UPDATED), + }; + + TEH_plugin->event_notify (TEH_plugin->cls, + &es, + NULL, + 0); key_generation++; TEH_resume_keys_requests (false); } diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 6c6853660..ce5e2b73d 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -192,6 +192,13 @@ void TEH_keys_denomination_revoke (const struct GNUNET_HashCode *h_denom_pub); +/** + * Fully clean up keys subsystem. + */ +void +TEH_keys_finished (void); + + /** * Resumse all suspended /keys requests, we may now have key material * (or are shutting down). @@ -377,11 +384,11 @@ TEH_keys_get_timing (const struct TALER_ExchangePublicKeyP *exchange_pub, /** - * Initialize keys submodule. + * Initialize keys subsystem. * * @return #GNUNET_OK on success */ -int +enum GNUNET_GenericReturnValue TEH_keys_init (void); diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index d256e3c50..8e4465ada 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -20,6 +20,7 @@ */ #include "platform.h" #include +#include "taler_dbevents.h" #include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_wire.h" #include "taler_json_lib.h" @@ -32,6 +33,11 @@ */ static struct WireStateHandle *wire_state; +/** + * Handler listening for wire updates by other exchange + * services. + */ +static struct GNUNET_DB_EventHandler *wire_eh; /** * Counter incremented whenever we have a reason to re-build the #wire_state @@ -77,6 +83,48 @@ destroy_wire_state (struct WireStateHandle *wsh) } +/** + * Function called whenever another exchange process has updated + * the wire data in the database. + * + * @param cls NULL + * @param extra unused + * @param extra_size number of bytes in @a extra unused + */ +static void +wire_update_event_cb (void *cls, + const void *extra, + size_t extra_size) +{ + (void) cls; + (void) extra; + (void) extra_size; + wire_generation++; +} + + +int +TEH_wire_init () +{ + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_EXCHANGE_KEYS_UPDATED), + }; + + wire_eh = TEH_plugin->event_listen (TEH_plugin->cls, + GNUNET_TIME_UNIT_FOREVER_REL, + &es, + &wire_update_event_cb, + NULL); + if (NULL == wire_eh) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + void TEH_WIRE_done () { @@ -85,6 +133,12 @@ TEH_WIRE_done () destroy_wire_state (wire_state); wire_state = NULL; } + if (NULL != wire_eh) + { + TEH_plugin->event_listen_cancel (TEH_plugin->cls, + wire_eh); + wire_eh = NULL; + } } @@ -302,6 +356,15 @@ build_wire_state (void) void TEH_wire_update_state (void) { + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + .type = htons (TALER_DBEVENT_EXCHANGE_WIRE_UPDATED), + }; + + TEH_plugin->event_notify (TEH_plugin->cls, + &es, + NULL, + 0); wire_generation++; } diff --git a/src/exchange/taler-exchange-httpd_wire.h b/src/exchange/taler-exchange-httpd_wire.h index fc4e55a95..5966ccbd4 100644 --- a/src/exchange/taler-exchange-httpd_wire.h +++ b/src/exchange/taler-exchange-httpd_wire.h @@ -33,6 +33,15 @@ void TEH_WIRE_done (void); +/** + * Initialize wire subsystem. + * + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +TEH_wire_init (void); + + /** * Something changed in the database. Rebuild the wire replies. This function * should be called if the exchange learns about a new signature from our -- cgit v1.2.3