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:
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 = {