From be535b68e1c5911c9ec011a0d24714d0f4b42377 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 9 Jul 2015 22:10:14 +0200 Subject: fix a few pointer passing issues, add remark about #3886 --- src/mint/taler-mint-httpd.c | 30 +++++- src/mint/taler-mint-httpd_keystate.c | 180 ++++++++++++++++++++++++---------- src/mint/taler-mint-httpd_keystate.h | 8 +- src/mint/taler-mint-httpd_parsing.c | 3 + src/mint/taler-mint-httpd_responses.c | 2 +- 5 files changed, 164 insertions(+), 59 deletions(-) (limited to 'src/mint') diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index a0f1eca4b..4fa867759 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -105,6 +105,7 @@ handle_mhd_completion_callback (void *cls, void **con_cls, enum MHD_RequestTerminationCode toe) { + fprintf (stderr, "CC called (%p)!\n", *con_cls); if (NULL == *con_cls) return; TMH_PARSE_post_cleanup_callback (*con_cls); @@ -482,9 +483,32 @@ main (int argc, char *const *argv) "Failed to start HTTP server.\n"); return 1; } - ret = TMH_KS_loop (); - MHD_stop_daemon (mydaemon); + switch (ret) + { + case GNUNET_OK: + case GNUNET_SYSERR: + MHD_stop_daemon (mydaemon); + break; + case GNUNET_NO: + { + MHD_socket sock = MHD_quiesce_daemon (mydaemon); + + /* FIXME #3474: fork another MHD, passing on the listen socket! */ + while (0 != MHD_get_daemon_info (mydaemon, + MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->num_connections) + sleep (1); + MHD_stop_daemon (mydaemon); + + close (sock); /* FIXME: done like this because #3474 is open */ + } + break; + default: + GNUNET_break (0); + MHD_stop_daemon (mydaemon); + break; + } + if (GNUNET_YES == TMH_test_mode) { struct TALER_MINTDB_Session *session; @@ -499,5 +523,5 @@ main (int argc, char *const *argv) } TALER_MINTDB_plugin_unload (TMH_plugin); - return (GNUNET_OK == ret) ? 0 : 1; + return (GNUNET_SYSERR == ret) ? 1 : 0; } diff --git a/src/mint/taler-mint-httpd_keystate.c b/src/mint/taler-mint-httpd_keystate.c index 87f2e9b95..e1509a600 100644 --- a/src/mint/taler-mint-httpd_keystate.c +++ b/src/mint/taler-mint-httpd_keystate.c @@ -296,6 +296,8 @@ reload_keys_denom_iter (void *cls, as it is possible we just retry until we succeed. */ } + /* FIXME: this is a VERY ugly (we obtain ownership of + pointers within 'dki' here!!!) #3886 */ d2 = GNUNET_memdup (dki, sizeof (struct TALER_MINTDB_DenominationKeyIssueInformation)); res = GNUNET_CONTAINER_multihashmap_put (ctx->denomkey_map, @@ -418,6 +420,8 @@ free_denom_key (void *cls, { struct TALER_MINTDB_DenominationKeyIssueInformation *dki = value; + GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key); + GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key); GNUNET_free (dki); return GNUNET_OK; } @@ -436,13 +440,25 @@ TMH_KS_release_ (struct TMH_KS_StateHandle *key_state) key_state->refcnt--; if (0 == key_state->refcnt) { - json_decref (key_state->denom_keys_array); - json_decref (key_state->sign_keys_array); - GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map, - &free_denom_key, - key_state); - GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map); - GNUNET_free (key_state->keys_json); + if (NULL != key_state->denom_keys_array) + { + json_decref (key_state->denom_keys_array); + key_state->denom_keys_array = NULL; + } + if (NULL != key_state->sign_keys_array) + { + json_decref (key_state->sign_keys_array); + key_state->sign_keys_array = NULL; + } + if (NULL != key_state->denomkey_map) + { + GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map, + &free_denom_key, + key_state); + GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map); + key_state->denomkey_map = NULL; + } + GNUNET_free_non_null (key_state->keys_json); GNUNET_free (key_state); } } @@ -532,6 +548,8 @@ TMH_KS_acquire (void) sizeof (struct TALER_MintPublicKeyP)), "eddsa_sig", TALER_json_from_data (&sig, sizeof (struct TALER_MintSignatureP))); + key_state->sign_keys_array = NULL; + key_state->denom_keys_array = NULL; key_state->keys_json = json_dumps (keys, JSON_INDENT (2)); json_decref (keys); @@ -605,8 +623,7 @@ TMH_KS_denomination_key_lookup (const struct TMH_KS_StateHandle *key_state, /** - * Handle a signal, writing relevant signal numbers - * (currently just SIGUSR1) to a pipe. + * Handle a signal, writing relevant signal numbers to the pipe. * * @param signal_number the signal number */ @@ -616,38 +633,83 @@ handle_signal (int signal_number) ssize_t res; char c = signal_number; - if (SIGUSR1 == signal_number) + res = write (reload_pipe[1], + &c, + 1); + if ( (res < 0) && + (EINTR != errno) ) { - res = write (reload_pipe[1], - &c, - 1); - if ( (res < 0) && - (EINTR != errno) ) - { - GNUNET_break (0); - return; - } - if (0 == res) - { - GNUNET_break (0); - return; - } + GNUNET_break (0); + return; + } + if (0 == res) + { + GNUNET_break (0); + return; } } +/** + * Call #handle_signal() to pass the received signal via + * the control pipe. + */ +static void +handle_sigusr1 () +{ + handle_signal (SIGUSR1); +} + + +/** + * Call #handle_signal() to pass the received signal via + * the control pipe. + */ +static void +handle_sigint () +{ + handle_signal (SIGINT); +} + + +/** + * Call #handle_signal() to pass the received signal via + * the control pipe. + */ +static void +handle_sigterm () +{ + handle_signal (SIGTERM); +} + + +/** + * Call #handle_signal() to pass the received signal via + * the control pipe. + */ +static void +handle_sighup () +{ + handle_signal (SIGHUP); +} + + /** * Read signals from a pipe in a loop, and reload keys from disk if - * SIGUSR1 is read from the pipe. + * SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and + * restart if SIGHUP is received. * - * @return #GNUNET_SYSERR on errors, otherwise does not return - * (FIXME: #3474) + * @return #GNUNET_SYSERR on errors, + * #GNUNET_OK to terminate normally + * #GNUNET_NO to restart an update version of the binary */ int TMH_KS_loop (void) { - struct sigaction act; - struct sigaction rec; + struct GNUNET_SIGNAL_Context *sigusr1; + struct GNUNET_SIGNAL_Context *sigterm; + struct GNUNET_SIGNAL_Context *sigint; + struct GNUNET_SIGNAL_Context *sighup; int ret; if (0 != pipe (reload_pipe)) @@ -656,22 +718,17 @@ TMH_KS_loop (void) "Failed to create pipe.\n"); return GNUNET_SYSERR; } - memset (&act, - 0, - sizeof (struct sigaction)); - act.sa_handler = &handle_signal; - if (0 != sigaction (SIGUSR1, - &act, - &rec)) - { - fprintf (stderr, - "Failed to set signal handler.\n"); - return GNUNET_SYSERR; - } - - ret = GNUNET_OK; - /* FIXME: allow for 'clean' termination or restart (#3474) */ - while (1) + sigusr1 = GNUNET_SIGNAL_handler_install (SIGUSR1, + &handle_sigusr1); + sigterm = GNUNET_SIGNAL_handler_install (SIGTERM, + &handle_sigterm); + sigint = GNUNET_SIGNAL_handler_install (SIGINT, + &handle_sigint); + sighup = GNUNET_SIGNAL_handler_install (SIGHUP, + &handle_sighup); + + ret = 0; + while (0 == ret) { char c; ssize_t res; @@ -700,16 +757,35 @@ read_again: } if (EINTR == errno) goto read_again; + switch (c) + { + case SIGUSR1: + /* reload internal key state, we do this in the loop */ + break; + case SIGTERM: + case SIGINT: + /* terminate */ + ret = GNUNET_OK; + break; + case SIGHUP: + /* restart updated binary */ + ret = GNUNET_NO; + break; + default: + /* unexpected character */ + GNUNET_break (0); + break; + } } - - if (0 != sigaction (SIGUSR1, - &rec, - &act)) + if (NULL != internal_key_state) { - fprintf (stderr, - "Failed to restore signal handler.\n"); - return GNUNET_SYSERR; + TMH_KS_release (internal_key_state); + internal_key_state = NULL; } + GNUNET_SIGNAL_handler_uninstall (sigusr1); + GNUNET_SIGNAL_handler_uninstall (sigterm); + GNUNET_SIGNAL_handler_uninstall (sigint); + GNUNET_SIGNAL_handler_uninstall (sighup); return ret; } diff --git a/src/mint/taler-mint-httpd_keystate.h b/src/mint/taler-mint-httpd_keystate.h index 5abb006cb..62b041e92 100644 --- a/src/mint/taler-mint-httpd_keystate.h +++ b/src/mint/taler-mint-httpd_keystate.h @@ -96,10 +96,12 @@ TMH_KS_denomination_key_lookup (const struct TMH_KS_StateHandle *key_state, /** * Read signals from a pipe in a loop, and reload keys from disk if - * SIGUSR1 is read from the pipe. + * SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and + * restart if SIGHUP is received. * - * @return #GNUNET_OK if we terminated normally, - * #GNUNET_SYSERR on error + * @return #GNUNET_SYSERR on errors, + * #GNUNET_OK to terminate normally + * #GNUNET_NO to restart an update version of the binary */ int TMH_KS_loop (void); diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c index b29cdeabf..0f31e8652 100644 --- a/src/mint/taler-mint-httpd_parsing.c +++ b/src/mint/taler-mint-httpd_parsing.c @@ -273,6 +273,7 @@ TMH_PARSE_post_json (struct MHD_Connection *connection, ? GNUNET_SYSERR : GNUNET_NO; } /* everything OK, wait for more POST data */ + fprintf (stderr, "Init %p\n", r); *upload_data_size = 0; *con_cls = r; return GNUNET_YES; @@ -314,6 +315,8 @@ TMH_PARSE_post_json (struct MHD_Connection *connection, TMH_RESPONSE_reply_invalid_json (connection)) ? GNUNET_NO : GNUNET_SYSERR; } + fprintf (stderr, "Deinit %p\n", r); + buffer_deinit (r); GNUNET_free (r); *con_cls = NULL; diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index bbf35b8bd..57b233e73 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -525,7 +525,7 @@ compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh, } ret = 1; json_array_append_new (json_history, - json_pack ("{s:s, s:o, s:o}", + json_pack ("{s:s, s:O, s:o}", "type", "DEPOSIT", "wire", pos->details.bank->wire, "amount", TALER_json_from_amount (&pos->details.bank->amount))); -- cgit v1.2.3