diff options
| -rw-r--r-- | src/mint/taler-mint-httpd.c | 30 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_keystate.c | 180 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_keystate.h | 8 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_parsing.c | 3 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_responses.c | 2 | ||||
| -rw-r--r-- | src/mintdb/mintdb_keyio.c | 6 | ||||
| -rw-r--r-- | src/mintdb/plugin_mintdb_common.c | 2 | ||||
| -rw-r--r-- | src/mintdb/plugin_mintdb_postgres.c | 4 | 
8 files changed, 174 insertions, 61 deletions
| diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index a0f1eca4..4fa86775 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 87f2e9b9..e1509a60 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 5abb006c..62b041e9 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 b29cdeab..0f31e865 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 bbf35b8b..57b233e7 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))); diff --git a/src/mintdb/mintdb_keyio.c b/src/mintdb/mintdb_keyio.c index f475218b..9e2cd60f 100644 --- a/src/mintdb/mintdb_keyio.c +++ b/src/mintdb/mintdb_keyio.c @@ -165,6 +165,7 @@ TALER_MINTDB_denomination_key_read (const char *filename,      GNUNET_free (data);      return GNUNET_SYSERR;    } +  GNUNET_assert (NULL == dki->denom_priv.rsa_private_key);    dki->denom_priv.rsa_private_key = priv;    dki->denom_pub.rsa_public_key      = GNUNET_CRYPTO_rsa_private_key_get_public (priv); @@ -270,15 +271,18 @@ denomkeys_iterate_keydir_iter (void *cls,    struct DenomkeysIterateContext *dic = cls;    struct TALER_MINTDB_DenominationKeyIssueInformation issue; +  memset (&issue, 0, sizeof (issue));    if (GNUNET_OK !=        TALER_MINTDB_denomination_key_read (filename, -                                 &issue)) +                                          &issue))    {      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,                  "Invalid denomkey file: '%s'\n",                  filename);      return GNUNET_OK;    } +  /* FIXME: very ugly, 'it' is to free memory WE +     allocated as part of issue!!?? #3886 */    return dic->it (dic->it_cls,                    dic->alias,                    &issue); diff --git a/src/mintdb/plugin_mintdb_common.c b/src/mintdb/plugin_mintdb_common.c index f380d7da..11430127 100644 --- a/src/mintdb/plugin_mintdb_common.c +++ b/src/mintdb/plugin_mintdb_common.c @@ -100,6 +100,8 @@ common_free_coin_transaction_list (void *cls,      {      case TALER_MINTDB_TT_DEPOSIT:        json_decref (list->details.deposit->wire); +      GNUNET_CRYPTO_rsa_public_key_free (list->details.deposit->coin.denom_pub.rsa_public_key); +      GNUNET_CRYPTO_rsa_signature_free (list->details.deposit->coin.denom_sig.rsa_signature);        GNUNET_free (list->details.deposit);        break;      case TALER_MINTDB_TT_REFRESH_MELT: diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index d6e136da..f2bc8367 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -892,10 +892,12 @@ postgres_prepare (PGconn *db_conn)  static void  db_conn_destroy (void *cls)  { -  PGconn *db_conn = cls; +  struct TALER_MINTDB_Session *session = cls; +  PGconn *db_conn = session->conn;    if (NULL != db_conn)      PQfinish (db_conn); +  GNUNET_free (session);  } | 
