exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit f3c837a22aeb506344d1a7e928a32b3122a31c01
parent 7222f220684d820f66467c732dec2eefa566ebb6
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 11 Oct 2026 14:33:11 +0200

fail fast and do not keep signing if exchange disconnected

Diffstat:
Msrc/util/secmod_cs.c | 52+++++++++++++++++++++++++++++++---------------------
Msrc/util/secmod_rsa.c | 30++++++++++++++++++++----------
2 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/src/util/secmod_cs.c b/src/util/secmod_cs.c @@ -898,8 +898,10 @@ start_derive_job (const struct TALER_CRYPTO_CsRDeriveRequest *rdr, * * @param client who made the request * @param[in,out] bj job to finish + * @return #GNUNET_OK on success, #GNUNET_SYSERR if we + * failed to transmit the reply to @a client */ -static void +static enum GNUNET_GenericReturnValue finish_job (struct TES_Client *client, struct BatchJob *bj) { @@ -909,25 +911,19 @@ finish_job (struct TES_Client *client, { case TYPE_SIGN: if (TALER_EC_NONE != bj->ec) - { - fail_sign (client, - bj->ec); - return; - } - send_signature (client, - &bj->details.sign.cs_answer); - break; + return fail_sign (client, + bj->ec); + return send_signature (client, + &bj->details.sign.cs_answer); case TYPE_RDERIVE: if (TALER_EC_NONE != bj->ec) - { - fail_derive (client, - bj->ec); - return; - } - send_derivation (client, - &bj->details.rderive.rpairp); - break; + return fail_derive (client, + bj->ec); + return send_derivation (client, + &bj->details.rderive.rpairp); } + GNUNET_break (0); + return GNUNET_SYSERR; } @@ -948,6 +944,7 @@ handle_batch_sign_request (struct TES_Client *client, const void *off = (const void *) &bsr[1]; unsigned int idx = 0; bool failure = false; + enum GNUNET_GenericReturnValue tret = GNUNET_OK; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Handling batch sign request of size %u\n", @@ -980,10 +977,16 @@ handle_batch_sign_request (struct TES_Client *client, GNUNET_break_op (0 == size); bs = GNUNET_MIN (bs, idx); + /* Note: we must finish (and thus reap) *every* job we started, + even once transmission failed, or we would leak workers. */ for (unsigned int i = 0; i<bs; i++) - finish_job (client, - &jobs[i]); + if (GNUNET_OK != + finish_job (client, + &jobs[i])) + tret = GNUNET_SYSERR; } + if (GNUNET_OK != tret) + return tret; /* client is gone, do not bother with more replies */ if (failure) { struct TALER_CRYPTO_SignFailure sf = { @@ -1017,6 +1020,7 @@ handle_batch_derive_request (struct TES_Client *client, const void *off = (const void *) &bdr[1]; unsigned int idx = 0; bool failure = false; + enum GNUNET_GenericReturnValue tret = GNUNET_OK; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Handling batch derivation request of size %u\n", @@ -1050,10 +1054,16 @@ handle_batch_derive_request (struct TES_Client *client, GNUNET_break_op (0 == size); bs = GNUNET_MIN (bs, idx); + /* Note: we must finish (and thus reap) *every* job we started, + even once transmission failed, or we would leak workers. */ for (unsigned int i = 0; i<bs; i++) - finish_job (client, - &jobs[i]); + if (GNUNET_OK != + finish_job (client, + &jobs[i])) + tret = GNUNET_SYSERR; } + if (GNUNET_OK != tret) + return tret; /* client is gone, do not bother with more replies */ if (failure) { GNUNET_break (0); diff --git a/src/util/secmod_rsa.c b/src/util/secmod_rsa.c @@ -731,23 +731,25 @@ start_job (const struct TALER_CRYPTO_SignRequest *sr, * * @param client who made the request * @param[in,out] bj job to finish + * @return #GNUNET_OK on success, #GNUNET_SYSERR if we + * failed to transmit the reply to @a client */ -static void +static enum GNUNET_GenericReturnValue finish_job (struct TES_Client *client, struct BatchJob *bj) { + enum GNUNET_GenericReturnValue ret; + sem_down (&bj->sem); sem_done (&bj->sem); if (TALER_EC_NONE != bj->ec) - { - fail_sign (client, - bj->ec); - return; - } + return fail_sign (client, + bj->ec); GNUNET_assert (NULL != bj->rsa_signature); - send_signature (client, - bj->rsa_signature); + ret = send_signature (client, + bj->rsa_signature); bj->rsa_signature = NULL; /* freed in send_signature */ + return ret; } @@ -768,6 +770,7 @@ handle_batch_sign_request (struct TES_Client *client, const void *off = (const void *) &bsr[1]; unsigned int idx = 0; bool failure = false; + enum GNUNET_GenericReturnValue tret = GNUNET_OK; /* an empty batch would be answered with no message at all, leaving the client waiting for a reply forever */ @@ -801,10 +804,17 @@ handle_batch_sign_request (struct TES_Client *client, GNUNET_break_op (0 == size); bs = GNUNET_MIN (bs, idx); + /* Note: we must finish (and thus reap) *every* job we started, + even once transmission failed, or we would leak workers and + the signatures they produced. */ for (unsigned int i = 0; i<bs; i++) - finish_job (client, - &jobs[i]); + if (GNUNET_OK != + finish_job (client, + &jobs[i])) + tret = GNUNET_SYSERR; } + if (GNUNET_OK != tret) + return tret; /* client is gone, do not bother with more replies */ if (failure) { struct TALER_CRYPTO_SignFailure sf = {